package handler

import (
	"errors"
	"net/http"

	"nex/backend/internal/domain"
	"nex/backend/internal/service"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"

	appErrors "nex/backend/pkg/errors"
)

// ModelHandler 模型管理处理器
type ModelHandler struct {
	modelService service.ModelService
}

// NewModelHandler 创建模型处理器
func NewModelHandler(modelService service.ModelService) *ModelHandler {
	return &ModelHandler{modelService: modelService}
}

// modelResponse 模型响应 DTO，扩展 unified_id 字段
type modelResponse struct {
	domain.Model
	UnifiedModelID string `json:"unified_id"`
}

// newModelResponse 从 domain.Model 构造响应 DTO
func newModelResponse(m *domain.Model) modelResponse {
	return modelResponse{
		Model:          *m,
		UnifiedModelID: m.UnifiedModelID(),
	}
}

// CreateModel 创建模型
func (h *ModelHandler) CreateModel(c *gin.Context) {
	var req struct {
		ProviderID string `json:"provider_id" binding:"required"`
		ModelName  string `json:"model_name" binding:"required"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "缺少必需字段: provider_id, model_name",
		})
		return
	}

	model := &domain.Model{
		ProviderID: req.ProviderID,
		ModelName:  req.ModelName,
	}

	err := h.modelService.Create(model)
	if err != nil {
		if errors.Is(err, appErrors.ErrProviderNotFound) {
			c.JSON(http.StatusBadRequest, gin.H{
				"error": "供应商不存在",
			})
			return
		}
		if errors.Is(err, appErrors.ErrDuplicateModel) {
			c.JSON(http.StatusConflict, gin.H{
				"error": "同一供应商下模型名称已存在",
				"code":  appErrors.ErrDuplicateModel.Code,
			})
			return
		}
		writeError(c, err)
		return
	}

	c.JSON(http.StatusCreated, newModelResponse(model))
}

// ListModels 列出模型
func (h *ModelHandler) ListModels(c *gin.Context) {
	providerID := c.Query("provider_id")

	models, err := h.modelService.List(providerID)
	if err != nil {
		writeError(c, err)
		return
	}

	resp := make([]modelResponse, len(models))
	for i, m := range models {
		resp[i] = newModelResponse(&m)
	}
	c.JSON(http.StatusOK, resp)
}

// GetModel 获取模型
func (h *ModelHandler) GetModel(c *gin.Context) {
	id := c.Param("id")

	model, err := h.modelService.Get(id)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			c.JSON(http.StatusNotFound, gin.H{
				"error": "模型未找到",
			})
			return
		}
		writeError(c, err)
		return
	}

	c.JSON(http.StatusOK, newModelResponse(model))
}

// UpdateModel 更新模型
func (h *ModelHandler) UpdateModel(c *gin.Context) {
	id := c.Param("id")

	var req map[string]interface{}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "无效的请求格式",
		})
		return
	}

	err := h.modelService.Update(id, req)
	if err != nil {
		if errors.Is(err, appErrors.ErrModelNotFound) {
			c.JSON(http.StatusNotFound, gin.H{
				"error": "模型未找到",
			})
			return
		}
		if errors.Is(err, appErrors.ErrProviderNotFound) {
			c.JSON(http.StatusBadRequest, gin.H{
				"error": "供应商不存在",
			})
			return
		}
		if errors.Is(err, appErrors.ErrDuplicateModel) {
			c.JSON(http.StatusConflict, gin.H{
				"error": appErrors.ErrDuplicateModel.Message,
				"code":  appErrors.ErrDuplicateModel.Code,
			})
			return
		}
		writeError(c, err)
		return
	}

	model, err := h.modelService.Get(id)
	if err != nil {
		writeError(c, err)
		return
	}

	c.JSON(http.StatusOK, newModelResponse(model))
}

// DeleteModel 删除模型
func (h *ModelHandler) DeleteModel(c *gin.Context) {
	id := c.Param("id")

	err := h.modelService.Delete(id)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			c.JSON(http.StatusNotFound, gin.H{
				"error": "模型未找到",
			})
			return
		}
		writeError(c, err)
		return
	}

	c.Status(http.StatusNoContent)
}
