package wallet import ( "fmt" "log" "net/http" "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/swagger" "github.com/labstack/echo/v4" "go.uber.org/zap" "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors" "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models" "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/payment" "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/wallet" "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils" "penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/echotools" "penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/validate" ) type Deps struct { Logger *zap.Logger WalletService *wallet.Service PaymentService *payment.Service } type Controller struct { logger *zap.Logger walletService *wallet.Service paymentService *payment.Service } func New(deps Deps) *Controller { if deps.Logger == nil { log.Panicln("logger is nil on ") } if deps.WalletService == nil { log.Panicln("wallet service is nil on ") } if deps.PaymentService == nil { log.Panicln("payment service is nil on ") } return &Controller{ logger: deps.Logger, walletService: deps.WalletService, paymentService: deps.PaymentService, } } func (receiver *Controller) ChangeCurrency(ctx echo.Context) error { userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string) if !ok { receiver.logger.Error("failed to convert jwt payload to string on of ") return errors.HTTP(ctx, errors.New( fmt.Errorf("failed to convert jwt payload to string: %s", userID), errors.ErrInvalidArgs, )) } request, bindErr := echotools.Bind[models.ChangeCurrency](ctx) if bindErr != nil { receiver.logger.Error("failed to bind body on of ", zap.Error(bindErr)) return errors.HTTP(ctx, errors.New( fmt.Errorf("failed to parse body on of : %w", bindErr), errors.ErrInvalidArgs, )) } if validate.IsStringEmpty(request.Currency) { return errors.HTTP(ctx, errors.New( fmt.Errorf("empty currency key on of : %w", errors.ErrInvalidArgs), errors.ErrInvalidArgs, )) } account, err := receiver.walletService.ChangeCurrency(ctx.Request().Context(), userID, request.Currency) if err != nil { receiver.logger.Error("failed to put money on of ", zap.Error(err)) return errors.HTTP(ctx, err) } return ctx.JSON(http.StatusOK, account) } func (receiver *Controller) GetPaymentLink(ctx echo.Context) error { userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string) if !ok { receiver.logger.Error("failed to convert jwt payload to string on of ") return errors.HTTP(ctx, errors.New( fmt.Errorf("failed to convert jwt payload to string: %s", userID), errors.ErrInvalidArgs, )) } request, bindErr := echotools.Bind[models.GetPaymentLinkBody](ctx) if bindErr != nil { receiver.logger.Error("failed to bind body on of ", zap.Error(bindErr)) return errors.HTTP(ctx, errors.New( fmt.Errorf("failed to parse body on of : %w", bindErr), errors.ErrInvalidArgs, )) } if validateErr := utils.ValidateGetPaymentLinkBody(request); validateErr != nil { receiver.logger.Error("failed to validate body on of ", zap.Error(validateErr)) return errors.HTTP(ctx, validateErr) } link, err := receiver.paymentService.GetPaymentLink(ctx.Request().Context(), &models.GetPaymentLinkRequest{ Body: request, UserID: userID, ClientIP: ctx.RealIP(), }) if err != nil { receiver.logger.Error("failed to get payment link on of ", zap.Error(err)) return errors.HTTP(ctx, err) } return ctx.JSON(http.StatusOK, &models.GetPaymentLinkResponse{Link: link}) } func (receiver *Controller) PostWalletRspay(ctx echo.Context) error { userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string) if !ok { receiver.logger.Error("failed to convert jwt payload to string on of ") return errors.HTTP(ctx, errors.New( fmt.Errorf("failed to convert jwt payload to string: %s", userID), errors.ErrInvalidArgs, )) } var req swagger.PostWalletRspayJSONBody if err := ctx.Bind(&req); err != nil { receiver.logger.Error("failed to bind request", zap.Error(err)) return errors.HTTP(ctx, errors.New( fmt.Errorf("failed to bind request: %s", err), errors.ErrInvalidArgs, )) } if err := receiver.walletService.PostWalletRspay(ctx.Request().Context(), userID, req); err != nil { if err == errors.ErrNoAccess { return errors.HTTP(ctx, err) } return errors.HTTP(ctx, errors.New( fmt.Errorf("failed to process rspay: %w", err), errors.ErrInternalError, )) } return ctx.NoContent(http.StatusOK) }