package handlers

import (
	"encoding/json"
	"math"
	"net/http"
	"strconv"

	"sale/internal/models"
	"sale/internal/schemas"
	"sale/internal/utils"

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

type ShippingTemplateHandler struct{}

func NewShippingTemplateHandler() *ShippingTemplateHandler {
	return &ShippingTemplateHandler{}
}

// List 获取运费模板列表
func (h *ShippingTemplateHandler) List(c *gin.Context) {
	var templates []models.ShippingTemplate
	utils.DB.Order("sort_order ASC, id ASC").Find(&templates)

	// 解析 provinces JSON 为数组
	type TemplateResponse struct {
		models.ShippingTemplate
		ProvincesList []string `json:"provinces_list"`
	}

	var response []TemplateResponse
	for _, t := range templates {
		var provinces []string
		if t.Provinces != "" {
			json.Unmarshal([]byte(t.Provinces), &provinces)
		}
		response = append(response, TemplateResponse{
			ShippingTemplate: t,
			ProvincesList:    provinces,
		})
	}

	c.JSON(http.StatusOK, gin.H{"data": response})
}

// GetByID 获取单个运费模板
func (h *ShippingTemplateHandler) GetByID(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))
	var template models.ShippingTemplate
	if err := utils.DB.First(&template, id).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "运费模板不存在"})
		return
	}

	var provinces []string
	if template.Provinces != "" {
		json.Unmarshal([]byte(template.Provinces), &provinces)
	}

	c.JSON(http.StatusOK, gin.H{
		"data": gin.H{
			"ShippingTemplate": template,
			"provinces_list":  provinces,
		},
	})
}

// Create 创建运费模板
func (h *ShippingTemplateHandler) Create(c *gin.Context) {
	var req schemas.CreateShippingTemplateRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 如果设为默认，先取消其他默认模板
	if req.IsDefault {
		utils.DB.Model(&models.ShippingTemplate{}).Where("is_default = ?", true).Update("is_default", false)
	}

	// 序列化省份列表
	var provincesJSON string
	if len(req.Provinces) > 0 {
		data, _ := json.Marshal(req.Provinces)
		provincesJSON = string(data)
	}

	template := models.ShippingTemplate{
		Name:           req.Name,
		CalcType:       req.CalcType,
		FirstUnit:      req.FirstUnit,
		FirstFee:       req.FirstFee,
		AdditionalUnit: req.AdditionalUnit,
		AdditionalFee:  req.AdditionalFee,
		FreeAmount:     req.FreeAmount,
		Provinces:      provincesJSON,
		IsDefault:      req.IsDefault,
		SortOrder:      req.SortOrder,
	}

	if err := utils.DB.Create(&template).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "创建运费模板失败"})
		return
	}

	c.JSON(http.StatusCreated, gin.H{"data": template})
}

// Update 更新运费模板
func (h *ShippingTemplateHandler) Update(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))
	var template models.ShippingTemplate
	if err := utils.DB.First(&template, id).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "运费模板不存在"})
		return
	}

	var req schemas.UpdateShippingTemplateRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	updates := make(map[string]interface{})

	if req.Name != nil {
		updates["name"] = *req.Name
	}
	if req.CalcType != nil {
		updates["calc_type"] = *req.CalcType
	}
	if req.FirstUnit != nil {
		updates["first_unit"] = *req.FirstUnit
	}
	if req.FirstFee != nil {
		updates["first_fee"] = *req.FirstFee
	}
	if req.AdditionalUnit != nil {
		updates["additional_unit"] = *req.AdditionalUnit
	}
	if req.AdditionalFee != nil {
		updates["additional_fee"] = *req.AdditionalFee
	}
	if req.FreeAmount != nil {
		updates["free_amount"] = *req.FreeAmount
	}
	if req.Provinces != nil {
		if len(req.Provinces) > 0 {
			data, _ := json.Marshal(req.Provinces)
			updates["provinces"] = string(data)
		} else {
			updates["provinces"] = ""
		}
	}
	if req.IsDefault != nil {
		if *req.IsDefault {
			utils.DB.Model(&models.ShippingTemplate{}).Where("is_default = ? AND id != ?", true, id).Update("is_default", false)
		}
		updates["is_default"] = *req.IsDefault
	}
	if req.SortOrder != nil {
		updates["sort_order"] = *req.SortOrder
	}

	utils.DB.Model(&template).Updates(updates)
	utils.DB.First(&template, id)

	c.JSON(http.StatusOK, gin.H{"data": template})
}

// Delete 删除运费模板
func (h *ShippingTemplateHandler) Delete(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))

	var template models.ShippingTemplate
	if err := utils.DB.First(&template, id).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "运费模板不存在"})
		return
	}

	// 检查是否有关联的商品
	var count int64
	utils.DB.Model(&models.Product{}).Where("shipping_template_id = ?", id).Count(&count)
	if count > 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "该运费模板已被商品关联，无法删除"})
		return
	}

	if err := utils.DB.Delete(&template).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "删除运费模板失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "删除成功"})
}

// CalculateShippingFee 计算运费（供内部调用）
func CalculateShippingFee(templateID *uint, weight float64, quantity int, subtotal float64, province string) (float64, error) {
	var template models.ShippingTemplate

	// 如果没有指定模板，使用默认模板
	if templateID == nil || *templateID == 0 {
		if err := utils.DB.Where("is_default = ?", true).First(&template).Error; err != nil {
			// 没有默认模板，运费为0
			return 0, nil
		}
	} else {
		if err := utils.DB.First(&template, *templateID).Error; err != nil {
			// 模板不存在，使用默认模板
			if err := utils.DB.Where("is_default = ?", true).First(&template).Error; err != nil {
				return 0, nil
			}
		}
	}

	// 检查适用地区
	if template.Provinces != "" && province != "" {
		var provinces []string
		json.Unmarshal([]byte(template.Provinces), &provinces)
		matched := false
		for _, p := range provinces {
			if p == province {
				matched = true
				break
			}
		}
		if !matched {
			// 地址不在适用范围内，使用默认模板
			var defaultTemplate models.ShippingTemplate
			if err := utils.DB.Where("is_default = ?", true).First(&defaultTemplate).Error; err == nil {
				template = defaultTemplate
			}
		}
	}

	// 检查是否满足包邮条件
	if template.FreeAmount > 0 && subtotal >= template.FreeAmount {
		return 0, nil
	}

	// 根据计费方式计算运费
	var totalUnit float64
	if template.CalcType == models.CalcTypeWeight {
		totalUnit = weight // 重量（克）
	} else {
		totalUnit = float64(quantity) // 件数
	}

	// 计算运费
	if totalUnit <= template.FirstUnit {
		return template.FirstFee, nil
	}

	remainingUnit := totalUnit - template.FirstUnit
	additionalCount := math.Ceil(remainingUnit / template.AdditionalUnit)

	return template.FirstFee + additionalCount*template.AdditionalFee, nil
}

// CalculateForUser 用户端计算运费接口
func (h *ShippingTemplateHandler) CalculateForUser(c *gin.Context) {
	var req schemas.CalculateShippingRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	fee, err := CalculateShippingFee(req.TemplateID, req.Weight, req.Quantity, req.Subtotal, req.Province)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "计算运费失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"data": gin.H{"shipping_fee": fee}})
}
