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 INTO order_coupons (order_id, user_coupon_id, applied_amount, created_at) VALUES (?,?,?,NOW(3))", orderID, userCouponID, appliedAmount).Error
}

// DeductCouponsForPaidOrder 支付成功后扣减金额券余额或核销一次性券
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
	}
	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 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 {
		// 幂等校验：已核销且绑定本订单，则跳过
		if r.Status == 2 && r.UsedOrderID == orderID {
			continue
		}

		var currentBal int64
		var ucUserID int64
		uc, err := readDb.UserCoupons.WithContext(ctx).Where(readDb.UserCoupons.ID.Eq(r.UserCouponID)).First()
		if err != nil || uc == nil {
			continue // 或记录日志
		}
		currentBal = uc.BalanceAmount
		ucUserID = uc.UserID

		if r.DiscountType == 1 { // 金额券：按量扣减
			nb := currentBal - r.AppliedAmount
			if nb < 0 {
				nb = 0
			}

			upd := map[string]any{
				"balance_amount": nb,
				"used_order_id":  orderID,
				"used_at":        paidAt,
			}
			if nb == 0 {
				upd["status"] = 2 // 余额扣完，标记为已完成
			}

			_, err = db.UserCoupons.WithContext(ctx).Where(db.UserCoupons.ID.Eq(r.UserCouponID)).Updates(upd)
			if err != nil {
				return fmt.Errorf("failed to update user coupon balance: %w", err)
			}

			// 记录账变流水
			ledger := &model.UserCouponLedger{
				UserID:       ucUserID,
				UserCouponID: r.UserCouponID,
				ChangeAmount: -r.AppliedAmount,
				BalanceAfter: nb,
				OrderID:      orderID,
				Action:       "apply",
				CreatedAt:    time.Now(),
			}
			_ = db.UserCouponLedger.WithContext(ctx).Create(ledger)

		} else { // 满减/折扣券：一次性核销
			_, err = db.UserCoupons.WithContext(ctx).Where(db.UserCoupons.ID.Eq(r.UserCouponID)).Updates(map[string]any{
				"status":        2,
				"used_order_id": orderID,
				"used_at":       paidAt,
			})
			if err != nil {
				return fmt.Errorf("failed to verify user coupon: %w", err)
			}

			// 记录账变流水
			ledger := &model.UserCouponLedger{
				UserID:       ucUserID,
				UserCouponID: r.UserCouponID,
				ChangeAmount: -r.AppliedAmount,
				BalanceAfter: 0,
				OrderID:      orderID,
				Action:       "apply",
				CreatedAt:    time.Now(),
			}
			_ = db.UserCouponLedger.WithContext(ctx).Create(ledger)
		}
	}
	return nil
}
