package handler

import (
	"lune/talentscale/internal/domain"
	"lune/talentscale/internal/pkg/ctxval"
	"lune/talentscale/pkg/response"
	"strconv"
	"time"

	"github.com/gofiber/fiber/v2"
	"github.com/google/uuid"
)

type UserHandler struct {
	userUsecase domain.UserUsecase
}

func NewUserHandler(userUsecase domain.UserUsecase) *UserHandler {
	return &UserHandler{userUsecase: userUsecase}
}

func (h *UserHandler) Create(c *fiber.Ctx) error {
	var req domain.User
	if err := c.BodyParser(&req); err != nil {
		return response.BadRequest(c, "Invalid request body")
	}

	companyID := ctxval.GetCompanyID(c)
	req.ID = uuid.New()
	req.CompanyID = &companyID
	req.CreatedAt = time.Now()
	req.UpdatedAt = time.Now()

	if err := h.userUsecase.Create(c.Context(), &req); err != nil {
		return response.InternalError(c, err.Error())
	}

	return response.Created(c, "User created successfully", req)
}

func (h *UserHandler) List(c *fiber.Ctx) error {
	companyID := ctxval.GetCompanyID(c)
	search := c.Query("search")
	roleIDStr := c.Query("role_id")
	limit, _ := strconv.Atoi(c.Query("limit", "10"))
	page, _ := strconv.Atoi(c.Query("page", "1"))
	offset := (page - 1) * limit

	var roleID uuid.UUID
	if roleIDStr != "" {
		roleID, _ = uuid.Parse(roleIDStr)
	}

	users, total, err := h.userUsecase.GetAll(c.Context(), companyID, search, roleID, limit, offset)
	if err != nil {
		return response.InternalError(c, err.Error())
	}

	totalPage := total / limit
	if total%limit > 0 {
		totalPage++
	}

	return response.OK(c, "Success", users, response.PaginationMeta{
		CurrentPage: page,
		TotalPage:   totalPage,
		TotalItems:  int64(total),
		PerPage:     limit,
	})
}

func (h *UserHandler) GetByID(c *fiber.Ctx) error {
	companyID := ctxval.GetCompanyID(c)
	idParam := c.Params("id")
	id, err := uuid.Parse(idParam)
	if err != nil {
		return response.BadRequest(c, "Invalid user ID format")
	}

	user, err := h.userUsecase.GetByID(c.Context(), id, companyID)
	if err != nil {
		return response.NotFound(c, "User not found")
	}

	return response.OK(c, "Success", user)
}

func (h *UserHandler) Update(c *fiber.Ctx) error {
	companyID := ctxval.GetCompanyID(c)
	idParam := c.Params("id")
	id, err := uuid.Parse(idParam)
	if err != nil {
		return response.BadRequest(c, "Invalid user ID format")
	}

	var req domain.User
	if err := c.BodyParser(&req); err != nil {
		return response.BadRequest(c, "Invalid request body")
	}

	req.ID = id
	req.CompanyID = &companyID
	if err := h.userUsecase.Update(c.Context(), &req); err != nil {
		return response.InternalError(c, err.Error())
	}

	return response.OK(c, "User updated successfully", nil)
}

func (h *UserHandler) Delete(c *fiber.Ctx) error {
	companyID := ctxval.GetCompanyID(c)
	idParam := c.Params("id")
	id, err := uuid.Parse(idParam)
	if err != nil {
		return response.BadRequest(c, "Invalid user ID format")
	}

	if err := h.userUsecase.Delete(c.Context(), id, companyID); err != nil {
		return response.InternalError(c, err.Error())
	}

	return response.OK(c, "User deleted successfully", nil)
}
