package main

import (
	"context"
	"flag"
	"fmt"
	"sort"

	"bindbox-game/internal/pkg/logger"
	"bindbox-game/internal/pkg/redis"
	"bindbox-game/internal/repository/mysql"
	"bindbox-game/internal/repository/mysql/dao"
	activitysvc "bindbox-game/internal/service/activity"
)

// usage: go run cmd/matching_sim/main.go -env dev -runs 10000
func main() {
	runs := flag.Int("runs", 10000, "运行模拟的次数")
	flag.Parse()

	// 1. 初始化数据库
	dbRepo, err := mysql.New()
	if err != nil {
		panic(fmt.Sprintf("数据库连接失败: %v", err))
	}

	// 2. 初始化日志 (模拟 Service 需要)
	l, err := logger.NewCustomLogger(dao.Use(dbRepo.GetDbW()))
	if err != nil {
		panic(err)
	}

	// 3. 初始化 Service (完全模拟真实注入)
	// 注意：这里不需要真实的 user service，传入 nil 即可
	svc := activitysvc.New(l, dbRepo, nil, redis.GetClient())

	ctx := context.Background()

	// 4. 从真实数据库加载卡牌配置
	fmt.Println(">>> 正在从数据库加载真实卡牌配置...")
	configs, err := svc.ListMatchingCardTypes(ctx)
	if err != nil {
		panic(fmt.Sprintf("读取卡牌配置失败: %v", err))
	}

	if len(configs) == 0 {
		fmt.Println("警告: 数据库中没有启用的卡牌配置，将使用默认配置。")
		configs = []activitysvc.CardTypeConfig{
			{Code: "A", Quantity: 9}, {Code: "B", Quantity: 9}, {Code: "C", Quantity: 9},
			{Code: "D", Quantity: 9}, {Code: "E", Quantity: 9}, {Code: "F", Quantity: 9},
			{Code: "G", Quantity: 9}, {Code: "H", Quantity: 9}, {Code: "I", Quantity: 9},
			{Code: "J", Quantity: 9}, {Code: "K", Quantity: 9},
		}
	}

	fmt.Println("当前生效配置:")
	for _, c := range configs {
		fmt.Printf("  - [%s]: %d张\n", c.Code, c.Quantity)
	}

	// 5. 开始执行模拟
	fmt.Printf("\n>>> 正在执行 %d 次大规模真实模拟...\n", *runs)
	results := make(map[int64]int)
	mseed := []byte("production_simulation_seed")
	position := "B" // 默认模拟选中 B 类型

	for i := 0; i < *runs; i++ {
		// 调用真实业务函数创建游戏 (固定数量逻辑)
		game := activitysvc.NewMatchingGameWithConfig(configs, position, mseed)

		// 调用真实业务模拟函数
		pairs := game.SimulateMaxPairs()
		results[pairs]++
	}

	// 6. 统计并输出
	fmt.Println("\n对数分布统计 (100% 模拟真实生产路径):")
	var pairsList []int64
	for k := range results {
		pairsList = append(pairsList, k)
	}
	sort.Slice(pairsList, func(i, j int) bool {
		return pairsList[i] < pairsList[j]
	})

	sumPairs := int64(0)
	for _, p := range pairsList {
		count := results[p]
		sumPairs += p * int64(count)
		fmt.Printf("  %2d 对: %5d 次 (%5.2f%%)\n", p, count, float64(count)/float64(*runs)*100)
	}
	fmt.Printf("\n平均对数: %.4f\n\n", float64(sumPairs)/float64(*runs))
}
