package bus

import (
	"context"
	"errors"
	"fmt"
	"pay/db"
	"pay/db/model"
	"pay/db/repo"
	"pay/log"
	"pay/pay"
	"pay/utils"
	"strconv"

	"github.com/go-pay/gopay"
	"github.com/go-pay/gopay/alipay"
	cpay "infish.cn/comm/pay"
)

type MutliAliPay struct {
}

func NewMutliAliPay() PayInf {
	return &MutliAliPay{}
}

func (a *MutliAliPay) Pay(ctx context.Context, orderMsg *cpay.OrderMsg) (interface{}, error) {
	fmt.Println("====================二维码获取=====================")

	// 初始化 BodyMap
	orderId := orderMsg.Project + "_" + orderMsg.Id.Hex()
	bm := make(gopay.BodyMap)
	amount, err := strconv.ParseFloat(fmt.Sprintf("%.2f", *orderMsg.Amount), 64)
	if err != nil {
		return nil, errors.New("价格parse错误！")
	}

	if err != nil {
		return nil, err
	}

	seller := &model.MultiSeller{}
	fmt.Println("----------------------------alipay-pay-orderMsg------------------------------")
	fmt.Printf("%#v\n", orderMsg)
	// 设置默认收款
	if orderMsg.SellerKey == "" {
		orderMsg.SellerKey = "sku3d"
	}

	fmt.Println("----------------------------alipay-pay-sellerkey------------------------------")
	println(orderMsg.SellerKey)
	ok, err := repo.RepoSeachDoc(&repo.RepoSession{Ctx: ctx, Client: db.GMongoDb}, &repo.DocSearchOptions{
		CollectName: "multi-sellers", //商家信息
		Query:       repo.Map{"key": orderMsg.SellerKey},
	}, seller)
	fmt.Println("----------------------------aplipay-multi-sellers------------------------------")
	fmt.Printf("%#v\n", seller)

	if err != nil {
		return nil, err
	}
	if !ok {
		return nil, fmt.Errorf("当前商户 %s 支付模块没接入", orderMsg.SellerKey)
	}

	bm.Set("subject", orderMsg.Name).
		Set("scene", "bar_code").
		//Set("auth_code", util.RandomNumber(10))
		Set("out_trade_no", orderId).
		Set("total_amount", amount).
		// 口碑门店，如果是第三方授权这里填写app_auth_token对应账号
		// Set("seller_id", "2088441503441284"). // sku3d
		Set("seller_id", seller.AlipaySellerId). // um
		Set("timeout_express", "10m")
	// 第三方授权方式 公共参数，不在此处设置
	// Set("app_auth_token", "202209BB3b97baabe741463ea9d8068222ebfX05")

	pay.MultiAlipayClient.SetAppAuthToken(seller.AlipayAuthToken)
	res, err := pay.MultiAlipayClient.TradePrecreate(ctx, bm)

	if err != nil {
		if bizErr, ok := alipay.IsBizError(err); ok {
			log.Errorf("%+v", bizErr)
			// do something
			return "", errors.New(bizErr.SubMsg)
		}
		log.Errorf("阿里支付信息%v,err:%v\n", bm, err)
		return "", err
	}
	if res.Response.Msg != "Success" {
		return "", errors.New(res.Response.ErrorResponse.SubMsg)
	}
	fmt.Printf("%#v\n", res.Response)
	qrCode := res.Response.QrCode

	return qrCode, nil
	// {"errorNo":200,"result":"https://qr.alipay.com/bax07889ilukkegehj3e2505","errorDesc":""}

}

func (a *MutliAliPay) Close(ctx context.Context, orderMsg *cpay.OrderMsg) (bool, error) {

	orderId := orderMsg.Project + "_" + orderMsg.Id.Hex()
	bm := make(gopay.BodyMap)
	bm.Set("out_trade_no", orderId)
	tradeClose, err := pay.SingleAlipayClient.TradeClose(ctx, bm)
	if err != nil {
		return false, err
	}
	if tradeClose.Response.Code != "10000" {
		return false, errors.New(tradeClose.Response.Msg)
	}
	return true, nil
}

// https://opendocs.alipay.com/apis/api_1/alipay.trade.refund
func (m *MutliAliPay) ReFundPay(ctx context.Context, refund *model.ReFund) (interface{}, error) {
	bm := make(gopay.BodyMap)
	// 整数转换为小数
	parseRefund, err := utils.IntToDecimal(*refund.Refund)
	if err != nil {
		return nil, err
	}
	bm.Set("out_trade_no", refund.TradeNo).
		Set("refund_amount", parseRefund).
		Set("refund_reason", refund.Reason).
		Set("out_request_no", refund.Id.Hex())
	res, err := pay.MultiAlipayClient.TradeRefund(ctx, bm)
	if err != nil {
		if bizErr, ok := alipay.IsBizError(err); ok {
			log.Errorf("%+v", bizErr)
			// do something
			return false, err
		}
		return false, err
	}
	if res.Response.Msg != "Success" {
		return false, errors.New(res.Response.SubMsg)
	}

	return true, nil

}

// 文档地址：https://opendocs.alipay.com/apis/api_1/alipay.trade.fastpay.refund.query
func (m *MutliAliPay) ReFundQuery(ctx context.Context, refund *model.ReFund) (interface{}, error) {
	bm := make(gopay.BodyMap)
	bm.Set("out_trade_no", refund.TradeNo).
		Set("out_request_no", refund.Id.Hex())
	// Set("query_options", []string{})

	res, err := pay.MultiAlipayClient.TradeFastPayRefundQuery(ctx, bm)
	if err != nil {
		if bizErr, ok := alipay.IsBizError(err); ok {
			log.Errorf("%+v", bizErr)
			// do something
			return false, err
		}
		return false, err
	}
	if res.Response.Msg != "Success" {
		return false, errors.New(res.Response.SubMsg)
	}

	return res.Response.RefundStatus, nil
	// return res.Response, nil
}
