package model

import (
	"errors"
	"fmt"

	"github.com/QuantumNous/new-api/common"
	"github.com/QuantumNous/new-api/logger"

	"github.com/shopspring/decimal"
	"gorm.io/gorm"
)

// RechargeWechat 微信支付充值完成（由回调触发）
func RechargeWechat(tradeNo string) error {
	return rechargeByQRCodePayment(tradeNo, "微信支付")
}

// RechargeAlipay 支付宝充值完成（由回调触发）
func RechargeAlipay(tradeNo string) error {
	return rechargeByQRCodePayment(tradeNo, "支付宝")
}

// rechargeByQRCodePayment 扫码支付充值完成（微信/支付宝通用）
// 使用事务+行锁保证幂等
func rechargeByQRCodePayment(tradeNo string, paymentMethod string) error {
	if tradeNo == "" {
		return errors.New("未提供支付单号")
	}

	var quotaToAdd int64
	var payMoney float64
	var userId int

	refCol := "`trade_no`"
	if common.UsingPostgreSQL {
		refCol = `"trade_no"`
	}

	err := DB.Transaction(func(tx *gorm.DB) error {
		topUp := &TopUp{}
		if err := tx.Set("gorm:query_option", "FOR UPDATE").Where(refCol+" = ?", tradeNo).First(topUp).Error; err != nil {
			return errors.New("充值订单不存在")
		}

		if topUp.Status == common.TopUpStatusSuccess {
			return nil
		}

		if topUp.Status != common.TopUpStatusPending {
			return errors.New("充值订单状态错误")
		}

		topUp.CompleteTime = common.GetTimestamp()
		topUp.Status = common.TopUpStatusSuccess
		if err := tx.Save(topUp).Error; err != nil {
			return err
		}

		dMoney := decimal.NewFromFloat(topUp.Money)
		dQuotaPerUnit := decimal.NewFromFloat(common.QuotaPerUnit)
		quotaToAdd = dMoney.Mul(dQuotaPerUnit).IntPart()

		if quotaToAdd <= 0 {
			return errors.New("无效的充值额度")
		}

		if err := tx.Model(&User{}).Where("id = ?", topUp.UserId).Update("quota", gorm.Expr("quota + ?", quotaToAdd)).Error; err != nil {
			return err
		}

		userId = topUp.UserId
		payMoney = topUp.Money
		return nil
	})

	if err != nil {
		return err
	}

	if quotaToAdd > 0 {
		RecordLog(userId, LogTypeTopup, fmt.Sprintf("使用%s充值成功，充值金额: %v，支付金额：%.2f", paymentMethod, logger.FormatQuota(int(quotaToAdd)), payMoney))
	}

	return nil
}
