package controller

import (
	"net/http"
	"sort"
	"strconv"
	"time"

	"github.com/QuantumNous/new-api/common"
	"github.com/QuantumNous/new-api/model"
	"github.com/gin-gonic/gin"
)

// SupplierModelUsageItem 供应商模型使用统计项。
type SupplierModelUsageItem struct {
	ModelName string `json:"model_name"`
	Requests  int    `json:"requests"`
	Tokens    int    `json:"tokens"`
	Quota     int    `json:"quota"`
}

// loadSupplierDashboardAccount 加载供应商对接人（申请人）在平台上的剩余额度与历史累计已用额度，与使用日志中的额度/花费字段同源。
func loadSupplierDashboardAccount(c *gin.Context, adminSupplierID int) (quota int, usedQuota int) {
	if c.GetInt("role") >= common.RoleAdminUser {
		if adminSupplierID <= 0 {
			return 0, 0
		}
		app, err := model.GetSupplierByID(adminSupplierID)
		if err != nil || app == nil || app.ApplicantUserID <= 0 {
			return 0, 0
		}
		u, err := model.GetUserById(app.ApplicantUserID, false)
		if err != nil {
			return 0, 0
		}
		return u.Quota, u.UsedQuota
	}
	u, err := model.GetUserById(c.GetInt("id"), false)
	if err != nil {
		return 0, 0
	}
	return u.Quota, u.UsedQuota
}

// parseSupplierDashboardTimeRange 解析供应商看板时间范围：请求参数 start_timestamp、end_timestamp 为 Unix 秒；未传或非法时默认最近 24 小时。
func parseSupplierDashboardTimeRange(c *gin.Context) (int64, int64) {
	startTimestamp, _ := strconv.ParseInt(c.Query("start_timestamp"), 10, 64)
	endTimestamp, _ := strconv.ParseInt(c.Query("end_timestamp"), 10, 64)
	if endTimestamp <= 0 {
		endTimestamp = time.Now().Unix()
	}
	if startTimestamp <= 0 || startTimestamp >= endTimestamp {
		startTimestamp = endTimestamp - 24*3600
	}
	return startTimestamp, endTimestamp
}

// toSortedModelSlice 将模型集合转换为稳定排序切片。
func toSortedModelSlice(modelsMap map[string]struct{}) []string {
	modelNames := make([]string, 0, len(modelsMap))
	for modelName := range modelsMap {
		modelNames = append(modelNames, modelName)
	}
	sort.Strings(modelNames)
	return modelNames
}

// GetSupplierDashboardData 返回供应商数据看板（供应商看自己，管理员看全部供应商模型）。
func GetSupplierDashboardData(c *gin.Context) {
	startTimestamp, endTimestamp := parseSupplierDashboardTimeRange(c)
	adminSupplierID, _ := strconv.Atoi(c.Query("supplier_id"))
	accountQuota, accountUsedQuota := loadSupplierDashboardAccount(c, adminSupplierID)

	var (
		modelNamesMap map[string]struct{}
		err           error
	)

	// 管理员默认查看全部供应商模型；当传 supplier_id 时查看指定供应商。
	if c.GetInt("role") >= common.RoleAdminUser {
		supplierID := adminSupplierID
		if supplierID > 0 {
			modelNamesMap, err = collectSupplierOwnedModelNamesBySupplierID(supplierID)
		} else {
			modelNamesMap, err = collectAllSupplierOwnedModelNames()
		}
	} else {
		modelNamesMap, err = collectSupplierOwnedModelNames(c.GetInt("id"))
	}
	if err != nil {
		common.ApiError(c, err)
		return
	}

	modelNames := toSortedModelSlice(modelNamesMap)
	quotaData, err := model.GetQuotaDataByModelNames(startTimestamp, endTimestamp, modelNames)
	if err != nil {
		common.ApiError(c, err)
		return
	}
	stat, err := model.SumUsedQuotaByModelNames(startTimestamp, endTimestamp, modelNames)
	if err != nil {
		common.ApiError(c, err)
		return
	}

	usageMap := make(map[string]*SupplierModelUsageItem)
	totalRequests := 0
	totalTokens := 0
	totalQuota := 0

	for _, item := range quotaData {
		if item == nil {
			continue
		}
		totalRequests += item.Count
		totalTokens += item.TokenUsed
		totalQuota += item.Quota

		usageItem, ok := usageMap[item.ModelName]
		if !ok {
			usageItem = &SupplierModelUsageItem{
				ModelName: item.ModelName,
			}
			usageMap[item.ModelName] = usageItem
		}
		usageItem.Requests += item.Count
		usageItem.Tokens += item.TokenUsed
		usageItem.Quota += item.Quota
	}

	modelUsageStats := make([]*SupplierModelUsageItem, 0, len(usageMap))
	for _, usageItem := range usageMap {
		modelUsageStats = append(modelUsageStats, usageItem)
	}
	sort.Slice(modelUsageStats, func(i, j int) bool {
		return modelUsageStats[i].Quota > modelUsageStats[j].Quota
	})

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "",
		"data": gin.H{
			"start_timestamp":   startTimestamp,
			"end_timestamp":     endTimestamp,
			"usage_time_range": gin.H{
				"start_timestamp": startTimestamp,
				"end_timestamp":   endTimestamp,
				"bucket":          "hour",
			},
			"account": gin.H{
				"quota":      accountQuota,
				"used_quota": accountUsedQuota,
			},
			"model_names":       modelNames,
			"quota_data":        quotaData,
			"model_usage_stats": modelUsageStats,
			"resource_consumption": gin.H{
				"total_requests": totalRequests,
				"total_tokens":   totalTokens,
				"total_quota":    totalQuota,
			},
			"performance_metrics": gin.H{
				"rpm": stat.Rpm,
				"tpm": stat.Tpm,
			},
			"model_data_analysis": gin.H{
				// provided_model_count: 供应商配置过的模型总数（无请求也计入）。
				"provided_model_count": len(modelNames),
				// active_model_count: 时间范围内有调用数据的模型数。
				"active_model_count": len(modelUsageStats),
				// model_count 保留为兼容字段，语义等同 provided_model_count。
				"model_count": len(modelNames),
				"top_models":  modelUsageStats,
			},
		},
	})
}
