package company_category

import (
	"tm/pkg/logger"
	"tm/pkg/response"

	"github.com/labstack/echo/v4"
)

// Handler handles HTTP requests for category operations
type Handler struct {
	service Service
	logger  logger.Logger
}

// NewHandler creates a new category handler
func NewHandler(service Service, logger logger.Logger) *Handler {
	return &Handler{
		service: service,
		logger:  logger,
	}
}

// Create creates a new category (Web Panel)
// @Summary Create a new category
// @Description Create a new category with name, description, and thumbnail
// @Tags Admin-Company-Categories
// @Accept json
// @Produce json
// @Param category body CategoryForm true "Category information"
// @Success 201 {object} response.APIResponse{data=CategoryResponse} "Category created successfully"
// @Failure 400 {object} response.APIResponse "Bad request - Invalid input data"
// @Failure 409 {object} response.APIResponse "Conflict - Category with this name already exists"
// @Failure 422 {object} response.APIResponse "Validation error - Invalid request data"
// @Failure 500 {object} response.APIResponse "Internal server error"
// @Security BearerAuth
// @Router /admin/v1/company-categories [post]
func (h *Handler) Create(c echo.Context) error {
	form, err := response.Parse[CategoryForm](c)
	if err != nil {
		return response.ValidationError(c, "Invalid request data", err.Error())
	}

	category, err := h.service.Create(c.Request().Context(), form)
	if err != nil {
		if err.Error() == "category with this name already exists" {
			return response.Conflict(c, err.Error())
		}
		return response.InternalServerError(c, "Failed to create category")
	}

	return response.Created(c, category, "Category created successfully")
}

// GetCategory retrieves a category by ID (Web Panel)
// @Summary Get category by ID
// @Description Retrieve detailed category information by category ID
// @Tags Admin-Company-Categories
// @Accept json
// @Produce json
// @Param id path string true "Category ID"
// @Success 200 {object} response.APIResponse{data=CategoryResponse} "Category retrieved successfully"
// @Failure 400 {object} response.APIResponse "Bad request - Invalid category ID"
// @Failure 404 {object} response.APIResponse "Not found - Category not found"
// @Failure 500 {object} response.APIResponse "Internal server error"
// @Security BearerAuth
// @Router /admin/v1/company-categories/{id} [get]
func (h *Handler) Get(c echo.Context) error {
	id := c.Param("id")

	category, err := h.service.GetByID(c.Request().Context(), id)
	if err != nil {
		if err.Error() == "category not found" {
			return response.NotFound(c, "Category not found")
		}
		return response.InternalServerError(c, "Failed to get category")
	}

	return response.Success(c, category, "Category retrieved successfully")
}

// Update updates a category (Web Panel)
// @Summary Update category information
// @Description Update category information including name, description, and thumbnail
// @Tags Admin-Company-Categories
// @Accept json
// @Produce json
// @Param id path string true "Category ID"
// @Param category body CategoryForm true "Category update information"
// @Success 200 {object} response.APIResponse{data=CategoryResponse} "Category updated successfully"
// @Failure 400 {object} response.APIResponse "Bad request - Invalid input data"
// @Failure 404 {object} response.APIResponse "Not found - Category not found"
// @Failure 409 {object} response.APIResponse "Conflict - Category with this name already exists"
// @Failure 422 {object} response.APIResponse "Validation error - Invalid request data"
// @Failure 500 {object} response.APIResponse "Internal server error"
// @Security BearerAuth
// @Router /admin/v1/company-categories/{id} [put]
func (h *Handler) Update(c echo.Context) error {
	id := c.Param("id")
	form, err := response.Parse[CategoryForm](c)
	if err != nil {
		return response.ValidationError(c, "Invalid request data", err.Error())
	}

	category, err := h.service.Update(c.Request().Context(), id, form)
	if err != nil {
		if err.Error() == "category not found" {
			return response.NotFound(c, "Category not found")
		}
		if err.Error() == "category with this name already exists" {
			return response.Conflict(c, err.Error())
		}
		return response.InternalServerError(c, "Failed to update category")
	}

	return response.Success(c, category, "Category updated successfully")
}

// Delete deletes a category (Web Panel)
// @Summary Delete category
// @Description Delete a category permanently
// @Tags Admin-Company-Categories
// @Accept json
// @Produce json
// @Param id path string true "Category ID"
// @Success 200 {object} response.APIResponse "Category deleted successfully"
// @Failure 400 {object} response.APIResponse "Bad request - Invalid category ID"
// @Failure 404 {object} response.APIResponse "Not found - Category not found"
// @Failure 500 {object} response.APIResponse "Internal server error"
// @Security BearerAuth
// @Router /admin/v1/company-categories/{id} [delete]
func (h *Handler) Delete(c echo.Context) error {
	id := c.Param("id")

	err := h.service.Delete(c.Request().Context(), id)
	if err != nil {
		if err.Error() == "category not found" {
			return response.NotFound(c, "Category not found")
		}
		return response.InternalServerError(c, "Failed to delete category")
	}

	return response.Success(c, map[string]interface{}{
		"message": "Category deleted successfully",
	}, "Category deleted successfully")
}

// Search searches categories with filters (Web Panel)
// @Summary Search categories
// @Description Search categories with filtering capabilities
// @Tags Admin-Company-Categories
// @Accept json
// @Produce json
// @Param q query string false "Search query"
// @Param published query boolean false "Published status filter"
// @Param limit query integer false "Limit" default(20)
// @Param offset query integer false "Offset" default(0)
// @Param sort_by query string false "Sort by field" Enums(name,created_at,updated_at,published_at)
// @Param sort_order query string false "Sort order" Enums(asc,desc)
// @Success 200 {object} response.APIResponse{data=CategoryListResponse} "Categories search completed"
// @Failure 400 {object} response.APIResponse "Bad request - Invalid query parameters"
// @Failure 422 {object} response.APIResponse "Validation error - Invalid query parameters"
// @Failure 500 {object} response.APIResponse "Internal server error"
// @Security BearerAuth
// @Router /admin/v1/company-categories [get]
func (h *Handler) Search(c echo.Context) error {
	form, err := response.Parse[SearchForm](c)
	if err != nil {
		return response.ValidationError(c, "Invalid request data", err.Error())
	}

	pagination, err := response.NewPagination(c)
	if err != nil {
		return response.PaginationBadRequest(c, err)
	}

	result, err := h.service.SearchCategories(c.Request().Context(), form, pagination)
	if err != nil {
		if response.IsListPaginationError(err) {
			return response.PaginationBadRequest(c, err)
		}
		return response.InternalServerError(c, "Failed to search categories")
	}

	return response.SuccessWithMeta(c, result, result.Meta, "Categories retrieved successfully")
}

// TogglePublish toggles category publish status (Web Panel)
// @Summary Toggle category publish status
// @Description Toggle category publish/unpublish status
// @Tags Admin-Company-Categories
// @Accept json
// @Produce json
// @Param id path string true "Category ID"
// @Success 200 {object} response.APIResponse{data=map[string]bool} "Company category published/unpublished successfully"
// @Failure 400 {object} response.APIResponse "Bad request - Invalid category ID"
// @Failure 404 {object} response.APIResponse "Not found - Company category not found"
// @Failure 500 {object} response.APIResponse "Internal server error - Failed to update published status"
// @Security BearerAuth
// @Router /admin/v1/company-categories/{id}/publish [patch]
func (h *Handler) TogglePublish(c echo.Context) error {
	id := c.Param("id")

	published, err := h.service.TogglePublish(c.Request().Context(), id)
	if err != nil {
		if err.Error() == "category not found" {
			return response.NotFound(c, "Company category not found")
		}
		h.logger.Error("Failed to update Company category published status", map[string]interface{}{
			"error":       err.Error(),
			"category_id": id,
		})
		return response.InternalServerError(c, "Failed to update Company category published status. Please try again or contact support if the problem persists.")
	}

	message := "Company category unpublished successfully"
	if published {
		message = "Company category published successfully"
	}

	return response.Success(
		c,
		map[string]interface{}{
			"published": published,
		},
		message,
	)
}
