package activity

import (
	"context"
	"time"

	"bindbox-game/internal/pkg/logger"
	"bindbox-game/internal/repository/mysql"
	"bindbox-game/internal/repository/mysql/dao"
	"bindbox-game/internal/repository/mysql/model"
	usersvc "bindbox-game/internal/service/user"

	"github.com/redis/go-redis/v9"
)

type Service interface {
	// ... (other methods)
	// ProcessOrderLottery 处理订单开奖（统一幂等逻辑）
	// 参数: ctx 上下文, orderID 订单ID
	// 返回: 错误信息
	ProcessOrderLottery(ctx context.Context, orderID int64) error

	// CreateActivity 创建活动
	// 参数: in 活动创建输入
	// 返回: 活动记录与错误
	CreateActivity(ctx context.Context, in CreateActivityInput) (*model.Activities, error)
	// ModifyActivity 修改活动
	// 参数: id 活动ID, in 修改输入
	// 返回: 错误信息
	ModifyActivity(ctx context.Context, id int64, in ModifyActivityInput) error
	// DeleteActivity 删除活动
	// 参数: id 活动ID
	// 返回: 错误信息
	DeleteActivity(ctx context.Context, id int64) error
	// GetActivity 获取活动详情
	// 参数: id 活动ID
	// 返回: 活动记录与错误
	GetActivity(ctx context.Context, id int64) (*model.Activities, error)
	// ListActivities 活动列表
	// 参数: in 列表查询输入
	// 返回: 活动集合、总数与错误
	ListActivities(ctx context.Context, in ListActivitiesInput) (items []*model.Activities, total int64, err error)

	// ListIssues 活动期列表
	// 参数: activityID 活动ID, page 页码, pageSize 每页数量
	// 返回: 期列表、总数与错误
	ListIssues(ctx context.Context, activityID int64, page, pageSize int) (items []*model.ActivityIssues, total int64, err error)
	// CreateIssue 创建期
	// 参数: activityID 活动ID, in 创建输入
	// 返回: 期记录与错误
	CreateIssue(ctx context.Context, activityID int64, in CreateIssueInput) (*model.ActivityIssues, error)
	// ModifyIssue 修改期
	// 参数: issueID 期ID, in 修改输入
	// 返回: 错误信息
	ModifyIssue(ctx context.Context, issueID int64, in ModifyIssueInput) error
	// DeleteIssue 删除期
	// 参数: issueID 期ID
	// 返回: 错误信息
	DeleteIssue(ctx context.Context, issueID int64) error

	// CreateIssueRewards 批量创建期奖励
	// 参数: issueID 期ID, rewards 奖励创建输入数组
	// 返回: 错误信息
	CreateIssueRewards(ctx context.Context, issueID int64, rewards []CreateRewardInput) error
	// ListIssueRewards 查询期奖励列表
	// 参数: issueID 期ID
	// 返回: 奖励集合与错误
	ListIssueRewards(ctx context.Context, issueID int64) (items []*model.ActivityRewardSettings, err error)
	// ModifyIssueReward 修改单个奖励
	// 参数: rewardID 奖励ID, in 修改输入
	// 返回: 错误信息
	ModifyIssueReward(ctx context.Context, rewardID int64, in ModifyRewardInput) error
	// DeleteIssueReward 删除单个奖励
	// 参数: rewardID 奖励ID
	// 返回: 错误信息
	DeleteIssueReward(ctx context.Context, rewardID int64) error

	// ListDrawLogs 抽奖记录列表
	// 参数: issueID 期ID, page/pageSize 分页, level 等级过滤
	// 返回: 抽奖记录集合、总数与错误
	ListDrawLogs(ctx context.Context, issueID int64, page, pageSize int, level *int32) (items []*model.ActivityDrawLogs, total int64, err error)

	// GetCategoryNames 批量查询分类名称
	// 参数: ids 分类ID数组
	// 返回: id->名称映射与错误
	GetCategoryNames(ctx context.Context, ids []int64) (map[int64]string, error)

	// CopyActivity 复制活动及其期次与奖励
	// 参数: activityID 源活动ID
	// 返回: 新活动ID与错误
	CopyActivity(ctx context.Context, activityID int64) (int64, error)

	// SaveActivityDrawConfig 保存活动开奖配置
	// 参数: activityID 活动ID, cfg 配置
	// 返回: 错误信息
	SaveActivityDrawConfig(ctx context.Context, activityID int64, cfg DrawConfig) error
	// GetActivityDrawConfig 读取活动开奖配置
	// 参数: activityID 活动ID
	// 返回: 配置与错误
	GetActivityDrawConfig(ctx context.Context, activityID int64) (*DrawConfig, error)

	// ReconstructMatchingGame 还原对对碰游戏过程
	ReconstructMatchingGame(ctx context.Context, orderNo string) (*MatchingGame, error)
	// GetMatchingGameFromRedis 从缓存获取游戏
	GetMatchingGameFromRedis(ctx context.Context, gameID string) (*MatchingGame, error)
	// SaveMatchingGameToRedis 保存游戏到缓存
	SaveMatchingGameToRedis(ctx context.Context, gameID string, game *MatchingGame) error
	// ListMatchingCardTypes 获取卡牌类型配置
	ListMatchingCardTypes(ctx context.Context) ([]CardTypeConfig, error)
	// ClearIchibanPositionsByOrderID 清理订单对应的一番赏占位
	ClearIchibanPositionsByOrderID(ctx context.Context, orderID int64) error
}

type service struct {
	logger  logger.CustomLogger
	readDB  *dao.Query
	writeDB *dao.Query
	repo    mysql.Repo
	user    usersvc.Service
	redis   *redis.Client
}

func New(l logger.CustomLogger, db mysql.Repo, u usersvc.Service, rdb *redis.Client) Service {
	return &service{
		logger:  l,
		readDB:  dao.Use(db.GetDbR()),
		writeDB: dao.Use(db.GetDbW()),
		repo:    db,
		user:    u,
		redis:   rdb,
	}
}

type CreateActivityInput struct {
	// Name 活动名称
	Name string
	// Banner 活动头图
	Banner string
	// Image 活动主图
	Image string
	// GameplayIntro 玩法介绍
	GameplayIntro string
	// ActivityCategoryID 活动分类ID
	ActivityCategoryID int64
	// Status 活动状态
	Status int32
	// PriceDraw 单次抽奖价格（分）
	PriceDraw int64
	// IsBoss 是否Boss活动
	IsBoss int32
	// StartTime 活动开始时间（可选）
	StartTime *time.Time
	// EndTime 活动结束时间（可选）
	EndTime        *time.Time
	AllowItemCards int32
	AllowCoupons   int32
}

type ModifyActivityInput struct {
	// Name 活动名称
	Name string
	// Banner 活动头图
	Banner string
	// Image 活动主图
	Image string
	// GameplayIntro 玩法介绍
	GameplayIntro string
	// ActivityCategoryID 活动分类ID
	ActivityCategoryID int64
	// Status 活动状态
	Status int32
	// PriceDraw 单次抽奖价格（分）
	PriceDraw int64
	// IsBoss 是否Boss活动
	IsBoss int32
	// StartTime 活动开始时间（可选）
	StartTime *time.Time
	// EndTime 活动结束时间（可选）
	EndTime        *time.Time
	AllowItemCards *int32
	AllowCoupons   *int32
}

type ListActivitiesInput struct {
	// Name 名称过滤
	Name string
	// CategoryID 分类过滤
	CategoryID int64
	// IsBoss Boss过滤
	IsBoss *int32
	// Status 状态过滤
	Status *int32
	// Page 页码
	Page int
	// PageSize 每页数量
	PageSize int
}

type CreateIssueInput struct {
	// IssueNumber 期号
	IssueNumber string
	// Status 状态
	Status int32
	// Sort 排序
	Sort int32
}

type ModifyIssueInput struct {
	// IssueNumber 期号
	IssueNumber string
	// Status 状态
	Status int32
	// Sort 排序
	Sort int32
}

type CreateRewardInput struct {
	// ProductID 商品ID
	ProductID int64
	// Name 奖励名称
	Name string
	// Weight 权重
	Weight int32
	// Quantity 数量（-1 表示不限）
	Quantity int64
	// OriginalQty 初始数量
	OriginalQty int64
	// Level 奖励等级
	Level int32
	// Sort 排序
	Sort int32
	// IsBoss 是否Boss奖励
	IsBoss   int32
	MinScore int64
}

type ModifyRewardInput struct {
	// ProductID 商品ID
	ProductID *int64
	// Name 奖励名称
	Name string
	// Weight 权重
	Weight *float64
	// Quantity 数量（-1 表示不限）
	Quantity *int64
	// OriginalQty 初始数量
	OriginalQty *int64
	// Level 奖励等级
	Level *int32
	// Sort 排序
	Sort *int32
	// IsBoss 是否Boss奖励
	IsBoss   *int32
	MinScore *int64
}
