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

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS;
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.oauth2.WxpayOauth2Params;
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.WxLiteOrderRQ;
import com.jeequan.jeepay.core.model.rqrs.payorder.payway.WxLiteOrderRS;
import com.jeequan.jeepay.core.utils.AmountUtil;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.thirdparty.channel.yspay.YspayPaymentService;
import com.jeequan.jeepay.thirdparty.channel.yspay.utils.YspayKit;
import com.jeequan.jeepay.thirdparty.service.ConfigContextQueryService;
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 2022/6/13 17:52
 */
@Slf4j
@Service("yspayPaymentByWxLiteService") //Service Name需保持全局唯一性
public class WxLite extends YspayPaymentService {

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

        WxLiteOrderRQ bizRQ = (WxLiteOrderRQ) rq;
        if(StringUtils.isEmpty(bizRQ.getOpenid())){
            throw new BizException("[openId]不可为空");
        }

        return null;
    }

    @Override
    public AbstractRS pay(UnifiedOrderRQ rq, PayOrder payOrder, MchAppConfigContext mchAppConfigContext) throws Exception {
        WxLiteOrderRS res = ApiResBuilder.buildSuccess(WxLiteOrderRS.class);
        ChannelRetMsg channelRetMsg = new ChannelRetMsg();
        res.setChannelRetMsg(channelRetMsg);
        try {
            // 设置请求参数
            WxLiteOrderRQ bizRQ = (WxLiteOrderRQ) rq;
            ConfigContextQueryService configContextQueryService = SpringBeansUtil.getBean(ConfigContextQueryService.class);
            WxpayOauth2Params oauth2Params = (WxpayOauth2Params) configContextQueryService.queryIsvOauth2Params(mchAppConfigContext.getMchApplyment().getIsvNo(), CS.IF_CODE.WXPAY);
            // 商户号
            // 设置请求参数
            JSONObject bizContent = new JSONObject();
            // 默认支付参数
            YspayKit.setPayParams(mchAppConfigContext, bizContent, "1", payOrder.getIfCode());

            // 商户订单号
            bizContent.put("out_trade_no", payOrder.getPayOrderId());
            // 订单交易日期
            bizContent.put("shopdate", DateUtil.format(payOrder.getCreatedAt(), DatePattern.PURE_DATE_PATTERN));
            // 订单备注
            bizContent.put("subject", payOrder.getSubject());
            // 金额 元
            bizContent.put("total_amount", AmountUtil.convertCent2Dollar(payOrder.getFindAmt()));
            // 用户在商户appid下的唯一标识
            bizContent.put("sub_openid", bizRQ.getChannelUserId());

            bizContent.put("is_minipg", "1");

            // 接口上传的appId
            if (StringUtils.isNotEmpty(bizRQ.getSubAppid())) {
                // 商户appId
                bizContent.put("appid", bizRQ.getSubAppid());
            }else {
                // 商户appId
                bizContent.put("appid", oauth2Params.getLiteAppId());
            }
            // 交易结束时间
            String expiredTime = DateUtil.formatBetween(DateUtil.between(payOrder.getCreatedAt(), payOrder.getExpiredTime(), DateUnit.MINUTE)).replace("毫秒", "");
            bizContent.put("timeout_express", expiredTime+"m");

            String result = YspayKit.payRequest("ysepay.online.weixin.pay", mchAppConfigContext, bizContent, getNotifyUrl(), payOrder.getIfCode());
            JSONObject resJson = JSONObject.parseObject(result);
            JSONObject response = resJson.getJSONObject("ysepay_online_weixin_pay_response");
            String code = response.getString("code");
            channelRetMsg.setChannelBizData(response);
            if (YspayKit.RES_CODE.equals(code)) {
                // 分账登记接口调用
                payOrderDivision(mchAppConfigContext, payOrder);

                String tradeStatus = response.getString("trade_status");
                if(YspayKit.WAIT_BUYER_PAY.equals(tradeStatus)){ // 交易中
                    // 转换为微信接收参数
                    String tradeNo = response.getString("trade_no");
                    JSONObject payInfo = response.getJSONObject("jsapi_pay_info");
                    channelRetMsg.setChannelOrderId(tradeNo);
                    res.setPayInfo(payInfo.toJSONString());
                    res.setPayData(payInfo.toJSONString());

                    ChannelJsapiMsg channelJsapiMsg = new ChannelJsapiMsg();
                    res.getChannelRetMsg().setJsapiMsg(channelJsapiMsg);
                    channelJsapiMsg.setAppId(payInfo.getString("appId"));
                    channelJsapiMsg.setNonceStr(payInfo.getString("nonceStr"));
                    channelJsapiMsg.setPayPackage(payInfo.getString("package"));
                    channelJsapiMsg.setPaySign(payInfo.getString("paySign"));
                    channelJsapiMsg.setTimeStamp(payInfo.getString("timeStamp"));

                    channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.WAITING);
                }else if (YspayKit.TRADE_FAILED.equals(tradeStatus)){  // 失败
                    channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
                    channelRetMsg.setChannelErrCode(response.getString("code"));
                    channelRetMsg.setChannelErrMsg(response.getString("sub_msg"));
                }
            }else {
                throw ChannelException.sysError(response.getString("sub_msg"));
            }
        }catch (BizException e) {
            channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.CONFIRM_FAIL);
            channelRetMsg.setChannelErrMsg(e.getMessage());
        }catch (Exception e) {
            throw ChannelException.sysError(e.getMessage());
        }
        return res;
    }

}
