package agent

import (
	"math/rand"
	"strconv"
	"time"
	"verification-platform-backend/internal/database"
	"verification-platform-backend/internal/model"
	"verification-platform-backend/pkg/response"

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

func SetupAgentRoutes(r *gin.RouterGroup) {
	r.GET("/stats", handleGetStats)
	r.GET("/apps", handleGetApps)
	r.GET("/cards", handleGetCards)
	r.POST("/cards/generate", handleGenerateCards)
	r.GET("/users", handleGetUsers)
	r.GET("/finance", handleGetFinance)
	r.GET("/profile", handleGetProfile)
	r.PUT("/profile", handleUpdateProfile)
}

func handleGetStats(c *gin.Context) {
	userID := c.GetUint("user_id")

	var totalApps int64
	database.DB.Model(&model.AgentApplication{}).Where("agent_id = ?", userID).Count(&totalApps)

	var totalCards int64
	database.DB.Model(&model.Card{}).Where("agent_id = ?", userID).Count(&totalCards)

	var totalUsers int64
	var agentApps []model.AgentApplication
	database.DB.Where("agent_id = ?", userID).Find(&agentApps)
	appIDs := make([]uint, 0)
	for _, app := range agentApps {
		appIDs = append(appIDs, app.ApplicationID)
	}
	if len(appIDs) > 0 {
		database.DB.Model(&model.AppUser{}).Where("application_id IN ?", appIDs).Count(&totalUsers)
	}

	var totalRevenue float64
	database.DB.Model(&model.Card{}).Where("agent_id = ?", userID).Select("COALESCE(SUM(price), 0)").Scan(&totalRevenue)

	today := time.Now().Format("2006-01-02")
	var todayCards int64
	database.DB.Model(&model.Card{}).Where("agent_id = ? AND DATE(created_at) = ?", userID, today).Count(&todayCards)

	var todayRevenue float64
	database.DB.Model(&model.Card{}).Where("agent_id = ? AND DATE(created_at) = ?", userID, today).Select("COALESCE(SUM(price), 0)").Scan(&todayRevenue)

	response.Success(c, gin.H{
		"totalApps":     totalApps,
		"totalCards":    totalCards,
		"totalUsers":    totalUsers,
		"totalRevenue":  totalRevenue,
		"todayCards":    todayCards,
		"todayRevenue":  todayRevenue,
	})
}

func handleGetApps(c *gin.Context) {
	userID := c.GetUint("user_id")

	var agentApps []model.AgentApplication
	if err := database.DB.Where("agent_id = ?", userID).Preload("Application").Find(&agentApps).Error; err != nil {
		response.Error(c, 500, "获取应用列表失败")
		return
	}

	apps := make([]gin.H, 0)
	for _, aa := range agentApps {
		if aa.Application.ID > 0 {
			apps = append(apps, gin.H{
				"id":            aa.Application.ID,
				"name":          aa.Application.Name,
				"description":   aa.Application.Description,
				"status":        aa.Application.Status,
				"authorized_at": aa.CreatedAt,
			})
		}
	}

	response.Success(c, gin.H{
		"apps": apps,
	})
}

func handleGetCards(c *gin.Context) {
	userID := c.GetUint("user_id")

	page := c.DefaultQuery("page", "1")
	pageSize := c.DefaultQuery("page_size", "20")

	var total int64
	database.DB.Model(&model.Card{}).Where("agent_id = ?", userID).Count(&total)

	var cards []model.Card
	offset := 0
	if pageInt, err := strconv.Atoi(page); err == nil && pageInt > 1 {
		offset = (pageInt - 1) * 20
	}

	limit := 20
	if pageSizeInt, err := strconv.Atoi(pageSize); err == nil && pageSizeInt > 0 {
		limit = pageSizeInt
	}

	database.DB.Where("agent_id = ?", userID).Order("created_at DESC").Limit(limit).Offset(offset).Find(&cards)

	response.Success(c, gin.H{
		"cards": cards,
		"total": total,
	})
}

func handleGenerateCards(c *gin.Context) {
	userID := c.GetUint("user_id")

	var req struct {
		ApplicationID uint `json:"application_id"`
		CardTypeID    uint `json:"card_type_id"`
		Quantity      int  `json:"quantity"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

	var agentApp model.AgentApplication
	if err := database.DB.Where("agent_id = ? AND application_id = ?", userID, req.ApplicationID).First(&agentApp).Error; err != nil {
		response.Error(c, 403, "无权操作该应用")
		return
	}

	cards := make([]model.Card, req.Quantity)
	for i := 0; i < req.Quantity; i++ {
		cards[i] = model.Card{
			ApplicationID: req.ApplicationID,
			CardTypeID:    req.CardTypeID,
			CardKey:       generateCardCode(),
			CreatorID:     userID,
			Status:        "unused",
		}
	}

	if err := database.DB.Create(&cards).Error; err != nil {
		response.Error(c, 500, "生成卡密失败")
		return
	}

	response.Success(c, gin.H{
		"count": req.Quantity,
	})
}

func generateCardCode() string {
	const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	b := make([]byte, 16)
	for i := range b {
		b[i] = charset[rand.Intn(len(charset))]
	}
	return string(b)
}

func handleGetUsers(c *gin.Context) {
	userID := c.GetUint("user_id")

	var agentApps []model.AgentApplication
	database.DB.Where("agent_id = ?", userID).Find(&agentApps)
	appIDs := make([]uint, 0)
	for _, app := range agentApps {
		appIDs = append(appIDs, app.ApplicationID)
	}

	if len(appIDs) == 0 {
		response.Success(c, gin.H{
			"users": []interface{}{},
			"total": 0,
		})
		return
	}

	page := c.DefaultQuery("page", "1")
	pageSize := c.DefaultQuery("page_size", "20")

	var total int64
	database.DB.Model(&model.AppUser{}).Where("application_id IN ?", appIDs).Count(&total)

	var users []model.AppUser
	offset := 0
	if pageInt, err := strconv.Atoi(page); err == nil && pageInt > 1 {
		offset = (pageInt - 1) * 20
	}

	limit := 20
	if pageSizeInt, err := strconv.Atoi(pageSize); err == nil && pageSizeInt > 0 {
		limit = pageSizeInt
	}

	database.DB.Where("application_id IN ?", appIDs).Order("created_at DESC").Limit(limit).Offset(offset).Find(&users)

	response.Success(c, gin.H{
		"users": users,
		"total": total,
	})
}

func handleGetFinance(c *gin.Context) {
	userID := c.GetUint("user_id")

	var user model.User
	if err := database.DB.First(&user, userID).Error; err != nil {
		response.Error(c, 404, "用户不存在")
		return
	}

	var records []model.RechargeRecord
	database.DB.Where("user_id = ?", userID).Order("created_at DESC").Limit(20).Find(&records)

	response.Success(c, gin.H{
		"balance":  user.Balance,
		"records":  records,
	})
}

func handleGetProfile(c *gin.Context) {
	userID := c.GetUint("user_id")

	var user model.User
	if err := database.DB.First(&user, userID).Error; err != nil {
		response.Error(c, 404, "用户不存在")
		return
	}

	response.Success(c, gin.H{
		"id":              user.ID,
		"username":        user.Username,
		"email":           user.Email,
		"avatar":          user.Avatar,
		"balance":         user.Balance,
		"can_create_agent": user.CanCreateAgent,
	})
}

func handleUpdateProfile(c *gin.Context) {
	userID := c.GetUint("user_id")

	var req struct {
		Email string `json:"email"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

	var user model.User
	if err := database.DB.First(&user, userID).Error; err != nil {
		response.Error(c, 404, "用户不存在")
		return
	}

	if req.Email != "" {
		user.Email = &req.Email
	}
	database.DB.Save(&user)

	response.Success(c, nil)
}
