package account_admin

import (
	"github.com/gofiber/fiber/v2"
	"go.uber.org/zap"
	"math"
	"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
}

type AccountInternalController struct {
	middleWare  *http.MiddleWare
	accountRepo *repository.AccountRepository
	logger      *zap.Logger
}

func NewAccountInternalController(deps Deps) *AccountInternalController {
	return &AccountInternalController{
		middleWare:  deps.MiddleWare,
		accountRepo: deps.AccountRepo,
		logger:      deps.Logger,
	}
}

func (receiver *AccountInternalController) DeleteCurrent(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 *AccountInternalController) GetCurrent(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 *AccountInternalController) Pagination(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)
}
