package holders

import (
	"log"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/gothinkster/golang-gin-realworld-example-app/common"
	"github.com/gothinkster/golang-gin-realworld-example-app/models"
)

// RegisterRoutes registers holders API routes
func RegisterRoutes(router *gin.RouterGroup) {
	router.GET("/stats", GetStats)
	router.GET("/:tokenType", GetHoldersByType)
	router.POST("/update", UpdateHolders)
}

// GetStats returns aggregated statistics for all token types
func GetStats(c *gin.Context) {
	db := common.GetDB()

	log.Printf("📊 [API] 收到获取统计数据请求 - IP: %s", c.ClientIP())

	var stats []models.HolderStats
	err := db.Raw(`
		SELECT
			token_type,
			COUNT(DISTINCT holder_address) as holder_count
		FROM holder_snapshots
		WHERE balance != '0' AND balance != '' AND LENGTH(balance) > 0
		GROUP BY token_type
	`).Scan(&stats).Error

	if err != nil {
		log.Printf("❌ [API] 查询统计数据失败: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"error":   "Failed to fetch stats",
		})
		return
	}

	log.Printf("✅ [API] 成功返回统计数据 - %d 个token类型", len(stats))
	for _, stat := range stats {
		log.Printf("   - %s: %d 个持有者", stat.TokenType, stat.HolderCount)
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"data":    stats,
	})
}

// GetHoldersByType returns holders for a specific token type
func GetHoldersByType(c *gin.Context) {
	tokenType := c.Param("tokenType")
	db := common.GetDB()

	// 记录请求日志
	log.Printf("🔍 [API] 收到获取持有者请求 - Token类型: %s, IP: %s", tokenType, c.ClientIP())

	var holders []models.HolderSnapshot
	err := db.Where("token_type = ? AND balance != ? AND balance != '' AND LENGTH(balance) > 0", tokenType, "0").
		Order("LENGTH(balance) DESC, balance DESC").
		Find(&holders).Error

	if err != nil {
		log.Printf("❌ [API] 查询持有者失败 - Token类型: %s, 错误: %v", tokenType, err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"error":   "Failed to fetch holders",
		})
		return
	}

	log.Printf("✅ [API] 成功返回 %d 个持有者 - Token类型: %s", len(holders), tokenType)

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"data":    holders,
	})
}

// Global scanner instance
var globalScanner *Scanner

// StartAllScanners 为所有支持的链启动 holder 扫描器（后台常驻）
func StartAllScanners() {
	supportedChains := []int64{97, 421614}
	for _, chainID := range supportedChains {
		config, err := LoadConfigFromDB(chainID)
		if err != nil {
			log.Printf("[HolderScanner] Chain %d 配置加载失败: %v", chainID, err)
			continue
		}
		if len(config.YTVaults) == 0 && config.YTLPAddress == "" {
			log.Printf("[HolderScanner] Chain %d 无活跃资产，跳过", chainID)
			continue
		}
		go func(cfg Config) {
			log.Printf("[HolderScanner] Chain %d 启动，YTVaults=%d ytLP=%s",
				cfg.ChainID, len(cfg.YTVaults), cfg.YTLPAddress)
			if err := Start(cfg); err != nil {
				log.Printf("[HolderScanner] Chain %d 异常退出: %v", cfg.ChainID, err)
			}
		}(config)
	}
}

// UpdateHolders triggers blockchain data update (admin only)
func UpdateHolders(c *gin.Context) {
	if globalScanner == nil {
		c.JSON(http.StatusOK, gin.H{
			"success": true,
			"message": "Scanner is running in background. It will process new blocks on next tick.",
			"timestamp": time.Now().Unix(),
		})
		return
	}
	go func() {
		if err := globalScanner.incrementalScan(c.Request.Context()); err != nil {
			log.Printf("[HolderScanner] Manual update error: %v", err)
		}
	}()
	c.JSON(http.StatusOK, gin.H{
		"success":   true,
		"message":   "Manual scan triggered.",
		"timestamp": time.Now().Unix(),
	})
}
