package handlers

import (
	"net/http"
	"strconv"
	"strings"

	"git.mchus.pro/mchus/quoteforge/internal/localdb"
	"git.mchus.pro/mchus/quoteforge/internal/models"
	"git.mchus.pro/mchus/quoteforge/internal/repository"
	"git.mchus.pro/mchus/quoteforge/internal/services"
	"github.com/gin-gonic/gin"
)

type ComponentHandler struct {
	componentService *services.ComponentService
	localDB          *localdb.LocalDB
}

func NewComponentHandler(componentService *services.ComponentService, localDB *localdb.LocalDB) *ComponentHandler {
	return &ComponentHandler{
		componentService: componentService,
		localDB:          localDB,
	}
}

func (h *ComponentHandler) List(c *gin.Context) {
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	perPage, _ := strconv.Atoi(c.DefaultQuery("per_page", "20"))
	if page < 1 {
		page = 1
	}
	if perPage < 1 {
		perPage = 20
	}

	filter := repository.ComponentFilter{
		Category:      c.Query("category"),
		Search:        c.Query("search"),
		HasPrice:      c.Query("has_price") == "true",
		ExcludeHidden: c.Query("include_hidden") != "true", // По умолчанию скрытые не показываются
	}

	localFilter := localdb.ComponentFilter{
		Category: filter.Category,
		Search:   filter.Search,
		HasPrice: filter.HasPrice,
	}
	offset := (page - 1) * perPage
	localComps, total, err := h.localDB.ListComponents(localFilter, offset, perPage)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	components := make([]services.ComponentView, len(localComps))
	for i, lc := range localComps {
		components[i] = services.ComponentView{
			LotName:      lc.LotName,
			Description:  lc.LotDescription,
			Category:     lc.Category,
			CategoryName: lc.Category,
			Model:        lc.Model,
		}
	}

	c.JSON(http.StatusOK, &services.ComponentListResult{
		Components: components,
		Total:      total,
		Page:       page,
		PerPage:    perPage,
	})
}

func (h *ComponentHandler) Get(c *gin.Context) {
	lotName := c.Param("lot_name")
	component, err := h.localDB.GetLocalComponent(lotName)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "component not found"})
		return
	}

	c.JSON(http.StatusOK, services.ComponentView{
		LotName:      component.LotName,
		Description:  component.LotDescription,
		Category:     component.Category,
		CategoryName: component.Category,
		Model:        component.Model,
	})
}

func (h *ComponentHandler) GetCategories(c *gin.Context) {
	codes, err := h.localDB.GetLocalComponentCategories()
	if err == nil && len(codes) > 0 {
		categories := make([]models.Category, 0, len(codes))
		for _, code := range codes {
			trimmed := strings.TrimSpace(code)
			if trimmed == "" {
				continue
			}
			categories = append(categories, models.Category{Code: trimmed, Name: trimmed})
		}
		c.JSON(http.StatusOK, categories)
		return
	}

	c.JSON(http.StatusOK, models.DefaultCategories)
}
