package handler

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

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

type CandidateHandler struct {
	usecase domain.CandidateUsecase
}

func NewCandidateHandler(usecase domain.CandidateUsecase) *CandidateHandler {
	return &CandidateHandler{usecase: usecase}
}

// Create - POST /api/v1/candidates
func (h *CandidateHandler) Create(c *fiber.Ctx) error {
	var req domain.Candidate
	if err := c.BodyParser(&req); err != nil {
		return response.BadRequest(c, "Invalid request body")
	}

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

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

// List - GET /api/v1/candidates
func (h *CandidateHandler) List(c *fiber.Ctx) error {
	companyID := ctxval.GetCompanyID(c)
	status := c.Query("status")
	search := c.Query("search")
	limit, _ := strconv.Atoi(c.Query("limit", "10"))
	page, _ := strconv.Atoi(c.Query("page", "1"))
	offset := (page - 1) * limit

	candidates, total, err := h.usecase.List(c.Context(), companyID, status, search, limit, offset)
	if err != nil {
		return response.InternalError(c, err.Error())
	}

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

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

// GetByID - GET /api/v1/candidates/:id
func (h *CandidateHandler) GetByID(c *fiber.Ctx) error {
	companyID := ctxval.GetCompanyID(c)
	id, err := uuid.Parse(c.Params("id"))
	if err != nil {
		return response.BadRequest(c, "Invalid candidate ID format")
	}

	candidate, err := h.usecase.GetByID(c.Context(), id, companyID)
	if err != nil {
		return response.NotFound(c, err.Error())
	}

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

// Update - PUT /api/v1/candidates/:id
func (h *CandidateHandler) Update(c *fiber.Ctx) error {
	companyID := ctxval.GetCompanyID(c)
	id, err := uuid.Parse(c.Params("id"))
	if err != nil {
		return response.BadRequest(c, "Invalid candidate ID format")
	}

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

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

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

// Delete - DELETE /api/v1/candidates/:id
func (h *CandidateHandler) Delete(c *fiber.Ctx) error {
	companyID := ctxval.GetCompanyID(c)
	id, err := uuid.Parse(c.Params("id"))
	if err != nil {
		return response.BadRequest(c, "Invalid candidate ID format")
	}

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

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

// BulkInvite - POST /api/v1/candidates/bulk-invite
func (h *CandidateHandler) BulkInvite(c *fiber.Ctx) error {
	companyID := ctxval.GetCompanyID(c)

	var req []domain.Candidate
	if err := c.BodyParser(&req); err != nil {
		return response.BadRequest(c, "Invalid request body: expected array of candidates")
	}

	if err := h.usecase.BulkInvite(c.Context(), companyID, req); err != nil {
		return response.InternalError(c, err.Error())
	}

	return response.OK(c, "Bulk invitation process started", nil)
}
