package com.jeequan.jeepay.thirdparty.channel.sandpay.payway;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.entity.PayOrder;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.exception.ChannelException;
import com.jeequan.jeepay.core.model.context.MchAppConfigContext;
import com.jeequan.jeepay.core.model.params.sandpay.SandpayConfig;
import com.jeequan.jeepay.core.model.rqrs.AbstractRS;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelJsapiMsg;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.core.model.rqrs.payorder.UnifiedOrderRQ;
import com.jeequan.jeepay.core.model.rqrs.payorder.payway.AliJsapiOrderRQ;
import com.jeequan.jeepay.core.model.rqrs.payorder.payway.AliJsapiOrderRS;
import com.jeequan.jeepay.thirdparty.channel.sandpay.SandPayKit;
import com.jeequan.jeepay.thirdparty.channel.sandpay.SandpayPaymentService;
import com.jeequan.jeepay.thirdparty.util.ApiResBuilder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

/**
 * 杉德 支付宝 jsapi
 *
 * @author xiaoyu
 *
 * @date 2021/12/22 18:11
 */
@Slf4j
@Service("sandpayPaymentByAliJsapiService") //Service Name需保持全局唯一性
public class AliJsapi extends SandpayPaymentService {

    @Override
    public String preCheck(UnifiedOrderRQ rq, PayOrder payOrder) {

        AliJsapiOrderRQ bizRQ = (AliJsapiOrderRQ) rq;
        if(StringUtils.isEmpty(bizRQ.getBuyerUserId())){
            throw new BizException("[buyerUserId]不可为空");
        }
        return null;
    }

    @Override
    public AbstractRS pay(UnifiedOrderRQ rq, PayOrder payOrder, MchAppConfigContext mchAppConfigContext) throws Exception {
        String logPrefix = "【杉德支付宝("+payOrder.getWayCode()+")支付】";
        AliJsapiOrderRS res = ApiResBuilder.buildSuccess(AliJsapiOrderRS.class);
        ChannelRetMsg channelRetMsg = new ChannelRetMsg();
        res.setChannelRetMsg(channelRetMsg);
        try {

            // 设置请求参数
            JSONObject bodyJson = new JSONObject();
            AliJsapiOrderRQ bizRQ = (AliJsapiOrderRQ) rq;
            // 付款支付宝用户号
            JSONObject paramsJson = new JSONObject();
            paramsJson.put("userId", bizRQ.getBuyerUserId());
            bodyJson.put("payExtra", paramsJson.toJSONString());
            // 支付模式
            bodyJson.put("payMode", "sand_alipay");
            SandPayKit.setPayBody(bodyJson, payOrder, getNotifyUrl(), getReturnUrl());

            // 发送请求
            log.info("{}， 下单请求发送数据：{}", logPrefix, bodyJson);
            JSONObject resJson = SandPayKit.requestServer(bodyJson, SandpayConfig.ORDER_PAY, SandpayConfig.ORDERPAY, SandpayConfig.PRODUCTID_ALIPAY_JSAPI, mchAppConfigContext);
            log.info("{}， 下单请求返回数据：{}", logPrefix, resJson);
            //请求 & 响应成功， 判断业务逻辑
            JSONObject resHead = resJson.getJSONObject("head");
            String status = resHead.getString("respCode");
            if(SandpayConfig.SUCCESS.equals(status)){
                //付款信息
                JSONObject resBody = resJson.getJSONObject("body");
                String channelOrderNo = resBody.get("tradeNo").toString();
                channelRetMsg.setChannelOrderId(channelOrderNo);

                // 获取payInfo
                JSONObject credentialJosn = resBody.getJSONObject("credential");
                JSONObject payInfoJson = credentialJosn.getJSONObject("params").getJSONObject("payInfo");
                res.setAlipayTradeNo(payInfoJson.getString("trade_no"));
                res.setPayData(JSON.toJSONString(new ChannelJsapiMsg(payInfoJson.getString("trade_no"))));
                channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.WAITING);
            }else {
                channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
                channelRetMsg.setChannelErrCode(resHead.getString("respCode"));
                channelRetMsg.setChannelErrMsg(resHead.getString("respMsg"));
            }
        }catch (Exception e) {
            throw ChannelException.sysError(e.getMessage());
        }
        return res;
    }

}
