package admin

import (
	"sync"
	"time"
	"verification-platform-backend/internal/database"
	"verification-platform-backend/internal/model"
	"verification-platform-backend/pkg/response"

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

func SetupDashboardRoutes(r *gin.RouterGroup) {
	r.GET("/dashboard", handleGetDashboard)
}

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

	var stats struct {
		TotalApplications int64   `json:"totalApplications"`
		TotalUsers        int64   `json:"totalUsers"`
		TotalCards        int64   `json:"totalCards"`
		MonthlyRevenue    float64 `json:"monthlyRevenue"`
	}

	var subscription struct {
		Plan           string `json:"plan"`
		Status         string `json:"status"`
		ExpireDate     string `json:"expireDate"`
		APIQuota       int    `json:"apiQuota"`
		APIUsed        int    `json:"apiUsed"`
		AppCount       int    `json:"appCount"`
		CanCreateAgent bool   `json:"canCreateAgent"`
		StorageQuota   int64  `json:"storageQuota"`
		StorageUsed    int64  `json:"storageUsed"`
	}

	userDistribution := gin.H{
		"provinces": []gin.H{},
		"overseas":  []gin.H{},
	}

	onlineTrend := make([]gin.H, 0, 30)
	recentTickets := make([]gin.H, 0, 5)

	var appIDs []uint
	database.DB.Model(&model.Application{}).Where("user_id = ?", userID).Pluck("id", &appIDs)

	var wg sync.WaitGroup
	var mu sync.Mutex

	wg.Add(8)

	go func() {
		defer wg.Done()
		database.DB.Model(&model.Application{}).Where("user_id = ?", userID).Count(&stats.TotalApplications)
	}()

	go func() {
		defer wg.Done()
		database.DB.Model(&model.Card{}).Where("creator_id = ?", userID).Count(&stats.TotalCards)
	}()

	go func() {
		defer wg.Done()
		if len(appIDs) > 0 {
			database.DB.Model(&model.AppUser{}).Where("application_id IN ?", appIDs).Count(&stats.TotalUsers)
		}
	}()

	go func() {
		defer wg.Done()
		if len(appIDs) > 0 {
			var appUserIDs []uint
			database.DB.Model(&model.AppUser{}).Where("application_id IN ?", appIDs).Pluck("id", &appUserIDs)
			if len(appUserIDs) > 0 {
				var revenue float64
				database.DB.Model(&model.RechargeRecord{}).
					Where("user_id IN ? AND status = ? AND created_at >= ?", appUserIDs, "success", time.Now().AddDate(0, -1, 0)).
					Select("COALESCE(SUM(amount), 0)").
					Scan(&revenue)
				stats.MonthlyRevenue = revenue
			}
		}
	}()

	go func() {
		defer wg.Done()
		var user model.User
		if err := database.DB.First(&user, userID).Error; err == nil {
			subscription.Plan = "基础版"
			if user.Role == "admin" {
				subscription.Plan = "管理员"
			}
			subscription.Status = "正常"
			if user.Status == "banned" {
				subscription.Status = "已禁用"
			}
			subscription.ExpireDate = "永久"
		}
	}()

	go func() {
		defer wg.Done()
		var apiUsed int64
		database.DB.Model(&model.ApiUsage{}).Where("user_id = ?", userID).Count(&apiUsed)
		subscription.APIUsed = int(apiUsed)

		var storageUsed int64
		database.DB.Model(&model.StorageUsage{}).Where("user_id = ?", userID).Select("COALESCE(SUM(size), 0)").Scan(&storageUsed)
		subscription.StorageUsed = storageUsed
	}()

	go func() {
		defer wg.Done()
		if len(appIDs) > 0 {
			var totalOnline int64
			var totalOffline int64

			var users []model.AppUser
			database.DB.Where("application_id IN ?", appIDs).Find(&users)

			cutoff := time.Now().Add(-5 * time.Minute)
			for _, user := range users {
				if user.LastHeartbeatAt != nil && user.LastHeartbeatAt.After(cutoff) {
					totalOnline++
				} else {
					totalOffline++
				}
			}

			provinces := []gin.H{
				{
					"name":    "China",
					"count":   totalOnline + totalOffline,
					"online":  totalOnline,
					"offline": totalOffline,
				},
			}

			mu.Lock()
			userDistribution["provinces"] = provinces
			mu.Unlock()
		}
	}()

	go func() {
		defer wg.Done()
		if len(appIDs) > 0 {
			type DailyCount struct {
				Date  string
				Count int64
			}
			var dailyCounts []DailyCount

			dateStart := time.Now().AddDate(0, 0, -29)
			dateStart = time.Date(dateStart.Year(), dateStart.Month(), dateStart.Day(), 0, 0, 0, 0, dateStart.Location())

			database.DB.Model(&model.DeviceSession{}).
				Select("DATE(last_heartbeat) as date, COUNT(*) as count").
				Joins("JOIN user_devices ON device_sessions.device_id = user_devices.id").
				Where("user_devices.application_id IN ? AND last_heartbeat >= ?", appIDs, dateStart).
				Group("DATE(last_heartbeat)").
				Order("date ASC").
				Find(&dailyCounts)

			countMap := make(map[string]int64)
			for _, dc := range dailyCounts {
				countMap[dc.Date] = dc.Count
			}

			trend := make([]gin.H, 0, 30)
			for i := 29; i >= 0; i-- {
				date := time.Now().AddDate(0, 0, -i)
				dateStr := date.Format("2006-01-02")
				count := countMap[dateStr]

				trend = append(trend, gin.H{
					"date":  date.Format("01-02"),
					"value": count,
				})
			}
			mu.Lock()
			onlineTrend = trend
			mu.Unlock()
		} else {
			trend := make([]gin.H, 0, 30)
			for i := 29; i >= 0; i-- {
				date := time.Now().AddDate(0, 0, -i)
				trend = append(trend, gin.H{
					"date":  date.Format("01-02"),
					"value": 0,
				})
			}
			mu.Lock()
			onlineTrend = trend
			mu.Unlock()
		}
	}()

	wg.Wait()

	subscription.AppCount = int(stats.TotalApplications)
	subscription.APIQuota = 10000
	subscription.StorageQuota = 100 * 1024 * 1024

	var tickets []model.Ticket
	database.DB.Where("user_id = ?", userID).Order("created_at DESC").Limit(5).Find(&tickets)
	for _, ticket := range tickets {
		recentTickets = append(recentTickets, gin.H{
			"id":         ticket.ID,
			"title":      ticket.Title,
			"status":     ticket.Status,
			"priority":   ticket.Priority,
			"created_at": ticket.CreatedAt,
		})
	}

	response.Success(c, gin.H{
		"stats":            stats,
		"subscription":     subscription,
		"userDistribution": userDistribution,
		"onlineTrend":      onlineTrend,
		"recentTickets":    recentTickets,
	})
}
