package service

import (
	"context"
	"crypto/rand"
	"tydata-server/app/main/api/internal/config"
	"tydata-server/app/main/model"
	"tydata-server/pkg/lzkit/lzUtils"
	"encoding/hex"
	"fmt"
	"net/http"
	"strconv"
	"sync/atomic"
	"time"

	"github.com/smartwalle/alipay/v3"
)

type AliPayService struct {
	config       config.AlipayConfig
	AlipayClient *alipay.Client
}

// NewAliPayService 是一个构造函数，用于初始化 AliPayService
func NewAliPayService(c config.Config) *AliPayService {
	client, err := alipay.New(c.Alipay.AppID, c.Alipay.PrivateKey, c.Alipay.IsProduction)
	if err != nil {
		panic(fmt.Sprintf("创建支付宝客户端失败: %v", err))
	}
	// 加载支付宝公钥
	err = client.LoadAliPayPublicKey(c.Alipay.AlipayPublicKey)
	if err != nil {
		panic(fmt.Sprintf("加载支付宝公钥失败: %v", err))
	}

	// 加载证书
	if err = client.LoadAppCertPublicKeyFromFile(c.Alipay.AppCertPath); err != nil {
		panic(fmt.Sprintf("加载应用公钥证书失败: %v", err))
	}
	if err = client.LoadAlipayCertPublicKeyFromFile(c.Alipay.AlipayCertPath); err != nil {
		panic(fmt.Sprintf("加载支付宝公钥证书失败: %v", err))
	}
	if err = client.LoadAliPayRootCertFromFile(c.Alipay.AlipayRootCertPath); err != nil {
		panic(fmt.Sprintf("加载根证书失败: %v", err))
	}

	return &AliPayService{
		config:       c.Alipay,
		AlipayClient: client,
	}
}

func (a *AliPayService) CreateAlipayAppOrder(amount float64, subject string, outTradeNo string) (string, error) {
	client := a.AlipayClient
	totalAmount := lzUtils.ToAlipayAmount(amount)
	// 构造移动支付请求
	p := alipay.TradeAppPay{
		Trade: alipay.Trade{
			Subject:     subject,
			OutTradeNo:  outTradeNo,
			TotalAmount: totalAmount,
			ProductCode: "QUICK_MSECURITY_PAY", // 移动端支付专用代码
			NotifyURL:   a.config.NotifyUrl,    // 异步回调通知地址
		},
	}

	// 获取APP支付字符串，这里会签名
	payStr, err := client.TradeAppPay(p)
	if err != nil {
		return "", fmt.Errorf("创建支付宝订单失败: %v", err)
	}

	return payStr, nil
}

// CreateAlipayH5Order 创建支付宝H5支付订单
func (a *AliPayService) CreateAlipayH5Order(amount float64, subject string, outTradeNo string) (string, error) {
	client := a.AlipayClient
	totalAmount := lzUtils.ToAlipayAmount(amount)
	// 构造H5支付请求
	p := alipay.TradeWapPay{
		Trade: alipay.Trade{
			Subject:     subject,
			OutTradeNo:  outTradeNo,
			TotalAmount: totalAmount,
			ProductCode: "QUICK_WAP_PAY",    // H5支付专用产品码
			NotifyURL:   a.config.NotifyUrl, // 异步回调通知地址
			ReturnURL:   a.config.ReturnURL,
		},
	}
	// 获取H5支付请求字符串，这里会签名
	payUrl, err := client.TradeWapPay(p)
	if err != nil {
		return "", fmt.Errorf("创建支付宝H5订单失败: %v", err)
	}

	return payUrl.String(), nil
}

// CreateAlipayOrder 根据平台类型创建支付宝支付订单
func (a *AliPayService) CreateAlipayOrder(ctx context.Context, amount float64, subject string, outTradeNo string) (string, error) {
	// 根据 ctx 中的 platform 判断平台
	platform, platformOk := ctx.Value("platform").(string)
	if !platformOk {
		return "", fmt.Errorf("无的支付平台: %s", platform)
	}
	switch platform {
	case model.PlatformApp:
		// 调用App支付的创建方法
		return a.CreateAlipayAppOrder(amount, subject, outTradeNo)
	case model.PlatformH5:
		// 调用H5支付的创建方法，并传入 returnUrl
		return a.CreateAlipayH5Order(amount, subject, outTradeNo)
	default:
		return "", fmt.Errorf("不支持的支付平台: %s", platform)
	}
}

// AliRefund 发起支付宝退款
func (a *AliPayService) AliRefund(ctx context.Context, outTradeNo string, refundAmount float64) (*alipay.TradeRefundRsp, error) {
	refund := alipay.TradeRefund{
		OutTradeNo:   outTradeNo,
		RefundAmount: lzUtils.ToAlipayAmount(refundAmount),
		OutRequestNo: fmt.Sprintf("refund-%s", outTradeNo),
	}

	// 发起退款请求
	refundResp, err := a.AlipayClient.TradeRefund(ctx, refund)
	if err != nil {
		return nil, fmt.Errorf("支付宝退款请求错误：%v", err)
	}
	return refundResp, nil
}

// HandleAliPaymentNotification 支付宝支付回调
func (a *AliPayService) HandleAliPaymentNotification(r *http.Request) (*alipay.Notification, error) {
	// 解析表单
	err := r.ParseForm()
	if err != nil {
		return nil, fmt.Errorf("解析请求表单失败：%v", err)
	}
	// 解析并验证通知，DecodeNotification 会自动验证签名
	notification, err := a.AlipayClient.DecodeNotification(r.Form)
	if err != nil {
		return nil, fmt.Errorf("验证签名失败: %v", err)
	}
	return notification, nil
}
func (a *AliPayService) QueryOrderStatus(ctx context.Context, outTradeNo string) (*alipay.TradeQueryRsp, error) {
	queryRequest := alipay.TradeQuery{
		OutTradeNo: outTradeNo,
	}

	// 发起查询请求
	resp, err := a.AlipayClient.TradeQuery(ctx, queryRequest)
	if err != nil {
		return nil, fmt.Errorf("查询支付宝订单失败: %v", err)
	}

	// 返回交易状态
	if resp.IsSuccess() {
		return resp, nil
	}

	return nil, fmt.Errorf("查询支付宝订单失败: %v", resp.SubMsg)
}

// 添加全局原子计数器
var alipayOrderCounter uint32 = 0

// GenerateOutTradeNo 生成唯一订单号的函数 - 优化版本
func (a *AliPayService) GenerateOutTradeNo() string {

	// 获取当前时间戳（毫秒级）
	timestamp := time.Now().UnixMilli()
	timeStr := strconv.FormatInt(timestamp, 10)

	// 原子递增计数器
	counter := atomic.AddUint32(&alipayOrderCounter, 1)

	// 生成4字节真随机数
	randomBytes := make([]byte, 4)
	_, err := rand.Read(randomBytes)
	if err != nil {
		// 如果随机数生成失败，回退到使用时间纳秒数据
		randomBytes = []byte(strconv.FormatInt(time.Now().UnixNano()%1000000, 16))
	}
	randomHex := hex.EncodeToString(randomBytes)

	// 组合所有部分: 前缀 + 时间戳 + 计数器 + 随机数
	orderNo := fmt.Sprintf("%s%06x%s", timeStr[:10], counter%0xFFFFFF, randomHex[:6])

	// 确保长度不超过32字符（大多数支付平台的限制）
	if len(orderNo) > 32 {
		orderNo = orderNo[:32]
	}

	return orderNo
}

// AliTransfer 支付宝单笔转账到支付宝账户（提现功能）
func (a *AliPayService) AliTransfer(
	ctx context.Context,
	payeeAccount string, // 收款方支付宝账户
	payeeName string, // 收款方姓名
	amount float64, // 转账金额
	remark string, // 转账备注
	outBizNo string, // 商户转账唯一订单号（可使用GenerateOutTradeNo生成）
) (*alipay.FundTransUniTransferRsp, error) {
	// 参数校验
	if payeeAccount == "" {
		return nil, fmt.Errorf("收款账户不能为空")
	}
	if amount <= 0 {
		return nil, fmt.Errorf("转账金额必须大于0")
	}

	// 构造转账请求
	req := alipay.FundTransUniTransfer{
		OutBizNo:    outBizNo,
		TransAmount: lzUtils.ToAlipayAmount(amount), // 金额格式转换
		ProductCode: "TRANS_ACCOUNT_NO_PWD",         // 单笔无密转账到支付宝账户
		BizScene:    "DIRECT_TRANSFER",              // 单笔转账
		OrderTitle:  "账户提现",                         // 转账标题
		Remark:      remark,
		PayeeInfo: &alipay.PayeeInfo{
			Identity:     payeeAccount,
			IdentityType: "ALIPAY_LOGON_ID", // 根据账户类型选择：
			Name:         payeeName,
			// ALIPAY_USER_ID/ALIPAY_LOGON_ID
		},
	}

	// 执行转账请求
	transferRsp, err := a.AlipayClient.FundTransUniTransfer(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("支付宝转账请求失败: %v", err)
	}

	return transferRsp, nil
}
func (a *AliPayService) QueryTransferStatus(
	ctx context.Context,
	outBizNo string,
) (*alipay.FundTransOrderQueryRsp, error) {
	req := alipay.FundTransOrderQuery{
		OutBizNo: outBizNo,
	}
	response, err := a.AlipayClient.FundTransOrderQuery(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("支付宝接口调用失败: %v", err)
	}
	// 处理响应
	if response.Code.IsFailure() {
		return nil, fmt.Errorf("支付宝返回错误: %s-%s", response.Code, response.Msg)
	}
	return response, nil
}
