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"
)

// ProviderHandler 供应商管理处理器
type ProviderHandler struct {
	providerService service.ProviderService
}

// NewProviderHandler 创建供应商处理器
func NewProviderHandler(providerService service.ProviderService) *ProviderHandler {
	return &ProviderHandler{providerService: providerService}
}

// CreateProvider 创建供应商
func (h *ProviderHandler) CreateProvider(c *gin.Context) {
	var req struct {
		ID       string `json:"id" binding:"required"`
		Name     string `json:"name" binding:"required"`
		APIKey   string `json:"api_key" binding:"required"`
		BaseURL  string `json:"base_url" binding:"required"`
		Protocol string `json:"protocol"`
	}

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

	protocol := req.Protocol
	if protocol == "" {
		protocol = "openai"
	}

	provider := &domain.Provider{
		ID:       req.ID,
		Name:     req.Name,
		APIKey:   req.APIKey,
		BaseURL:  req.BaseURL,
		Protocol: protocol,
	}

	err := h.providerService.Create(provider)
	if err != nil {
		if errors.Is(err, appErrors.ErrInvalidProviderID) {
			c.JSON(http.StatusBadRequest, gin.H{
				"error": appErrors.ErrInvalidProviderID.Message,
				"code":  appErrors.ErrInvalidProviderID.Code,
			})
			return
		}
		writeError(c, err)
		return
	}

	c.JSON(http.StatusCreated, provider)
}

// ListProviders 列出所有供应商
func (h *ProviderHandler) ListProviders(c *gin.Context) {
	providers, err := h.providerService.List()
	if err != nil {
		writeError(c, err)
		return
	}

	c.JSON(http.StatusOK, providers)
}

// GetProvider 获取供应商
func (h *ProviderHandler) GetProvider(c *gin.Context) {
	id := c.Param("id")

	provider, err := h.providerService.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, provider)
}

// UpdateProvider 更新供应商
func (h *ProviderHandler) UpdateProvider(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.providerService.Update(id, req)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			c.JSON(http.StatusNotFound, gin.H{
				"error": "供应商未找到",
			})
			return
		}
		if errors.Is(err, appErrors.ErrImmutableField) {
			c.JSON(http.StatusBadRequest, gin.H{
				"error": appErrors.ErrImmutableField.Message,
				"code":  appErrors.ErrImmutableField.Code,
			})
			return
		}
		writeError(c, err)
		return
	}

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

	c.JSON(http.StatusOK, provider)
}

// DeleteProvider 删除供应商
func (h *ProviderHandler) DeleteProvider(c *gin.Context) {
	id := c.Param("id")

	err := h.providerService.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)
}

// writeError 统一错误响应处理
func writeError(c *gin.Context, err error) {
	if appErr, ok := appErrors.AsAppError(err); ok {
		c.JSON(appErr.HTTPStatus, gin.H{
			"error": appErr.Message,
			"code":  appErr.Code,
		})
		return
	}
	c.JSON(http.StatusInternalServerError, gin.H{
		"error": err.Error(),
	})
}
