package admin

import (
	"net/http"
	"strconv"
	"strings"
	"time"

	"bindbox-game/internal/code"
	"bindbox-game/internal/pkg/core"
	"bindbox-game/internal/pkg/validation"
	"bindbox-game/internal/repository/mysql/model"
	"bindbox-game/internal/service/livestream"

	"gorm.io/gorm"
)

// ========== 直播间活动管理 ==========

type createLivestreamActivityRequest struct {
	Name                string `json:"name" binding:"required"`
	StreamerName        string `json:"streamer_name"`
	StreamerContact     string `json:"streamer_contact"`
	DouyinProductID     string `json:"douyin_product_id"`
	OrderRewardType     string `json:"order_reward_type"`     // 下单奖励类型: flip_card/minesweeper
	OrderRewardQuantity int32  `json:"order_reward_quantity"` // 下单奖励数量: 1-100
	TicketPrice         int64  `json:"ticket_price"`
	StartTime           string `json:"start_time"`
	EndTime             string `json:"end_time"`
}

type livestreamActivityResponse struct {
	ID                  int64  `json:"id"`
	Name                string `json:"name"`
	StreamerName        string `json:"streamer_name"`
	StreamerContact     string `json:"streamer_contact"`
	AccessCode          string `json:"access_code"`
	DouyinProductID     string `json:"douyin_product_id"`
	OrderRewardType     string `json:"order_reward_type"`     // 下单奖励类型
	OrderRewardQuantity int32  `json:"order_reward_quantity"` // 下单奖励数量
	TicketPrice         int64  `json:"ticket_price"`
	Status              int32  `json:"status"`
	StartTime           string `json:"start_time,omitempty"`
	EndTime             string `json:"end_time,omitempty"`
	CreatedAt           string `json:"created_at"`
}

// CreateLivestreamActivity 创建直播间活动
// @Summary 创建直播间活动
// @Description 创建新的直播间活动，自动生成唯一访问码
// @Tags 管理端.直播间
// @Accept json
// @Produce json
// @Param RequestBody body createLivestreamActivityRequest true "请求参数"
// @Success 200 {object} livestreamActivityResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/livestream/activities [post]
// @Security LoginVerifyToken
func (h *handler) CreateLivestreamActivity() core.HandlerFunc {
	return func(ctx core.Context) {
		req := new(createLivestreamActivityRequest)
		if err := ctx.ShouldBindJSON(req); err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
			return
		}

		input := livestream.CreateActivityInput{
			Name:                req.Name,
			StreamerName:        req.StreamerName,
			StreamerContact:     req.StreamerContact,
			DouyinProductID:     req.DouyinProductID,
			OrderRewardType:     req.OrderRewardType,
			OrderRewardQuantity: req.OrderRewardQuantity,
			TicketPrice:         req.TicketPrice,
		}

		if req.StartTime != "" {
			if t, err := time.ParseInLocation("2006-01-02 15:04:05", req.StartTime, time.Local); err == nil {
				input.StartTime = &t
			}
		}
		if req.EndTime != "" {
			if t, err := time.ParseInLocation("2006-01-02 15:04:05", req.EndTime, time.Local); err == nil {
				input.EndTime = &t
			}
		}

		activity, err := h.livestream.CreateActivity(ctx.RequestContext(), input)
		if err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
			return
		}

		ctx.Payload(&livestreamActivityResponse{
			ID:                  activity.ID,
			Name:                activity.Name,
			StreamerName:        activity.StreamerName,
			StreamerContact:     activity.StreamerContact,
			AccessCode:          activity.AccessCode,
			DouyinProductID:     activity.DouyinProductID,
			OrderRewardType:     activity.OrderRewardType,
			OrderRewardQuantity: activity.OrderRewardQuantity,
			TicketPrice:         int64(activity.TicketPrice),
			Status:              activity.Status,
			CreatedAt:           activity.CreatedAt.Format("2006-01-02 15:04:05"),
		})
	}
}

type updateLivestreamActivityRequest struct {
	Name                string `json:"name"`
	StreamerName        string `json:"streamer_name"`
	StreamerContact     string `json:"streamer_contact"`
	DouyinProductID     string `json:"douyin_product_id"`
	OrderRewardType     string `json:"order_reward_type"`     // 下单奖励类型
	OrderRewardQuantity *int32 `json:"order_reward_quantity"` // 下单奖励数量
	TicketPrice         *int64 `json:"ticket_price"`
	Status              *int32 `json:"status"`
	StartTime           string `json:"start_time"`
	EndTime             string `json:"end_time"`
}

// UpdateLivestreamActivity 更新直播间活动
// @Summary 更新直播间活动
// @Description 更新直播间活动信息
// @Tags 管理端.直播间
// @Accept json
// @Produce json
// @Param id path integer true "活动ID"
// @Param RequestBody body updateLivestreamActivityRequest true "请求参数"
// @Success 200 {object} simpleMessageResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/livestream/activities/{id} [put]
// @Security LoginVerifyToken
func (h *handler) UpdateLivestreamActivity() core.HandlerFunc {
	return func(ctx core.Context) {
		id, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
		if err != nil || id <= 0 {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "无效的活动ID"))
			return
		}

		req := new(updateLivestreamActivityRequest)
		if err := ctx.ShouldBindJSON(req); err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
			return
		}

		input := livestream.UpdateActivityInput{
			Name:                req.Name,
			StreamerName:        req.StreamerName,
			StreamerContact:     req.StreamerContact,
			DouyinProductID:     req.DouyinProductID,
			OrderRewardType:     req.OrderRewardType,
			OrderRewardQuantity: req.OrderRewardQuantity,
			TicketPrice:         req.TicketPrice,
			Status:              req.Status,
		}

		if req.StartTime != "" {
			if t, err := time.ParseInLocation("2006-01-02 15:04:05", req.StartTime, time.Local); err == nil {
				input.StartTime = &t
			}
		}
		if req.EndTime != "" {
			if t, err := time.ParseInLocation("2006-01-02 15:04:05", req.EndTime, time.Local); err == nil {
				input.EndTime = &t
			}
		}

		if err := h.livestream.UpdateActivity(ctx.RequestContext(), id, input); err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
			return
		}

		ctx.Payload(&simpleMessageResponse{Message: "操作成功"})
	}
}

type listLivestreamActivitiesRequest struct {
	Page     int    `form:"page"`
	PageSize int    `form:"page_size"`
	Status   *int32 `form:"status"`
}

type listLivestreamActivitiesResponse struct {
	List     []livestreamActivityResponse `json:"list"`
	Total    int64                        `json:"total"`
	Page     int                          `json:"page"`
	PageSize int                          `json:"page_size"`
}

// ListLivestreamActivities 直播间活动列表
// @Summary 直播间活动列表
// @Description 获取直播间活动列表
// @Tags 管理端.直播间
// @Accept json
// @Produce json
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(20)
// @Param status query int false "状态过滤"
// @Success 200 {object} listLivestreamActivitiesResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/livestream/activities [get]
// @Security LoginVerifyToken
func (h *handler) ListLivestreamActivities() core.HandlerFunc {
	return func(ctx core.Context) {
		req := new(listLivestreamActivitiesRequest)
		if err := ctx.ShouldBindForm(req); err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
			return
		}

		if req.Page <= 0 {
			req.Page = 1
		}
		if req.PageSize <= 0 {
			req.PageSize = 20
		}

		list, total, err := h.livestream.ListActivities(ctx.RequestContext(), req.Page, req.PageSize, req.Status)
		if err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
			return
		}

		res := &listLivestreamActivitiesResponse{
			List:     make([]livestreamActivityResponse, len(list)),
			Total:    total,
			Page:     req.Page,
			PageSize: req.PageSize,
		}

		for i, a := range list {
			item := livestreamActivityResponse{
				ID:                  a.ID,
				Name:                a.Name,
				StreamerName:        a.StreamerName,
				StreamerContact:     a.StreamerContact,
				AccessCode:          a.AccessCode,
				DouyinProductID:     a.DouyinProductID,
				OrderRewardType:     a.OrderRewardType,
				OrderRewardQuantity: a.OrderRewardQuantity,
				TicketPrice:         int64(a.TicketPrice),
				Status:              a.Status,
				CreatedAt:           a.CreatedAt.Format("2006-01-02 15:04:05"),
			}
			if !a.StartTime.IsZero() {
				item.StartTime = a.StartTime.Format("2006-01-02 15:04:05")
			}
			if !a.EndTime.IsZero() {
				item.EndTime = a.EndTime.Format("2006-01-02 15:04:05")
			}
			res.List[i] = item
		}

		ctx.Payload(res)
	}
}

// GetLivestreamActivity 获取直播间活动详情
// @Summary 获取直播间活动详情
// @Description 根据ID获取直播间活动详情
// @Tags 管理端.直播间
// @Accept json
// @Produce json
// @Param id path integer true "活动ID"
// @Success 200 {object} livestreamActivityResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/livestream/activities/{id} [get]
// @Security LoginVerifyToken
func (h *handler) GetLivestreamActivity() core.HandlerFunc {
	return func(ctx core.Context) {
		id, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
		if err != nil || id <= 0 {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "无效的活动ID"))
			return
		}

		activity, err := h.livestream.GetActivity(ctx.RequestContext(), id)
		if err != nil {
			ctx.AbortWithError(core.Error(http.StatusNotFound, code.ServerError, "活动不存在"))
			return
		}

		res := &livestreamActivityResponse{
			ID:                  activity.ID,
			Name:                activity.Name,
			StreamerName:        activity.StreamerName,
			StreamerContact:     activity.StreamerContact,
			AccessCode:          activity.AccessCode,
			DouyinProductID:     activity.DouyinProductID,
			OrderRewardType:     activity.OrderRewardType,
			OrderRewardQuantity: activity.OrderRewardQuantity,
			TicketPrice:         int64(activity.TicketPrice),
			Status:              activity.Status,
			CreatedAt:           activity.CreatedAt.Format("2006-01-02 15:04:05"),
		}
		if !activity.StartTime.IsZero() {
			res.StartTime = activity.StartTime.Format("2006-01-02 15:04:05")
		}
		if !activity.EndTime.IsZero() {
			res.EndTime = activity.EndTime.Format("2006-01-02 15:04:05")
		}

		ctx.Payload(res)
	}
}

// DeleteLivestreamActivity 删除直播间活动
// @Summary 删除直播间活动
// @Description 删除指定直播间活动
// @Tags 管理端.直播间
// @Accept json
// @Produce json
// @Param id path integer true "活动ID"
// @Success 200 {object} simpleMessageResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/livestream/activities/{id} [delete]
// @Security LoginVerifyToken
func (h *handler) DeleteLivestreamActivity() core.HandlerFunc {
	return func(ctx core.Context) {
		id, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
		if err != nil || id <= 0 {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "无效的活动ID"))
			return
		}

		if err := h.livestream.DeleteActivity(ctx.RequestContext(), id); err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
			return
		}

		ctx.Payload(&simpleMessageResponse{Message: "删除成功"})
	}
}

// ========== 直播间奖品管理 ==========

type createLivestreamPrizeRequest struct {
	Name      string `json:"name"`
	Image     string `json:"image"`
	Level     int32  `json:"level"`
	Weight    int32  `json:"weight"`
	Quantity  int32  `json:"quantity"`
	ProductID int64  `json:"product_id"`
	CostPrice int64  `json:"cost_price"`
}

type livestreamPrizeResponse struct {
	ID        int64  `json:"id"`
	Name      string `json:"name"`
	Image     string `json:"image"`
	Level     int32  `json:"level"`
	Weight    int32  `json:"weight"`
	Quantity  int32  `json:"quantity"`
	Remaining int64  `json:"remaining"`
	ProductID int64  `json:"product_id"`
	CostPrice int64  `json:"cost_price"`
	Sort      int32  `json:"sort"`
}

// CreateLivestreamPrizes 批量创建奖品
// @Summary 批量创建直播间奖品
// @Description 为指定活动批量创建奖品
// @Tags 管理端.直播间
// @Accept json
// @Produce json
// @Param activity_id path integer true "活动ID"
// @Param RequestBody body []createLivestreamPrizeRequest true "奖品列表"
// @Success 200 {object} simpleMessageResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/livestream/activities/{activity_id}/prizes [post]
// @Security LoginVerifyToken
func (h *handler) CreateLivestreamPrizes() core.HandlerFunc {
	return func(ctx core.Context) {
		activityID, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
		if err != nil || activityID <= 0 {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "无效的活动ID"))
			return
		}

		var req []createLivestreamPrizeRequest
		if err := ctx.ShouldBindJSON(&req); err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
			return
		}

		var inputs []livestream.CreatePrizeInput
		for _, p := range req {
			inputs = append(inputs, livestream.CreatePrizeInput{
				Name:      p.Name,
				Image:     p.Image,
				Weight:    p.Weight,
				Quantity:  p.Quantity,
				Level:     p.Level,
				ProductID: p.ProductID,
				CostPrice: p.CostPrice,
			})
		}

		if err := h.livestream.CreatePrizes(ctx.RequestContext(), activityID, inputs); err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
			return
		}

		ctx.Payload(&simpleMessageResponse{Message: "创建成功"})
	}
}

// ListLivestreamPrizes 获取活动奖品列表
// @Summary 获取直播间活动奖品列表
// @Description 获取指定活动的所有奖品
// @Tags 管理端.直播间
// @Accept json
// @Produce json
// @Param activity_id path integer true "活动ID"
// @Success 200 {object} []livestreamPrizeResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/livestream/activities/{activity_id}/prizes [get]
// @Security LoginVerifyToken
func (h *handler) ListLivestreamPrizes() core.HandlerFunc {
	return func(ctx core.Context) {
		activityID, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
		if err != nil || activityID <= 0 {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "无效的活动ID"))
			return
		}

		prizes, err := h.livestream.ListPrizes(ctx.RequestContext(), activityID)
		if err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
			return
		}

		res := make([]livestreamPrizeResponse, len(prizes))
		for i, p := range prizes {
			res[i] = livestreamPrizeResponse{
				ID:        p.ID,
				Name:      p.Name,
				Image:     p.Image,
				Weight:    p.Weight,
				Quantity:  p.Quantity,
				Remaining: int64(p.Remaining),
				Level:     p.Level,
				ProductID: p.ProductID,
				CostPrice: p.CostPrice,
				Sort:      p.Sort,
			}
		}

		ctx.Payload(res)
	}
}

// DeleteLivestreamPrize 删除奖品
// @Summary 删除直播间奖品
// @Description 删除指定奖品
// @Tags 管理端.直播间
// @Accept json
// @Produce json
// @Param prize_id path integer true "奖品ID"
// @Success 200 {object} simpleMessageResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/livestream/prizes/{prize_id} [delete]
// @Security LoginVerifyToken
func (h *handler) DeleteLivestreamPrize() core.HandlerFunc {
	return func(ctx core.Context) {
		prizeID, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
		if err != nil || prizeID <= 0 {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "无效的奖品ID"))
			return
		}

		if err := h.livestream.DeletePrize(ctx.RequestContext(), prizeID); err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
			return
		}

		ctx.Payload(&simpleMessageResponse{Message: "删除成功"})
	}
}

// ========== 直播间中奖记录 ==========

type livestreamDrawLogResponse struct {
	ID            int64  `json:"id"`
	ActivityID    int64  `json:"activity_id"`
	PrizeID       int64  `json:"prize_id"`
	PrizeName     string `json:"prize_name"`
	Level         int32  `json:"level"`
	DouyinOrderID int64  `json:"douyin_order_id"` // 关联ID
	ShopOrderID   string `json:"shop_order_id"`   // 店铺订单号
	LocalUserID   int64  `json:"local_user_id"`
	DouyinUserID  string `json:"douyin_user_id"`
	UserNickname  string `json:"user_nickname"` // 用户昵称
	SeedHash      string `json:"seed_hash"`
	CreatedAt     string `json:"created_at"`
}

type listLivestreamDrawLogsResponse struct {
	List     []livestreamDrawLogResponse `json:"list"`
	Total    int64                       `json:"total"`
	Page     int                         `json:"page"`
	PageSize int                         `json:"page_size"`
	Stats    *livestreamDrawLogsStats    `json:"stats,omitempty"`
}

type livestreamDrawLogsStats struct {
	UserCount   int64 `json:"user_count"`
	OrderCount  int64 `json:"order_count"`
	TotalRev    int64 `json:"total_revenue"` // 总流水
	TotalRefund int64 `json:"total_refund"`
	TotalCost   int64 `json:"total_cost"`
	NetProfit   int64 `json:"net_profit"`
}

type listLivestreamDrawLogsRequest struct {
	Page           int    `form:"page"`
	PageSize       int    `form:"page_size"`
	StartTime      string `form:"start_time"`
	EndTime        string `form:"end_time"`
	Keyword        string `form:"keyword"`
	ExcludeUserIDs string `form:"exclude_user_ids"` // 逗号分隔的 UserIDs
}

// ListLivestreamDrawLogs 获取中奖记录
// @Summary 获取直播间中奖记录
// @Description 获取指定活动的中奖记录，支持时间范围和关键词筛选
// @Tags 管理端.直播间
// @Accept json
// @Produce json
// @Param activity_id path integer true "活动ID"
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(20)
// @Param start_time query string false "开始时间 (YYYY-MM-DD)"
// @Param end_time query string false "结束时间 (YYYY-MM-DD)"
// @Param keyword query string false "搜索关键词 (昵称/订单号/奖品名称)"
// @Success 200 {object} listLivestreamDrawLogsResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/livestream/activities/{activity_id}/draw_logs [get]
// @Security LoginVerifyToken
func (h *handler) ListLivestreamDrawLogs() core.HandlerFunc {
	return func(ctx core.Context) {
		activityID, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
		if err != nil || activityID <= 0 {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "无效的活动ID"))
			return
		}

		req := new(listLivestreamDrawLogsRequest)
		_ = ctx.ShouldBindForm(req)

		page := req.Page
		pageSize := req.PageSize
		if page <= 0 {
			page = 1
		}
		if pageSize <= 0 {
			pageSize = 20
		}

		// 解析时间范围 (支持 YYYY-MM-DD HH:mm:ss 和 YYYY-MM-DD)
		var startTime, endTime *time.Time
		if req.StartTime != "" {
			// 尝试解析完整时间
			if t, err := time.ParseInLocation("2006-01-02 15:04:05", req.StartTime, time.Local); err == nil {
				startTime = &t
			} else if t, err := time.ParseInLocation("2006-01-02", req.StartTime, time.Local); err == nil {
				// 只有日期，默认 00:00:00
				startTime = &t
			}
		}
		if req.EndTime != "" {
			if t, err := time.ParseInLocation("2006-01-02 15:04:05", req.EndTime, time.Local); err == nil {
				endTime = &t
			} else if t, err := time.ParseInLocation("2006-01-02", req.EndTime, time.Local); err == nil {
				// 只有日期，设为当天结束 23:59:59.999
				end := t.Add(24*time.Hour - time.Nanosecond)
				endTime = &end
			}
		}

		// 解析排除用户ID
		var excludeUIDs []int64
		if req.ExcludeUserIDs != "" {
			parts := strings.Split(req.ExcludeUserIDs, ",")
			for _, p := range parts {
				p = strings.TrimSpace(p)
				if val, err := strconv.ParseInt(p, 10, 64); err == nil && val > 0 {
					excludeUIDs = append(excludeUIDs, val)
				}
			}
		}

		// 使用底层 GORM 直接查询以支持 keyword
		db := h.repo.GetDbR().Model(&model.LivestreamDrawLogs{}).Where("activity_id = ?", activityID)

		if startTime != nil {
			db = db.Where("created_at >= ?", startTime)
		}
		if endTime != nil {
			db = db.Where("created_at <= ?", endTime)
		}
		if req.Keyword != "" {
			keyword := "%" + req.Keyword + "%"
			db = db.Where("(user_nickname LIKE ? OR shop_order_id LIKE ? OR prize_name LIKE ?)", keyword, keyword, keyword)
		}
		if len(excludeUIDs) > 0 {
			db = db.Where("local_user_id NOT IN ?", excludeUIDs)
		}

		var total int64
		db.Count(&total)

		// 计算统计数据 (仅当有数据时)
		var stats *livestreamDrawLogsStats
		if total > 0 {
			stats = &livestreamDrawLogsStats{}
			// 1. 统计用户数
			// 使用 Session() 避免污染主 db 对象
			db.Session(&gorm.Session{}).Select("COUNT(DISTINCT douyin_user_id)").Scan(&stats.UserCount)

			// 2. 获取所有相关的 douyin_order_id 和 prize_id，用于在内存中聚合金额和成本
			// 注意：如果数据量极大，这里可能有性能隐患。但考虑到这是后台查询且通常带有筛选，暂且全量拉取 ID。
			// 优化：只查需要的字段
			type logMeta struct {
				DouyinOrderID int64
				PrizeID       int64
				ShopOrderID   string // 用于关联退款状态查 douyin_orders
			}
			var metas []logMeta
			// 使用不带分页的 db 克隆
			if err := db.Session(&gorm.Session{}).Select("douyin_order_id, prize_id, shop_order_id").Scan(&metas).Error; err == nil {
				orderIDs := make([]int64, 0, len(metas))
				distinctOrderIDs := make(map[int64]bool)
				prizeIDCount := make(map[int64]int64)

				for _, m := range metas {
					if !distinctOrderIDs[m.DouyinOrderID] {
						distinctOrderIDs[m.DouyinOrderID] = true
						orderIDs = append(orderIDs, m.DouyinOrderID)
					}
				}
				stats.OrderCount = int64(len(orderIDs))

				// 3. 查询订单金额和退款状态
				if len(orderIDs) > 0 {
					var orders []model.DouyinOrders
					// 分批查询防止 IN 子句过长? 暂时假设量级可控
					h.repo.GetDbR().Select("id, actual_pay_amount, order_status").
						Where("id IN ?", orderIDs).Find(&orders)

					orderRefundMap := make(map[int64]bool)

					for _, o := range orders {
						// 统计营收 (总流水)
						stats.TotalRev += int64(o.ActualPayAmount)

						if o.OrderStatus == 4 { // 已退款
							stats.TotalRefund += int64(o.ActualPayAmount)
							orderRefundMap[o.ID] = true
						}
					}

					// 4. 统计成本 (剔除退款订单)
					for _, m := range metas {
						if !orderRefundMap[m.DouyinOrderID] {
							prizeIDCount[m.PrizeID]++
						}
					}

					// 计算奖品成本 (逻辑参考 GetLivestreamStats，简化版)
					if len(prizeIDCount) > 0 {
						prizeIDs := make([]int64, 0, len(prizeIDCount))
						for pid := range prizeIDCount {
							prizeIDs = append(prizeIDs, pid)
						}

						var prizes []model.LivestreamPrizes
						h.repo.GetDbR().Where("id IN ?", prizeIDs).Find(&prizes)

						// 批量获取关联商品
						productIDs := make([]int64, 0)
						for _, p := range prizes {
							if p.CostPrice == 0 && p.ProductID > 0 {
								productIDs = append(productIDs, p.ProductID)
							}
						}
						productPriceMap := make(map[int64]int64)
						if len(productIDs) > 0 {
							var products []model.Products
							h.repo.GetDbR().Select("id, price").Where("id IN ?", productIDs).Find(&products)
							for _, prod := range products {
								productPriceMap[prod.ID] = prod.Price
							}
						}

						for _, p := range prizes {
							cost := p.CostPrice
							if cost == 0 && p.ProductID > 0 {
								cost = productPriceMap[p.ProductID]
							}
							count := prizeIDCount[p.ID]
							stats.TotalCost += cost * count
						}
					}
				}
			}
			stats.NetProfit = (stats.TotalRev - stats.TotalRefund) - stats.TotalCost
		}

		var logs []model.LivestreamDrawLogs
		// 重置 Select，确保查询 logs 时获取所有字段 (或者指定 default fields)
		// db 对象如果被污染，这里需要显式清除 Select。使用 Session 应该能避免。
		// 安全起见，这里也可以用 db.Session(&gorm.Session{})
		if err := db.Session(&gorm.Session{}).Order("id DESC").Offset((page - 1) * pageSize).Limit(pageSize).Find(&logs).Error; err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
			return
		}

		res := &listLivestreamDrawLogsResponse{
			List:     make([]livestreamDrawLogResponse, len(logs)),
			Total:    total,
			Page:     page,
			PageSize: pageSize,
			Stats:    stats,
		}

		for i, log := range logs {
			res.List[i] = livestreamDrawLogResponse{
				ID:            log.ID,
				ActivityID:    log.ActivityID,
				PrizeID:       log.PrizeID,
				PrizeName:     log.PrizeName,
				Level:         log.Level,
				DouyinOrderID: log.DouyinOrderID,
				ShopOrderID:   log.ShopOrderID,
				LocalUserID:   log.LocalUserID,
				DouyinUserID:  log.DouyinUserID,
				UserNickname:  log.UserNickname,
				SeedHash:      log.SeedHash,
				CreatedAt:     log.CreatedAt.Format("2006-01-02 15:04:05"),
			}
		}

		ctx.Payload(res)
	}
}

// ========== 直播间承诺管理 ==========

type livestreamCommitmentSummaryResponse struct {
	SeedVersion int32  `json:"seed_version"`
	Algo        string `json:"algo"`
	HasSeed     bool   `json:"has_seed"`
	LenSeed     int    `json:"len_seed_master"`
	LenHash     int    `json:"len_seed_hash"`
	SeedHashHex string `json:"seed_hash_hex"` // 种子哈希的十六进制表示（可公开复制）
}

// GenerateLivestreamCommitment 生成直播间活动承诺
// @Summary 生成直播间活动承诺
// @Description 为直播间活动生成可验证的承诺种子
// @Tags 管理端.直播间
// @Accept json
// @Produce json
// @Param id path integer true "活动ID"
// @Success 200 {object} map[string]int32
// @Failure 400 {object} code.Failure
// @Router /api/admin/livestream/activities/{id}/commitment/generate [post]
// @Security LoginVerifyToken
func (h *handler) GenerateLivestreamCommitment() core.HandlerFunc {
	return func(ctx core.Context) {
		id, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
		if err != nil || id <= 0 {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "无效的活动ID"))
			return
		}

		version, err := h.livestream.GenerateCommitment(ctx.RequestContext(), id)
		if err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
			return
		}

		ctx.Payload(map[string]int32{"seed_version": version})
	}
}

// GetLivestreamCommitmentSummary 获取直播间活动承诺摘要
// @Summary 获取直播间活动承诺摘要
// @Description 获取直播间活动的承诺状态信息
// @Tags 管理端.直播间
// @Accept json
// @Produce json
// @Param id path integer true "活动ID"
// @Success 200 {object} livestreamCommitmentSummaryResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/livestream/activities/{id}/commitment/summary [get]
// @Security LoginVerifyToken
func (h *handler) GetLivestreamCommitmentSummary() core.HandlerFunc {
	return func(ctx core.Context) {
		id, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
		if err != nil || id <= 0 {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "无效的活动ID"))
			return
		}

		summary, err := h.livestream.GetCommitmentSummary(ctx.RequestContext(), id)
		if err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
			return
		}

		ctx.Payload(&livestreamCommitmentSummaryResponse{
			SeedVersion: summary.SeedVersion,
			Algo:        summary.Algo,
			HasSeed:     summary.HasSeed,
			LenSeed:     summary.LenSeed,
			LenHash:     summary.LenHash,
			SeedHashHex: summary.SeedHashHex,
		})
	}
}
