package app

import (
	"bindbox-game/internal/code"
	"bindbox-game/internal/pkg/core"
	"bindbox-game/internal/pkg/validation"
	"bindbox-game/internal/repository/mysql/model"
	"net/http"
	"strconv"
	"strings"
)

type listCouponUsageRequest struct {
	Page     int `form:"page"`
	PageSize int `form:"page_size"`
}

// 优惠券详情
type couponDetail struct {
	ID         int64  `json:"id"`
	Name       string `json:"name"`
	Amount     int64  `json:"amount"`      // 原始面值
	Remaining  int64  `json:"remaining"`   // 剩余额度
	UsedAmount int64  `json:"used_amount"` // 累计已使用金额
	UseCount   int64  `json:"use_count"`   // 使用次数
	ValidStart string `json:"valid_start"`
	ValidEnd   string `json:"valid_end"`
	Status     int32  `json:"status"`
}

// 使用记录项
type couponUsageItem struct {
	ID           int64  `json:"id"`
	OrderNo      string `json:"order_no"`      // 订单号
	ActivityName string `json:"activity_name"` // 活动名称
	Amount       int64  `json:"amount"`        // 本次使用金额（正数）
	CreatedAt    string `json:"created_at"`
}

type listCouponUsageResponse struct {
	Coupon   *couponDetail     `json:"coupon"`
	Records  []couponUsageItem `json:"records"`
	Total    int64             `json:"total"`
	Page     int               `json:"page"`
	PageSize int               `json:"page_size"`
}

// ListUserCouponUsage 获取单张优惠券使用记录
// @Summary 获取单张优惠券使用记录
// @Description 获取指定优惠券的使用记录，包含优惠券详情、订单号、活动名称
// @Tags APP端.用户
// @Accept json
// @Produce json
// @Param user_id path integer true "用户ID"
// @Param user_coupon_id path integer true "用户优惠券ID"
// @Security LoginVerifyToken
// @Param page query int false "页码，默认1"
// @Param page_size query int false "每页数量，默认20"
// @Success 200 {object} listCouponUsageResponse
// @Failure 400 {object} code.Failure
// @Router /api/app/users/{user_id}/coupons/{user_coupon_id}/usage [get]
func (h *handler) ListUserCouponUsage() core.HandlerFunc {
	return func(ctx core.Context) {
		req := new(listCouponUsageRequest)
		rsp := new(listCouponUsageResponse)
		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
		}
		if req.PageSize > 100 {
			req.PageSize = 100
		}

		userID := int64(ctx.SessionUserInfo().Id)
		ucid, err := strconv.ParseInt(ctx.Param("user_coupon_id"), 10, 64)
		if err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递持券ID"))
			return
		}

		// 获取优惠券信息
		uc, err := h.readDB.UserCoupons.WithContext(ctx.RequestContext()).ReadDB().
			Where(h.readDB.UserCoupons.ID.Eq(ucid), h.readDB.UserCoupons.UserID.Eq(userID)).First()
		if err != nil || uc == nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, 10010, "优惠券不存在"))
			return
		}

		// 获取优惠券模板信息
		sc, _ := h.readDB.SystemCoupons.WithContext(ctx.RequestContext()).ReadDB().
			Where(h.readDB.SystemCoupons.ID.Eq(uc.CouponID)).First()

		// 统计使用次数和累计使用金额
		var useCount int64
		var usedAmount int64
		_ = h.repo.GetDbR().Raw("SELECT COUNT(*), COALESCE(SUM(ABS(change_amount)), 0) FROM user_coupon_ledger WHERE user_coupon_id = ? AND change_amount < 0", ucid).Row().Scan(&useCount, &usedAmount)

		// 构建优惠券详情
		couponName := ""
		originalAmount := int64(0)
		if sc != nil {
			couponName = sc.Name
			originalAmount = sc.DiscountValue
		}
		rsp.Coupon = &couponDetail{
			ID:         uc.ID,
			Name:       couponName,
			Amount:     originalAmount,
			Remaining:  uc.BalanceAmount,
			UsedAmount: usedAmount,
			UseCount:   useCount,
			ValidStart: uc.ValidStart.Format("2006-01-02 15:04:05"),
			ValidEnd: func() string {
				if !uc.ValidEnd.IsZero() {
					return uc.ValidEnd.Format("2006-01-02 15:04:05")
				}
				return ""
			}(),
			Status: uc.Status,
		}

		// 获取使用记录
		var total int64
		db := h.repo.GetDbR().Model(&model.UserCouponLedger{}).Where("user_id = ? AND user_coupon_id = ? AND change_amount < 0", userID, ucid)
		_ = db.Count(&total).Error

		var list []model.UserCouponLedger
		_ = db.Order("id DESC").Offset((req.Page - 1) * req.PageSize).Limit(req.PageSize).Find(&list).Error

		// 收集订单ID批量查询
		orderIDs := make([]int64, 0, len(list))
		for _, v := range list {
			if v.OrderID > 0 {
				orderIDs = append(orderIDs, v.OrderID)
			}
		}

		// 批量查询订单信息
		orderMap := make(map[int64]*model.Orders)
		if len(orderIDs) > 0 {
			orders, _ := h.readDB.Orders.WithContext(ctx.RequestContext()).ReadDB().
				Where(h.readDB.Orders.ID.In(orderIDs...)).Find()
			for _, o := range orders {
				orderMap[o.ID] = o
			}
		}

		records := make([]couponUsageItem, len(list))
		for i, v := range list {
			orderNo := ""
			activityName := ""

			if order, ok := orderMap[v.OrderID]; ok && order != nil {
				orderNo = order.OrderNo
				// 从 remark 解析活动信息
				if order.SourceType == 2 && strings.Contains(order.Remark, "lottery:activity:") {
					// 尝试获取活动名称
					remark := order.Remark
					var activityID int64
					for _, seg := range strings.Split(remark, "|") {
						if strings.HasPrefix(seg, "lottery:activity:") {
							idStr := strings.TrimPrefix(seg, "lottery:activity:")
							if idx := strings.Index(idStr, ":"); idx > 0 {
								idStr = idStr[:idx]
							}
							activityID, _ = strconv.ParseInt(idStr, 10, 64)
							break
						}
					}
					if activityID > 0 {
						if act, _ := h.readDB.Activities.WithContext(ctx.RequestContext()).ReadDB().
							Where(h.readDB.Activities.ID.Eq(activityID)).First(); act != nil {
							activityName = act.Name
						}
					}
				}
			}

			records[i] = couponUsageItem{
				ID:           v.ID,
				OrderNo:      orderNo,
				ActivityName: activityName,
				Amount:       -v.ChangeAmount, // 转为正数
				CreatedAt:    v.CreatedAt.Format("2006-01-02 15:04:05"),
			}
		}

		rsp.Records = records
		rsp.Total = total
		rsp.Page = req.Page
		rsp.PageSize = req.PageSize
		ctx.Payload(rsp)
	}
}
