package funcoes

import (
	"net/http"
	"strings"

	"photum-backend/internal/db/generated"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

type Handler struct {
	service *Service
}

func NewHandler(service *Service) *Handler {
	return &Handler{service: service}
}

type FuncaoResponse struct {
	ID   string `json:"id"`
	Nome string `json:"nome"`
}

type CreateFuncaoRequest struct {
	Nome string `json:"nome" binding:"required"`
}

func toResponse(f generated.FuncoesProfissionai) FuncaoResponse {
	return FuncaoResponse{
		ID:   uuid.UUID(f.ID.Bytes).String(),
		Nome: f.Nome,
	}
}

// Create godoc
// @Summary      Create a new function
// @Description  Create a new professional function
// @Tags         funcoes
// @Accept       json
// @Produce      json
// @Security     BearerAuth
// @Param        request body CreateFuncaoRequest true "Create Function Request"
// @Success      201  {object}  FuncaoResponse
// @Failure      400  {object}  map[string]string
// @Failure      409  {object}  map[string]string
// @Failure      500  {object}  map[string]string
// @Router       /api/funcoes [post]
func (h *Handler) Create(c *gin.Context) {
	var req CreateFuncaoRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	funcao, err := h.service.Create(c.Request.Context(), req.Nome)
	if err != nil {
		if strings.Contains(err.Error(), "duplicate key value") {
			c.JSON(http.StatusConflict, gin.H{"error": "Funcao already exists"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusCreated, toResponse(*funcao))
}

// List godoc
// @Summary      List functions
// @Description  List all professional functions
// @Tags         funcoes
// @Accept       json
// @Produce      json
// @Success      200  {array}   FuncaoResponse
// @Failure      500  {object}  map[string]string
// @Router       /api/funcoes [get]
func (h *Handler) List(c *gin.Context) {
	funcoes, err := h.service.List(c.Request.Context())
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	var response []FuncaoResponse
	for _, f := range funcoes {
		response = append(response, toResponse(f))
	}

	c.JSON(http.StatusOK, response)
}

// Update godoc
// @Summary      Update function
// @Description  Update a professional function by ID
// @Tags         funcoes
// @Accept       json
// @Produce      json
// @Security     BearerAuth
// @Param        id   path      string  true  "Function ID"
// @Param        request body CreateFuncaoRequest true "Update Function Request"
// @Success      200  {object}  FuncaoResponse
// @Failure      400  {object}  map[string]string
// @Failure      409  {object}  map[string]string
// @Failure      500  {object}  map[string]string
// @Router       /api/funcoes/{id} [put]
func (h *Handler) Update(c *gin.Context) {
	id := c.Param("id")
	var req CreateFuncaoRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	funcao, err := h.service.Update(c.Request.Context(), id, req.Nome)
	if err != nil {
		if strings.Contains(err.Error(), "duplicate key value") {
			c.JSON(http.StatusConflict, gin.H{"error": "Funcao already exists"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, toResponse(*funcao))
}

// Delete godoc
// @Summary      Delete function
// @Description  Delete a professional function by ID
// @Tags         funcoes
// @Accept       json
// @Produce      json
// @Security     BearerAuth
// @Param        id   path      string  true  "Function ID"
// @Success      200  {object}  map[string]string
// @Failure      400  {object}  map[string]string
// @Failure      500  {object}  map[string]string
// @Router       /api/funcoes/{id} [delete]
func (h *Handler) Delete(c *gin.Context) {
	id := c.Param("id")
	err := h.service.Delete(c.Request.Context(), id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "deleted"})
}
