package api

import (
	"encoding/json"
	logger "eta/eta_mini_ht_api/common/component/log"
	"eta/eta_mini_ht_api/common/exception"
	"io"
	"sync"
)

const (
	queryPaymentUrl  = "/paygateway/query.json"
	createPaymentUrl = "/paygateway/createpay.json"
)

var (
	paymentFacadeOnce sync.Once
	paymentFacade     *HTPaymentApi
)

type HTPaymentApi struct {
	*HTApi
}

func GetPaymentInstance() *HTPaymentApi {
	paymentFacadeOnce.Do(func() {
		paymentFacade = &HTPaymentApi{
			GetInstance(),
		}
	})
	return paymentFacade
}

type PaymentOrderRequest struct {
	AppId           string `json:"appId"`           // 必须 业务系统编号
	Sign            string `json:"sign"`            // 必须 加密字符串
	ChannelTypeCode string `json:"channelTypeCode"` // 必须 支付渠道编码(6:华为支付,7:微信小程序)
	Subject         string `json:"subject"`         // 必须 商品标题
	Body            string `json:"body"`            // 必须 商品描述
	TotalFee        string `json:"totalFee"`        // 必须 订单价格
	BillNo          string `json:"billNo"`          // 必须 商户系统内部的订单号
	BillTypeCode    string `json:"billTypeCode"`    // 非必须 业务类型code
	BillType        string `json:"billType"`        // 非必须 业务类型
	TimeoutExpress  string `json:"timeoutExpress"`  // 必须 订单失效时间(秒)
	Optional        string `json:"optional"`        // 必须 扩展类参数
	Mobile          string `json:"mobile"`          // 非必须 手机号
	IapProductId    string `json:"iapProductId"`    // 非必须 苹果内购产品ID
}
type PaymentOrderResponse struct {
	Success    bool   `json:"success"`    // 必须 接口调用结果
	ResultCode string `json:"resultCode"` // 必须 结果码
	ResultDesc string `json:"resultDesc"` // 必须 结果描述
	ResultView string `json:"resultView"` // 必须 错误结果显示
	PrePayStr  string `json:"prePayStr"`  // 必须 预支付订单信息
}

func (f *HTPaymentApi) CreatePaymentOrder(req PaymentOrderRequest) (tradeNo string, err error) {
	url := f.htConfig.GetPaymentApiUrl() + createPaymentUrl
	req.AppId = f.htConfig.GetPaymentAppId()
	req.Sign = f.htConfig.GetPaymentSign()
	resp, err := f.client.Post(url, req)
	if err != nil {
		logger.Error("调用支付创单接口失败:[%v]", err)
		return
	}
	defer func(Body io.ReadCloser) {
		closeErr := Body.Close()
		if closeErr != nil {
			logger.Error("关闭Response失败:%v", closeErr)
		}
	}(resp.Body)
	body, _ := io.ReadAll(resp.Body)
	var paymentOrderResponse PaymentOrderResponse
	err = json.Unmarshal(body, &paymentOrderResponse)
	if err != nil {
		logger.Warn("[支付接口调用]解析支付创建订单接口应答失败:%v", err)
		err = exception.New(exception.CreatePaymentOrderFailed)
		return
	}
	if !paymentOrderResponse.Success {
		logger.Warn("[支付接口调用] 创建订单失败:[code:%v, msg:%v]", paymentOrderResponse.ResultCode, paymentOrderResponse.ResultDesc)
		err = exception.NewWithException(exception.CreatePaymentOrderFailed, paymentOrderResponse.ResultView)
		return
	}
	logger.Info("[支付接口调用] 创建订单成功:[%v]", paymentOrderResponse.PrePayStr)
	tradeNo = paymentOrderResponse.PrePayStr
	return
}