package user

import (
	"bindbox-game/internal/repository/mysql/dao"
	"bindbox-game/internal/repository/mysql/model"
	"context"
	"fmt"
	"time"
)

// RecordOrderCouponUsage 记录订单使用的用户券与本次抵扣金额
func (s *service) RecordOrderCouponUsage(ctx context.Context, orderID int64, userCouponID int64, appliedAmount int64) error {
	if orderID <= 0 || userCouponID <= 0 || appliedAmount <= 0 {
		return nil
	}
	// 根治方案：使用唯一索引保证记录不重复
	return s.repo.GetDbW().Exec("INSERT IGNORE INTO order_coupons (order_id, user_coupon_id, applied_amount, created_at) VALUES (?,?,?,NOW(3))", orderID, userCouponID, appliedAmount).Error
}

// DeductCouponsForPaidOrder 支付成功后确认优惠券预扣
// 新逻辑：优惠券余额已在下单时预扣(status=4)，支付成功后只需确认状态
// 金额券：status 4 → 2（若余额为0）或保持 4（若还有余额，等后续订单继续使用）
// 满减/折扣券：status 4 → 2
func (s *service) DeductCouponsForPaidOrder(ctx context.Context, tx *dao.Query, userID int64, orderID int64, paidAt time.Time) error {
	type row struct {
		UserCouponID  int64
		AppliedAmount int64
		Status        int32
		UsedOrderID   int64
		DiscountType  int32
		BalanceAmount int64
	}
	var rows []row

	// 确定使用的数据库查询对象
	db := s.writeDB
	if tx != nil {
		db = tx
	}
	readDb := s.readDB
	if tx != nil {
		readDb = tx
	}

	// 1. 获取该订单关联的所有优惠券使用记录（包含当前余额）
	_ = readDb.OrderCoupons.WithContext(ctx).UnderlyingDB().Raw(`
		SELECT oc.user_coupon_id AS user_coupon_id, 
			   oc.applied_amount AS applied_amount, 
			   uc.status AS status, 
			   uc.used_order_id AS used_order_id, 
			   sc.discount_type AS discount_type,
			   uc.balance_amount AS balance_amount
		FROM order_coupons oc 
		JOIN user_coupons uc ON uc.id=oc.user_coupon_id 
		JOIN system_coupons sc ON sc.id=uc.coupon_id 
		WHERE oc.order_id=?
	`, orderID).Scan(&rows).Error

	for _, r := range rows {
		// 幂等校验：检查是否已有确认流水
		ledgerExists, _ := readDb.UserCouponLedger.WithContext(ctx).Where(
			readDb.UserCouponLedger.UserCouponID.Eq(r.UserCouponID),
			readDb.UserCouponLedger.OrderID.Eq(orderID),
			readDb.UserCouponLedger.Action.Eq("confirm"),
		).Count()
		if ledgerExists > 0 {
			continue
		}

		// 2. 确认预扣：将 status=4 (预扣中) 更新为最终状态
		if r.DiscountType == 1 { // 金额券
			// 下单时已扣减余额并更新状态，此处无需再次更新状态
			// 仅记录确认流水
			ledger := &model.UserCouponLedger{
				UserID:       userID,
				UserCouponID: r.UserCouponID,
				ChangeAmount: 0, // 确认操作不改变余额
				BalanceAfter: r.BalanceAmount,
				OrderID:      orderID,
				Action:       "confirm",
				CreatedAt:    time.Now(),
			}
			_ = db.UserCouponLedger.WithContext(ctx).Create(ledger)

		} else { // 满减/折扣券：一次性核销
			res := db.UserCoupons.WithContext(ctx).UnderlyingDB().Exec(`
				UPDATE user_coupons 
				SET status = 2
				WHERE id = ? AND status = 4
			`, r.UserCouponID)

			if res.Error != nil {
				return fmt.Errorf("failed to confirm coupon: %w", res.Error)
			}

			// 记录确认流水
			ledger := &model.UserCouponLedger{
				UserID:       userID,
				UserCouponID: r.UserCouponID,
				ChangeAmount: 0,
				BalanceAfter: 0,
				OrderID:      orderID,
				Action:       "confirm",
				CreatedAt:    time.Now(),
			}
			_ = db.UserCouponLedger.WithContext(ctx).Create(ledger)
		}
	}
	return nil
}
