package com.jeequan.jeepay.pay.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.components.mq.model.PayOrderMchNotifyMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.converter.MchInfoConverter;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.interfaces.IConfigContextQueryService;
import com.jeequan.jeepay.core.model.openapi.AccessError;
import com.jeequan.jeepay.core.model.openapi.AccessReq;
import com.jeequan.jeepay.core.model.openapi.AccessResp;
import com.jeequan.jeepay.core.model.openapi.biz.PayResultResp;
import com.jeequan.jeepay.core.model.openapi.biz.RefundResultResp;
import com.jeequan.jeepay.core.model.rqrs.payorder.QueryPayOrderRS;
import com.jeequan.jeepay.core.model.rqrs.transfer.QueryTransferOrderRS;
import com.jeequan.jeepay.core.utils.DateKit;
import com.jeequan.jeepay.core.utils.JeepayKit;
import com.jeequan.jeepay.core.utils.StringKit;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.pay.util.ApiResKit;
import com.jeequan.jeepay.service.impl.MchAppService;
import com.jeequan.jeepay.service.impl.MchConfigService;
import com.jeequan.jeepay.service.impl.MchNotifyRecordService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/*
* 商户通知 service
*
* @author terrfly
*
* @date 2021/6/8 17:43
*/
@Slf4j
@Service
public class PayMchNotifyService {

    @Autowired private MchNotifyRecordService mchNotifyRecordService;
    @Autowired private IConfigContextQueryService configContextQueryService;
    @Autowired private MchConfigService mchConfigService;
    @Autowired private IMQSender mqSender;
    @Autowired private MchAppService mchAppService;
    @Autowired private MchInfoConverter mchInfoConverter;

    /** 商户通知信息， 只有订单是终态，才会发送通知， 如明确成功和明确失败 **/
    public void payOrderNotify(PayOrder dbPayOrder){

        try {
            boolean isNotify = true;

            // 是否发送通知
            MchConfig mchConfig = mchConfigService.getByMchNoAndConfigKey(dbPayOrder.getMchNo(), "mchNotifyFlag");
            if (mchConfig != null && StringUtils.isNotEmpty(mchConfig.getConfigVal())) {
                JSONObject mchNotifyJson = JSONObject.parseObject(mchConfig.getConfigVal());
                Byte payNotifyFlag = mchNotifyJson.getByte("payNotifyFlag");
                // 明确不发送通知
                if (payNotifyFlag != null && payNotifyFlag == CS.NO) {
                    isNotify = false;
                }
            }

            if (!isNotify){
                return ;
            }

            // 通知地址为空
            if(StringUtils.isEmpty(dbPayOrder.getNotifyUrl())){
                return ;
            }

            //获取到通知对象
            MchNotifyRecord mchNotifyRecord = mchNotifyRecordService.findByPayOrder(dbPayOrder.getPayOrderId());

            if(mchNotifyRecord != null){

                log.info("当前已存在通知消息， 不再发送。");
                return ;
            }
            AccessResp body = bulidNotifyData(dbPayOrder);
            // 封装通知url
//            String notifyUrl = createNotifyUrl(dbPayOrder, appSecret);
            mchNotifyRecord = new MchNotifyRecord();
            mchNotifyRecord.setOrderId(dbPayOrder.getPayOrderId());
            mchNotifyRecord.setOrderType(MchNotifyRecord.TYPE_PAY_ORDER);
            mchNotifyRecord.setMchNo(dbPayOrder.getMchNo());
            mchNotifyRecord.setMchOrderNo(dbPayOrder.getMchOrderNo()); //商户订单号
            mchNotifyRecord.setIsvNo(dbPayOrder.getIsvNo());
            mchNotifyRecord.setNotifyBody(JSONObject.toJSONString(body));
            mchNotifyRecord.setAppId(dbPayOrder.getAppId());
            mchNotifyRecord.setNotifyUrl(dbPayOrder.getNotifyUrl());
            mchNotifyRecord.setNotifyPostType(CS.NOTIFY_POST_TYPE.POST_JSON); // 通知类型
            mchNotifyRecord.setResResult("");
            mchNotifyRecord.setNotifyCount(0);
            mchNotifyRecord.setState(MchNotifyRecord.STATE_ING); // 通知中

            try {
                mchNotifyRecordService.save(mchNotifyRecord);
            } catch (Exception e) {
                log.info("数据库已存在[{}]消息，本次不再推送。", mchNotifyRecord.getOrderId());
                return ;
            }

            //推送到MQ
            Long notifyId = mchNotifyRecord.getNotifyId();
            mqSender.send(PayOrderMchNotifyMQ.build(notifyId));

        } catch (Exception e) {
            log.error("推送失败！", e);
        }
    }

    /**
     * 通知参数
     * @param payOrder
     * @return
     */
    public AccessResp bulidNotifyData(PayOrder payOrder) {
        AccessReq req = new AccessReq();
        req.setAppId(payOrder.getAppId());
        MchAppEntity mchApp = mchAppService.getById(payOrder.getAppId());
        req.setAppInfo(mchInfoConverter.toModel(mchApp));
        req.setPlatPriKey(ApiResKit.getKey());
        PayResultResp bizResp = new PayResultResp(payOrder);
        bizResp.setMsgType(CS.OpenMsgType.TRADE_MSG_TYPE);
        AccessResp resp = new AccessResp(AccessError.SUCCESS,bizResp,req);
        // 生成通知
        return resp;
    }

    /**
     * 退款通知
     * @param refundOrder
     * @return
     */
    public AccessResp bulidNotifyData(RefundOrder refundOrder) {
        AccessReq req = new AccessReq();
        req.setAppId(refundOrder.getAppId());
        MchAppEntity mchApp = mchAppService.getById(refundOrder.getAppId());
        req.setAppInfo(mchInfoConverter.toModel(mchApp));
        req.setPlatPriKey(ApiResKit.getKey());
        RefundResultResp bizResp = refundOrder.bulidResult();
        bizResp.setMsgType(CS.OpenMsgType.REFUND_MSG_TYPE);
        AccessResp resp = new AccessResp(AccessError.SUCCESS,bizResp,req);
        // 生成通知
        return resp;
    }

    /** 商户通知信息，退款成功的发送通知 **/
    public void refundOrderNotify(RefundOrder dbRefundOrder){

        try {
            boolean isNotify = true;

            // 是否发送通知
            MchConfig mchConfig = mchConfigService.getByMchNoAndConfigKey(dbRefundOrder.getMchNo(), "mchNotifyFlag");
            if (mchConfig != null && StringUtils.isNotEmpty(mchConfig.getConfigVal())) {
                JSONObject mchNotifyJson = JSONObject.parseObject(mchConfig.getConfigVal());
                Byte refundNotifyFlag = mchNotifyJson.getByte("refundNotifyFlag");
                // 明确不发送通知
                if (refundNotifyFlag != null && refundNotifyFlag == CS.NO) {
                    isNotify = false;
                }
            }

            // 不发送通知直接返回
            if (!isNotify) {
                return ;
            }

            // 通知地址为空
            if(StringUtils.isEmpty(dbRefundOrder.getNotifyUrl())){
                return ;
            }

            //获取到通知对象
            MchNotifyRecord mchNotifyRecord = mchNotifyRecordService.findByRefundOrder(dbRefundOrder.getRefundOrderId());

            if(mchNotifyRecord != null){

                log.info("当前已存在通知消息， 不再发送。");
                return ;
            }
            // 封装通知url
            AccessResp body = bulidNotifyData(dbRefundOrder);
            mchNotifyRecord = new MchNotifyRecord();
            mchNotifyRecord.setOrderId(dbRefundOrder.getRefundOrderId());
            mchNotifyRecord.setOrderType(MchNotifyRecord.TYPE_REFUND_ORDER);
            mchNotifyRecord.setMchNo(dbRefundOrder.getMchNo());
            mchNotifyRecord.setMchOrderNo(dbRefundOrder.getMchRefundNo()); //商户订单号
            mchNotifyRecord.setIsvNo(dbRefundOrder.getIsvNo());
            mchNotifyRecord.setAppId(dbRefundOrder.getAppId());
            mchNotifyRecord.setNotifyUrl(dbRefundOrder.getNotifyUrl());
            mchNotifyRecord.setNotifyUrl(JSON.toJSONString(body));
            mchNotifyRecord.setNotifyPostType(CS.NOTIFY_POST_TYPE.POST_BODY); // 通知类型
            mchNotifyRecord.setResResult("");
            mchNotifyRecord.setNotifyCount(0);
            mchNotifyRecord.setState(MchNotifyRecord.STATE_ING); // 通知中

            try {
                mchNotifyRecordService.save(mchNotifyRecord);
            } catch (Exception e) {
                log.info("数据库已存在[{}]消息，本次不再推送。", mchNotifyRecord.getOrderId());
                return ;
            }

            //推送到MQ
            Long notifyId = mchNotifyRecord.getNotifyId();
            mqSender.send(PayOrderMchNotifyMQ.build(notifyId));

        } catch (Exception e) {
            log.error("推送失败！", e);
        }
    }


    /** 商户通知信息，转账订单的通知接口 **/
    public void transferOrderNotify(TransferOrderEntity dbTransferOrder){

        try {
            // 通知地址为空
            if(StringUtils.isEmpty(dbTransferOrder.getNotifyUrl())){
                return ;
            }

            //获取到通知对象
            MchNotifyRecord mchNotifyRecord = mchNotifyRecordService.findByTransferOrder(dbTransferOrder.getTransferId());

            if(mchNotifyRecord != null){
                log.info("当前已存在通知消息， 不再发送。");
                return ;
            }

            //商户app私钥
            String appSecret = configContextQueryService.queryMchApp(dbTransferOrder.getMchNo(), dbTransferOrder.getAppId()).getAppSecret();

            // 封装通知url
            String notifyUrl = createNotifyUrl(dbTransferOrder, appSecret);
            mchNotifyRecord = new MchNotifyRecord();
            mchNotifyRecord.setOrderId(dbTransferOrder.getTransferId());
            mchNotifyRecord.setOrderType(MchNotifyRecord.TYPE_TRANSFER_ORDER);
            mchNotifyRecord.setMchNo(dbTransferOrder.getMchNo());
            mchNotifyRecord.setMchOrderNo(dbTransferOrder.getMchOrderNo()); //商户订单号
            mchNotifyRecord.setIsvNo(dbTransferOrder.getIsvNo());
            mchNotifyRecord.setAppId(dbTransferOrder.getAppId());
            mchNotifyRecord.setNotifyUrl(notifyUrl);
            mchNotifyRecord.setNotifyPostType(mchConfigService.queryMchNotifyTypeConfigDefaultPOSTBody(dbTransferOrder.getMchNo())); // 通知类型
            mchNotifyRecord.setResResult("");
            mchNotifyRecord.setNotifyCount(0);
            mchNotifyRecord.setState(MchNotifyRecord.STATE_ING); // 通知中

            try {
                mchNotifyRecordService.save(mchNotifyRecord);
            } catch (Exception e) {
                log.info("数据库已存在[{}]消息，本次不再推送。", mchNotifyRecord.getOrderId());
                return ;
            }

            //推送到MQ
            Long notifyId = mchNotifyRecord.getNotifyId();
            mqSender.send(PayOrderMchNotifyMQ.build(notifyId));

        } catch (Exception e) {
            log.error("推送失败！", e);
        }
    }

//    public static void main(String[] args) {
//        String key = "O3kAhyaxYSbYhFg0CDiNflJ8eoNGpQ8Gn8m1vQKrcybE0tH8aB1WEggDT3NbRza6FItOoSDbj64WdxR0JG749c1jTTI4LQkKzZMAggPbhRB32Mf2lgnYDKJNs5sqlJLS";
//        String url = "https://b.shouyinbei.com/api/anon/paytestNotify/payOrder";
//        JSONObject jsonObject = new JSONObject();
//        jsonObject.put("amount","1");
//        jsonObject.put("appId","65d5abb9e4b0607c72ea5eaf");
//        jsonObject.put("body","快捷收款[U17085019455商户联调]");
//        jsonObject.put("channelOrderNo","C612403121544108298482444");
//        jsonObject.put("clientIp","127.0.0.1");
//        jsonObject.put("createdAt","1710229450815");
//        jsonObject.put("currency","CNY");
//        jsonObject.put("ifCode","ryxpay");
//        jsonObject.put("mchNo","U17085019455");
//        jsonObject.put("mchOrderNo","M17102293428963596");
//        jsonObject.put("payOrderId","O1767456536883744769");
//        jsonObject.put("reqTime","1710229472526");
//        jsonObject.put("state","2");
//
//        jsonObject.put("subject","快捷收款[U17085019455商户联调]");
//        jsonObject.put("successTime","1710229472000");
//        jsonObject.put("wayCode","WX_BAR");
//        String s = StringKit.appendUrlQuery(url, jsonObject);
//        System.out.println(s);
//    }

    /**
     * 创建响应URL
     */
    public String createNotifyUrl(TransferOrderEntity transferOrder, String appSecret) {

        QueryTransferOrderRS rs = QueryTransferOrderRS.buildByRecord(transferOrder);
        JSONObject jsonObject = (JSONObject)JSONObject.toJSON(rs);
        jsonObject.put("reqTime", DateKit.currentTimeMillis()); //添加请求时间

        // 报文签名
        jsonObject.put("sign", JeepayKit.getSign(jsonObject, appSecret));

        // 生成通知
        return StringKit.appendUrlQuery(transferOrder.getNotifyUrl(), jsonObject);
    }


    /**
     * 创建响应URL
     */
    public String createReturnUrl(PayOrder payOrder, String appSecret) {

        if(StringUtils.isEmpty(payOrder.getReturnUrl())){
            return "";
        }

        QueryPayOrderRS queryPayOrderRS = QueryPayOrderRS.buildByPayOrder(payOrder);
        JSONObject jsonObject = (JSONObject)JSONObject.toJSON(queryPayOrderRS);
        jsonObject.put("reqTime", DateKit.currentTimeMillis()); //添加请求时间

        // 报文签名
        jsonObject.put("sign", JeepayKit.getSign(jsonObject, appSecret));   // 签名

        // 生成跳转地址
        return StringKit.appendUrlQuery(payOrder.getReturnUrl(), jsonObject);

    }

}
