package account import ( "github.com/gofiber/fiber/v2" "go.uber.org/zap" "math" qutils "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/utils" "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors" "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/client" "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http" "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/repository" "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models" "strconv" ) type Deps struct { MiddleWare *http.MiddleWare AccountRepo *repository.AccountRepository Logger *zap.Logger Encrypt *qutils.Encrypt AuthClient *client.AuthClient } type AccountController struct { middleWare *http.MiddleWare accountRepo *repository.AccountRepository logger *zap.Logger encrypt *qutils.Encrypt authClient *client.AuthClient } func NewAccountController(deps Deps) *AccountController { return &AccountController{ middleWare: deps.MiddleWare, accountRepo: deps.AccountRepo, logger: deps.Logger, encrypt: deps.Encrypt, authClient: deps.AuthClient, } } func (receiver *AccountController) DeleteAccount(ctx *fiber.Ctx) error { userID, ok := receiver.middleWare.ExtractUserID(ctx) if !ok || userID == "" { return receiver.middleWare.NoAuth(ctx) } account, err := receiver.accountRepo.Remove(ctx.Context(), userID) if err != nil { return receiver.middleWare.ErrorOld(ctx, err) } return ctx.Status(fiber.StatusOK).JSON(account) } func (receiver *AccountController) ChangeAccount(ctx *fiber.Ctx) error { userID, ok := receiver.middleWare.ExtractUserID(ctx) if !ok || userID == "" { return receiver.middleWare.NoAuth(ctx) } var request models.Name if err := ctx.BodyParser(&request); err != nil { return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind json", err) } account, err := receiver.accountRepo.UpdateName(ctx.Context(), userID, &request) if err != nil { return receiver.middleWare.ErrorOld(ctx, err) } return ctx.Status(fiber.StatusOK).JSON(account) } func (receiver *AccountController) SetAccountVerificationStatus(ctx *fiber.Ctx) error { userID := ctx.Params("userId") if userID == "" { return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "invalid format for parameter userId") } var request models.SetAccountStatus if err := ctx.BodyParser(&request); err != nil { return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind json", err) } account, err := receiver.accountRepo.SetStatus(ctx.Context(), userID, request.Status) if err != nil { receiver.logger.Error("failed to set status on of ", zap.Error(err)) return receiver.middleWare.ErrorOld(ctx, err) } return ctx.Status(fiber.StatusOK).JSON(account) } func (receiver *AccountController) GetAccount(ctx *fiber.Ctx) error { userID, ok := receiver.middleWare.ExtractUserID(ctx) if !ok || userID == "" { return receiver.middleWare.NoAuth(ctx) } account, err := receiver.accountRepo.FindByUserID(ctx.Context(), userID) if err != nil { return receiver.middleWare.ErrorOld(ctx, err) } return ctx.Status(fiber.StatusOK).JSON(account) } func (receiver *AccountController) AddAccount(ctx *fiber.Ctx) error { userID, ok := receiver.middleWare.ExtractUserID(ctx) if !ok || userID == "" { return receiver.middleWare.NoAuth(ctx) } var er error quizFrom := ctx.Cookies("quizFrom") quizUser := ctx.Cookies("quizUser") if quizUser != "" { quizUser, er = receiver.encrypt.DecryptStr([]byte(quizUser)) if er != nil { return receiver.middleWare.ErrorOld(ctx, er) } } account, err := receiver.accountRepo.FindByUserID(ctx.Context(), userID) if err != nil && err.Type() != errors.ErrNotFound { return receiver.middleWare.ErrorOld(ctx, err) } if account != nil { return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "account exists") } user, err := receiver.authClient.GetUser(ctx.Context(), userID) if err != nil { return receiver.middleWare.ErrorOld(ctx, err) } account, err = receiver.accountRepo.Insert(ctx.Context(), &models.Account{ UserID: user.ID, Wallet: models.Wallet{Currency: models.DefaultCurrency}, From: quizFrom, Partner: quizUser}) if err != nil { return receiver.middleWare.ErrorOld(ctx, err) } return ctx.Status(fiber.StatusOK).JSON(account) } func (receiver *AccountController) DeleteDirectAccount(ctx *fiber.Ctx) error { userID := ctx.Params("userId") if userID == "" { return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "invalid format for parameter userId") } account, err := receiver.accountRepo.Remove(ctx.Context(), userID) if err != nil { return receiver.middleWare.ErrorOld(ctx, err) } return ctx.Status(fiber.StatusOK).JSON(account) } func (receiver *AccountController) GetDirectAccount(ctx *fiber.Ctx) error { userID := ctx.Params("userId") if userID == "" { return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "invalid format for parameter userId") } account, err := receiver.accountRepo.FindByUserID(ctx.Context(), userID) if err != nil { return receiver.middleWare.ErrorOld(ctx, err) } return ctx.Status(fiber.StatusOK).JSON(account) } func (receiver *AccountController) PaginationAccounts(ctx *fiber.Ctx) error { pageStr := ctx.Query("page", "1") limitStr := ctx.Query("limit", "100") page, err := strconv.ParseInt(pageStr, 10, 64) if err != nil || page < 1 { page = 1 } limit, err := strconv.ParseInt(limitStr, 10, 64) if err != nil || limit < 1 { limit = models.DefaultLimit } else { limit = int64(math.Min(float64(limit), float64(models.DefaultLimit))) } count, err := receiver.accountRepo.CountAll(ctx.Context()) if err != nil { return receiver.middleWare.ErrorOld(ctx, err) } if count == 0 { response := models.PaginationResponse[models.Account]{TotalPages: 0, Records: []models.Account{}} return ctx.Status(fiber.StatusOK).JSON(response) } totalPages := int64(math.Ceil(float64(count) / float64(limit))) accounts, err := receiver.accountRepo.FindMany(ctx.Context(), page, limit) if err != nil { return receiver.middleWare.ErrorOld(ctx, err) } response := models.PaginationResponse[models.Account]{ TotalPages: totalPages, Records: accounts, } return ctx.Status(fiber.StatusOK).JSON(response) }