package controller

import (
	"fmt"
	"strconv"
	"strings"

	"github.com/QuantumNous/new-api/common"
	"github.com/QuantumNous/new-api/model"
	"github.com/QuantumNous/new-api/setting/ratio_setting"

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

// GetAllChannelPricing 获取所有渠道定价（分页）
func GetAllChannelPricing(c *gin.Context) {
	page, _ := strconv.Atoi(c.DefaultQuery("p", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))
	offset := (page - 1) * pageSize

	list, total, err := model.GetAllChannelPricing(offset, pageSize)
	if err != nil {
		common.ApiError(c, err)
		return
	}

	common.ApiSuccess(c, gin.H{
		"page":      page,
		"page_size": pageSize,
		"total":     total,
		"items":     list,
	})
}

// GetChannelPricingByModel 获取指定模型的所有渠道定价
func GetChannelPricingByModel(c *gin.Context) {
	modelName := c.Param("name")
	if modelName == "" {
		common.ApiErrorMsg(c, "model name is required")
		return
	}

	list, err := model.GetChannelPricingByModel(modelName)
	if err != nil {
		common.ApiError(c, err)
		return
	}

	common.ApiSuccess(c, list)
}

// CreateChannelPricingRequest 创建渠道定价请求
type CreateChannelPricingRequest struct {
	Id                   int     `json:"id"`
	ModelName            string  `json:"model_name" binding:"required"`
	ChannelId            int     `json:"channel_id" binding:"required"`
	QuotaType            int     `json:"quota_type"`
	ModelRatio           float64 `json:"model_ratio"`
	CompletionRatio      float64 `json:"completion_ratio"`
	ModelPrice           float64 `json:"model_price"`
	TagIds               string  `json:"tag_ids"`
	CacheRatio           float64 `json:"cache_ratio"`
	CacheCreationRatio   float64 `json:"cache_creation_ratio"`
	ImageRatio           float64 `json:"image_ratio"`
	AudioRatio           float64 `json:"audio_ratio"`
	AudioCompletionRatio float64 `json:"audio_completion_ratio"`
}

// applyRequest 将请求字段应用到 ChannelPricing
func applyRequestFields(cp *model.ChannelPricing, req *CreateChannelPricingRequest) {
	cp.ApplyFields(req.QuotaType, req.ModelRatio, req.CompletionRatio, req.ModelPrice, req.TagIds,
		req.CacheRatio, req.CacheCreationRatio, req.ImageRatio, req.AudioRatio, req.AudioCompletionRatio)
}

// CreateChannelPricing 创建或更新渠道定价
func CreateChannelPricing(c *gin.Context) {
	var req CreateChannelPricingRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		common.ApiError(c, err)
		return
	}

	if req.CacheRatio < 0 || req.CacheCreationRatio < 0 || req.ImageRatio < 0 || req.AudioRatio < 0 || req.AudioCompletionRatio < 0 {
		common.ApiErrorMsg(c, "ratio values must be >= 0")
		return
	}

	// 检查是否已存在
	existing, _ := model.GetChannelPricing(req.ModelName, req.ChannelId)
	if existing != nil {
		applyRequestFields(existing, &req)
		if err := existing.Update(); err != nil {
			common.ApiError(c, err)
			return
		}
		common.SysLog(fmt.Sprintf("[ChannelPricing] updated: id=%d model=%s channel=%d", existing.Id, existing.ModelName, existing.ChannelId))
		common.ApiSuccess(c, existing)
		return
	}

	// 创建
	cp := &model.ChannelPricing{
		ModelName: req.ModelName,
		ChannelId: req.ChannelId,
	}
	applyRequestFields(cp, &req)
	if err := cp.Insert(); err != nil {
		common.ApiError(c, err)
		return
	}

	common.SysLog(fmt.Sprintf("[ChannelPricing] created: model=%s channel=%d quotaType=%d modelRatio=%.4f completionRatio=%.4f modelPrice=%.4f cacheRatio=%.4f cacheCreationRatio=%.4f imageRatio=%.4f audioRatio=%.4f audioCompletionRatio=%.4f",
		req.ModelName, req.ChannelId, req.QuotaType, req.ModelRatio, req.CompletionRatio, req.ModelPrice,
		req.CacheRatio, req.CacheCreationRatio, req.ImageRatio, req.AudioRatio, req.AudioCompletionRatio))
	common.ApiSuccess(c, cp)
}

// BatchCreateChannelPricingRequest 批量创建请求
type BatchCreateChannelPricingRequest struct {
	Items []*CreateChannelPricingRequest `json:"items" binding:"required"`
}

// BatchCreateChannelPricing 批量创建或更新渠道定价
func BatchCreateChannelPricing(c *gin.Context) {
	var req BatchCreateChannelPricingRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		common.ApiError(c, err)
		return
	}

	pricings := make([]*model.ChannelPricing, 0, len(req.Items))
	for _, item := range req.Items {
		cp := &model.ChannelPricing{
			ModelName: item.ModelName,
			ChannelId: item.ChannelId,
		}
		applyRequestFields(cp, item)
		pricings = append(pricings, cp)
	}

	// 使用事务逐个处理（GORM 的批量 upsert 在不同数据库表现不一致）
	for _, cp := range pricings {
		existing, _ := model.GetChannelPricing(cp.ModelName, cp.ChannelId)
		if existing != nil {
			existing.ApplyFields(cp.QuotaType, cp.ModelRatio, cp.CompletionRatio, cp.ModelPrice, cp.TagIds,
				cp.CacheRatio, cp.CacheCreationRatio, cp.ImageRatio, cp.AudioRatio, cp.AudioCompletionRatio)
			if err := existing.Update(); err != nil {
				common.ApiError(c, err)
				return
			}
		} else {
			if err := cp.Insert(); err != nil {
				common.ApiError(c, err)
				return
			}
		}
	}

	common.ApiSuccess(c, gin.H{"affected": len(pricings)})
}

// DeleteChannelPricing 删除渠道定价
func DeleteChannelPricing(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		common.ApiError(c, err)
		return
	}

	cp := &model.ChannelPricing{Id: id}
	if err := cp.Delete(); err != nil {
		common.ApiError(c, err)
		return
	}

	common.SysLog(fmt.Sprintf("[ChannelPricing] deleted: id=%d", id))
	common.ApiSuccess(c, nil)
}

// CopyGlobalPricingRequest 复制全局定价请求
type CopyGlobalPricingRequest struct {
	Overwrite bool `json:"overwrite"` // 是否覆盖已存在的渠道定价
}

// CopyGlobalPricing 复制全局定价到指定渠道
// 从 ratio_setting 读取全局定价信息，复制到 channel_pricing 表
func CopyGlobalPricing(c *gin.Context) {
	channelIdStr := c.Param("channel_id")
	channelId, err := strconv.Atoi(channelIdStr)
	if err != nil {
		common.ApiError(c, err)
		return
	}

	var req CopyGlobalPricingRequest
	c.ShouldBindJSON(&req)

	// 获取该渠道支持的所有模型（使用 GetAbilitiesByChannelId）
	abilities, err := model.GetAbilitiesByChannelId(channelId)
	if err != nil {
		common.ApiError(c, err)
		return
	}

	imported := 0
	for _, ability := range abilities {
		// 检查是否已存在
		existing, _ := model.GetChannelPricing(ability.Model, channelId)
		if existing != nil && !req.Overwrite {
			continue
		}

		// 获取全局扩展比率
		globalCacheRatio, hasCacheRatio := ratio_setting.GetCacheRatio(ability.Model)
		if !hasCacheRatio {
			globalCacheRatio = 0
		}
		globalCacheCreationRatio, hasCacheCreationRatio := ratio_setting.GetCreateCacheRatio(ability.Model)
		if !hasCacheCreationRatio {
			globalCacheCreationRatio = 0
		}
		globalImageRatio, hasImageRatio := ratio_setting.GetImageRatio(ability.Model)
		if !hasImageRatio {
			globalImageRatio = 0
		}
		globalAudioRatio, hasAudioRatio := ratio_setting.GetAudioRatioV2(ability.Model)
		if !hasAudioRatio {
			globalAudioRatio = 0
		}
		globalAudioCompletionRatio, hasAudioCompRatio := ratio_setting.GetAudioCompletionRatioV2(ability.Model)
		if !hasAudioCompRatio {
			globalAudioCompletionRatio = 0
		}

		// 确定定价类型
		var quotaType int
		var ratio, completionRatio, price float64

		// 优先检查是否有按次计费的价格
		modelPrice, hasPrice := ratio_setting.GetModelPrice(ability.Model, false)
		if hasPrice {
			quotaType = model.QuotaTypeByCall
			price = modelPrice
		} else {
			// 使用按量计费
			quotaType = model.QuotaTypeByTokens
			modelRatio, hasRatio, _ := ratio_setting.GetModelRatio(ability.Model)
			if hasRatio {
				ratio = modelRatio
			}
			completionRatio = ratio_setting.GetCompletionRatio(ability.Model)
		}

		if existing != nil {
			existing.ApplyFields(quotaType, ratio, completionRatio, price, "",
				globalCacheRatio, globalCacheCreationRatio, globalImageRatio, globalAudioRatio, globalAudioCompletionRatio)
			if err := existing.Update(); err == nil {
				imported++
			}
		} else {
			cp := &model.ChannelPricing{
				ModelName: ability.Model,
				ChannelId: channelId,
			}
			cp.ApplyFields(quotaType, ratio, completionRatio, price, "",
				globalCacheRatio, globalCacheCreationRatio, globalImageRatio, globalAudioRatio, globalAudioCompletionRatio)
			if err := cp.Insert(); err == nil {
				imported++
			}
		}
	}

	common.SysLog(fmt.Sprintf("[ChannelPricing] copyGlobalPricing: channel=%d imported=%d/%d", channelId, imported, len(abilities)))
	common.ApiSuccess(c, gin.H{
		"total":    len(abilities),
		"imported": imported,
	})
}

// ChannelPricingWithTags 带标签详情的渠道定价响应
type ChannelPricingWithTags struct {
	*model.ChannelPricing
	Tags []*model.PricingTag `json:"tags"`
}

// GetChannelPricingByModelWithChannelInfo 获取指定模型的渠道定价（带渠道信息，所有用户可访问）
func GetChannelPricingByModelWithChannelInfo(c *gin.Context) {
	// 使用通配符路由时，参数包含前导斜杠，需要去除
	modelName := c.Param("name")
	if modelName == "" {
		common.ApiErrorMsg(c, "model name is required")
		return
	}
	// 去除前导斜杠（路由是 /channel-pricing/model/*name，name 会是 "/deepseek-ai/xxx"）
	modelName = strings.TrimPrefix(modelName, "/")

	list, err := model.GetChannelPricingByModelWithChannelInfo(modelName)
	if err != nil {
		common.ApiError(c, err)
		return
	}

	common.ApiSuccess(c, list)
}

// GetChannelPricingWithTags 获取渠道定价（带标签详情）
func GetChannelPricingWithTags(c *gin.Context) {
	page, _ := strconv.Atoi(c.DefaultQuery("p", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))
	offset := (page - 1) * pageSize

	list, total, err := model.GetAllChannelPricing(offset, pageSize)
	if err != nil {
		common.ApiError(c, err)
		return
	}

	// 获取所有标签
	tags, _ := model.GetAllPricingTags()
	tagMap := make(map[int]*model.PricingTag)
	for _, tag := range tags {
		tagMap[tag.Id] = tag
	}

	// 为每个定价填充标签详情
	result := make([]*ChannelPricingWithTags, 0, len(list))
	for _, cp := range list {
		item := &ChannelPricingWithTags{
			ChannelPricing: cp,
			Tags:           model.ParseTagIds(cp.TagIds, tagMap),
		}
		result = append(result, item)
	}

	common.ApiSuccess(c, gin.H{
		"page":      page,
		"page_size": pageSize,
		"total":     total,
		"items":     result,
	})
}

// SetDefaultChannelRequest 设置默认通道请求
type SetDefaultChannelRequest struct {
	ModelName string `json:"model_name" binding:"required"`
	ChannelId int    `json:"channel_id" binding:"required"`
}

// SetDefaultChannel 设置指定模型的默认通道
func SetDefaultChannel(c *gin.Context) {
	var req SetDefaultChannelRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		common.ApiError(c, err)
		return
	}

	// 验证渠道定价记录存在
	existing, err := model.GetChannelPricing(req.ModelName, req.ChannelId)
	if err != nil || existing == nil {
		common.ApiErrorMsg(c, "channel pricing not found for this model and channel")
		return
	}

	if err := model.SetDefaultChannel(req.ModelName, req.ChannelId); err != nil {
		common.ApiError(c, err)
		return
	}

	common.SysLog(fmt.Sprintf("[ChannelPricing] set default: model=%s channel=%d", req.ModelName, req.ChannelId))
	common.ApiSuccess(c, nil)
}

// ClearDefaultChannel 清除指定模型的默认通道
func ClearDefaultChannel(c *gin.Context) {
	modelName := c.Param("name")
	modelName = strings.TrimPrefix(modelName, "/")
	if modelName == "" {
		common.ApiErrorMsg(c, "model name is required")
		return
	}

	if err := model.ClearDefaultChannel(modelName); err != nil {
		common.ApiError(c, err)
		return
	}

	common.SysLog(fmt.Sprintf("[ChannelPricing] cleared default: model=%s", modelName))
	common.ApiSuccess(c, nil)
}
