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

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.entity.MchApplyment;
import com.jeequan.jeepay.core.entity.MchModifyApplyment;
import com.jeequan.jeepay.core.interfaces.paychannel.IIsvmchModifyApplymentService;
import com.jeequan.jeepay.core.model.applyment.ApplymentSignInfo;
import com.jeequan.jeepay.core.model.applyment.MchModifyApplymentModel;
import com.jeequan.jeepay.core.model.applyment.YspayApplymentInfo;
import com.jeequan.jeepay.core.model.params.yspay.YspayIsvParams;
import com.jeequan.jeepay.service.impl.SysConfigService;
import com.jeequan.jeepay.thirdparty.channel.yspay.model.ReqMethod;
import com.jeequan.jeepay.thirdparty.channel.yspay.utils.YspayKit;
import com.jeequan.jeepay.thirdparty.service.ConfigContextQueryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.MutablePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;


@Slf4j
@Service
public class YspayIsvmchModifyApplymentService implements IIsvmchModifyApplymentService {

    @Autowired
    protected SysConfigService sysConfigService;

    @Autowired
    private ConfigContextQueryService configContextQueryService;

    @Override
    public MutablePair<MchModifyApplyment, MchApplyment> localModifyBase(MutablePair<MchModifyApplyment, MchApplyment> mchDataPair) {
        MchModifyApplyment resultModifyApplyment = new MchModifyApplyment();
        MchApplyment resultMchApplyment = new MchApplyment();

        MchModifyApplyment mchModifyApplyment = mchDataPair.getKey();
        resultModifyApplyment.setModifyApplyId(mchModifyApplyment.getModifyApplyId());
        resultModifyApplyment.setState(MchApplyment.STATE_SUCCESS);
        MchApplyment mchApplyment = mchDataPair.getValue();
        resultMchApplyment.setApplyId(mchApplyment.getApplyId());

        String applyDetailInfo = mchModifyApplyment.getApplyDetailInfo();
        MchModifyApplymentModel mchModifyData = JSON.parseObject(applyDetailInfo, MchModifyApplymentModel.class);

        String originApplyDetailInfo = mchApplyment.getApplyDetailInfo();
        YspayApplymentInfo originMchModifyData = JSON.parseObject(originApplyDetailInfo, YspayApplymentInfo.class);
        resultMchApplyment.setApplyDetailInfo(JSON.toJSONString(originMchModifyData));

        originMchModifyData.setMchShortName(mchModifyData.getMchShortName());
        resultMchApplyment.setMchShortName(mchModifyData.getMchShortName());

        return new MutablePair<>(resultModifyApplyment, resultMchApplyment);
    }

    @Override
    public MutablePair<MchModifyApplyment, MchApplyment> localModifySettlement(MutablePair<MchModifyApplyment, MchApplyment> mchDataPair) {
        MchModifyApplyment resultModifyApplyment = new MchModifyApplyment();
        MchApplyment resultMchApplyment = new MchApplyment();

        MchModifyApplyment mchModifyApplyment = mchDataPair.getKey();
        resultModifyApplyment.setModifyApplyId(mchModifyApplyment.getModifyApplyId());
        resultModifyApplyment.setState(MchApplyment.STATE_SUCCESS);
        MchApplyment mchApplyment = mchDataPair.getValue();
        resultMchApplyment.setApplyId(mchApplyment.getApplyId());

        String applyDetailInfo = mchModifyApplyment.getApplyDetailInfo();
        MchModifyApplymentModel mchModifyData = JSON.parseObject(applyDetailInfo, MchModifyApplymentModel.class);

        String originApplyDetailInfo = mchApplyment.getApplyDetailInfo();
        YspayApplymentInfo originMchModifyData = JSON.parseObject(originApplyDetailInfo, YspayApplymentInfo.class);
        resultMchApplyment.setApplyDetailInfo(JSON.toJSONString(originMchModifyData));

        originMchModifyData.setSettAccountType(mchModifyData.getSettAccountType());
        originMchModifyData.setIsUncrpSett(mchModifyData.getIllegal());
        originMchModifyData.setSettAccountLicenseImg(mchModifyData.getSettAccountLicenseImg());
        originMchModifyData.setSettAccountName(mchModifyData.getSettAccountName());
        originMchModifyData.setSettAccountNo(mchModifyData.getSettAccountNo());
        originMchModifyData.setSettAccountBankName(mchModifyData.getSettAccountBankName());
        originMchModifyData.setSettleAuthLetterPhoto(mchModifyData.getNonLegSettleAuthPic());
        originMchModifyData.setSettAccountIdcardNo(mchModifyData.getSettAccountIdcardNo());
        originMchModifyData.setSettAccountIdcard1Img(mchModifyData.getSettAccountIdcard1Img());
        originMchModifyData.setSettAccountIdcard2Img(mchModifyData.getSettAccountIdcard2Img());
        originMchModifyData.setSettAccountIdcardEffectBegin(mchModifyData.getSettAccountIdcardEffectBegin());
        originMchModifyData.setSettAccountIdcardEffectEnd(mchModifyData.getSettAccountIdcardEffectEnd());

        return new MutablePair<>(resultModifyApplyment, resultMchApplyment);
    }

    @Override
    public MutablePair<MchModifyApplyment, MchApplyment> localModifyRate(MutablePair<MchModifyApplyment, MchApplyment> mchDataPair) {
        return mchDataPair;
    }

    @Override
    public MutablePair<MchModifyApplyment, MchApplyment> syncChannelModifyBase(MutablePair<MchModifyApplyment, MchApplyment> mchDataPair) {
        MchModifyApplyment resultModifyApplyment = new MchModifyApplyment();

        MchModifyApplyment mchModifyApplyment = mchDataPair.getKey();
        resultModifyApplyment.setModifyApplyId(mchModifyApplyment.getModifyApplyId());
        resultModifyApplyment.setState(MchApplyment.STATE_AUDITING);
        MchApplyment mchApplyment = mchDataPair.getValue();

        YspayIsvParams isvParams = (YspayIsvParams) configContextQueryService.queryIsvParams(mchApplyment);

        String applyDetailInfo = mchModifyApplyment.getApplyDetailInfo();
        MchModifyApplymentModel mchModifyData = JSON.parseObject(applyDetailInfo, MchModifyApplymentModel.class);

        JSONObject param = new JSONObject();
        param.put("notifyUrl", getCallbackUrl(mchApplyment.getIfCode(), mchApplyment.getApplyId()));
        param.put("mercId", mchApplyment.getChannelMchNo());
        param.put("contractType", "2");
        param.put("changeThirdFlowId", mchModifyApplyment.getModifyApplyId());

        JSONObject custInfo = new JSONObject();

        custInfo.put("mercShortName", mchModifyData.getMchShortName());
        // 其他属性暂不考虑
        param.put("custInfo", custInfo);

        if (ObjectUtils.isEmpty(mchModifyData.getChangeFormPic())) {
            // 使用电子变更申请表
            param.put("contractType", "2");
        } else {
            // 使用纸质变更申请表
            param.put("contractType", "1");
        }

        try {
            String respData = YspayKit.applymentRequest(ReqMethod.Method.CHANGE_MERC_BASE_INFO, isvParams, param);
            JSONObject applyResp = JSON.parseObject(respData);
            JSONObject applyRespData = applyResp.getJSONObject("data");

            String changeSysFlowId = applyRespData.getString("changeSysFlowId");

            resultModifyApplyment.setChannelApplyNo(changeSysFlowId);
            resultModifyApplyment.setChannelVar1(applyRespData.toJSONString());
            resultModifyApplyment.setState(MchApplyment.STATE_AUDITING);

            String signUrl = applyRespData.getString("signUrl");
            if (!CharSequenceUtil.isEmpty(signUrl)) {
                resultModifyApplyment.setState(MchApplyment.STATE_WAIT_SIGN);
            }

            String remark = "银盛基本信息变更已发起";
            resultModifyApplyment.setRemark(remark);
            log.debug("云商服3.0基本信息变更发起成功");
        } catch (Exception e) {
            resultModifyApplyment.setApplyErrorInfo("[" + e.getMessage() + "]");
            resultModifyApplyment.setState(MchApplyment.STATE_REJECT_WAIT_MODIFY);
        }

        if (!ObjectUtils.isEmpty(mchModifyData.getChangeFormPic())) {
            // 使用纸质变更申请表
            YspayKit.uploadEditRequest(resultModifyApplyment.getChannelApplyNo(), isvParams, mchModifyData.getChangeFormPic(), "B008");
        }

        return new MutablePair<>(resultModifyApplyment, null);
    }

    @Override
    public MutablePair<MchModifyApplyment, MchApplyment> syncChannelModifySettlement(MutablePair<MchModifyApplyment, MchApplyment> mchDataPair) {
        MchModifyApplyment resultModifyApplyment = new MchModifyApplyment();

        MchModifyApplyment mchModifyApplyment = mchDataPair.getKey();
        resultModifyApplyment.setModifyApplyId(mchModifyApplyment.getModifyApplyId());
        resultModifyApplyment.setState(MchApplyment.STATE_AUDITING);
        MchApplyment mchApplyment = mchDataPair.getValue();

        YspayIsvParams isvParams = (YspayIsvParams) configContextQueryService.queryIsvParams(mchApplyment);

        String applyDetailInfo = mchModifyApplyment.getApplyDetailInfo();
        MchModifyApplymentModel mchModifyData = JSON.parseObject(applyDetailInfo, MchModifyApplymentModel.class);

        JSONObject param = new JSONObject();
        param.put("notifyUrl", getCallbackUrl(mchApplyment.getIfCode(), mchApplyment.getApplyId()));
        JSONObject stlAccInfo = new JSONObject();
        stlAccInfo.put("isSettInPlatAcc", "N");
        stlAccInfo.put("isUncrpSett", mchModifyData.getIllegal());
        stlAccInfo.put("stlAccNo", mchModifyData.getSettAccountNo());
        stlAccInfo.put("stlAccType", mchModifyData.getSettAccountType().equals("B")? "21": "11");
        stlAccInfo.put("openCertNo", mchModifyData.getSettAccountIdcardNo());
        stlAccInfo.put("stlAccNm", mchModifyData.getSettAccountName());
        stlAccInfo.put("bankSubCode", mchModifyData.getBankSubCode());
        stlAccInfo.put("bankMobile", mchModifyData.getPhone());

        stlAccInfo.put("bankProince", mchModifyData.getSettAccountBankBranchAreaCode().getString(0));
        stlAccInfo.put("bankCity", mchModifyData.getSettAccountBankBranchAreaCode().getString(1));

        param.put("stlAccInfo", stlAccInfo);
        param.put("mercId", mchApplyment.getChannelMchNo());

        if (ObjectUtils.isEmpty(mchModifyData.getChangeFormPic())) {
            // 使用电子变更申请表
            param.put("contractType", "2");
        } else {
            // 使用纸质变更申请表
            param.put("contractType", "1");
        }

        try {
            String respData = YspayKit.applymentRequest(ReqMethod.Method.CHANGE_MERC_STL_ACC_INFO, isvParams, param);
            JSONObject applyResp = JSON.parseObject(respData);
            JSONObject applyRespData = applyResp.getJSONObject("data");

            String changeSysFlowId = applyRespData.getString("changeSysFlowId");

            resultModifyApplyment.setChannelApplyNo(changeSysFlowId);
            resultModifyApplyment.setChannelVar1(applyRespData.toJSONString());
            resultModifyApplyment.setState(MchApplyment.STATE_AUDITING);

            String signUrl = applyRespData.getString("signUrl");
            if (!CharSequenceUtil.isEmpty(signUrl)) {
                resultModifyApplyment.setState(MchApplyment.STATE_WAIT_SIGN);
            }

            String remark = "银盛结算信息变更已发起";
            resultModifyApplyment.setRemark(remark);
            log.debug("云商服3.0基本信息变更发起成功");
        } catch (Exception e) {
            resultModifyApplyment.setApplyErrorInfo("[" + e.getMessage() + "]");
            resultModifyApplyment.setState(MchApplyment.STATE_REJECT_WAIT_MODIFY);

            return new MutablePair<>(resultModifyApplyment, null);
        }

        // 上传图片
        if ("B".equals(mchModifyData.getSettAccountType())) {
            YspayKit.uploadEditRequest(resultModifyApplyment.getChannelApplyNo(), isvParams, mchModifyData.getSettAccountLicenseImg(), "A011");
        } else {
            YspayKit.uploadEditRequest(resultModifyApplyment.getChannelApplyNo(), isvParams, mchModifyData.getSettAccountLicenseImg(), "A004");
            YspayKit.uploadEditRequest(resultModifyApplyment.getChannelApplyNo(), isvParams, mchModifyData.getSettAccountLicenseImg(), "A005");
        }

        if ("Y".equals(mchModifyData.getIllegal())) {
            // 非法人结算, 上传身份证图片
            YspayKit.uploadEditRequest(resultModifyApplyment.getChannelApplyNo(), isvParams, mchModifyData.getSettAccountIdcard1Img(), "A013");
            YspayKit.uploadEditRequest(resultModifyApplyment.getChannelApplyNo(), isvParams, mchModifyData.getSettAccountIdcard2Img(), "A014");
            YspayKit.uploadEditRequest(resultModifyApplyment.getChannelApplyNo(), isvParams, mchModifyData.getNonLegSettleAuthPic(), "B005");
        }

        if (!ObjectUtils.isEmpty(mchModifyData.getChangeFormPic())) {
            // 使用纸质变更申请表
            YspayKit.uploadEditRequest(resultModifyApplyment.getChannelApplyNo(), isvParams, mchModifyData.getChangeFormPic(), "B008");
        }

        return new MutablePair<>(resultModifyApplyment, null);
    }

    @Override
    public MutablePair<MchModifyApplyment, MchApplyment> syncChannelModifyRate(MutablePair<MchModifyApplyment, MchApplyment> mchDataPair) {
        return mchDataPair;
    }

    @Override
    public MutablePair<MchModifyApplyment, MchApplyment> syncChannelModifySettlementType(MutablePair<MchModifyApplyment, MchApplyment> mchDataPair) {
        // 银盛的变更与本地修改保持一致
        return localModifySettlementType(mchDataPair);
    }

    @Override
    public MutablePair<MchModifyApplyment, MchApplyment> queryModifyResult(MutablePair<MchModifyApplyment, MchApplyment> mchDataPair) {
        MchModifyApplyment resultModifyApplyment = new MchModifyApplyment();

        MchModifyApplyment modifyApplyment = mchDataPair.getLeft();
        resultModifyApplyment.setModifyApplyId(modifyApplyment.getModifyApplyId());

        MchApplyment mchApplyment = mchDataPair.getRight();

        YspayIsvParams isvParams = (YspayIsvParams) configContextQueryService.queryIsvParams(mchApplyment);

        JSONObject param = new JSONObject();
        param.put("changeSysFlowId", modifyApplyment.getChannelApplyNo());

        String respData = YspayKit.applymentRequest(ReqMethod.Method.QUERY_CUST_CHANGE, isvParams, param);
        JSONObject bizData = JSON.parseObject(respData).getJSONObject("data");
        String status = bizData.getString("status");

        switch (status) {
            case "00":
                // 成功
                resultModifyApplyment.setChannelVar1(processChannelValue(modifyApplyment.getChannelVar1(), bizData));
                return handleSuccessCase(modifyApplyment, mchDataPair);
            case "01":
                // 待补充资料, 图片未上传
                resultModifyApplyment.setChannelVar1(processChannelValue(modifyApplyment.getChannelVar1(), bizData));
                resultModifyApplyment.setState(MchApplyment.STATE_WAIT_VERIFY);

                return new MutablePair<>(resultModifyApplyment, null);
            case "02":
                // 待审核
                // 待签署电子变更申请表
                resultModifyApplyment.setChannelVar1(processChannelValue(modifyApplyment.getChannelVar1(), bizData));
                resultModifyApplyment.setState(MchApplyment.STATE_AUDITING);
                return new MutablePair<>(resultModifyApplyment, null);
            case "03":
                // 待签署电子变更申请表
                resultModifyApplyment.setChannelVar1(processChannelValue(modifyApplyment.getChannelVar1(), bizData));
                resultModifyApplyment.setState(MchApplyment.STATE_WAIT_SIGN);

                return new MutablePair<>(resultModifyApplyment, null);
            default:
                // 失败
                resultModifyApplyment.setChannelVar1(processChannelValue(modifyApplyment.getChannelVar1(), bizData));
                resultModifyApplyment.setState(MchApplyment.STATE_REJECT_WAIT_MODIFY);
                resultModifyApplyment.setApplyErrorInfo("[" + bizData.getString("note") + "]");

                return new MutablePair<>(resultModifyApplyment, null);
        }

    }

    private MutablePair<MchModifyApplyment, MchApplyment> handleSuccessCase(MchModifyApplyment modifyApplyment, MutablePair<MchModifyApplyment, MchApplyment> mchDataPair) {
        switch (modifyApplyment.getModifyApplyType()) {
            case MchModifyApplyment.MODIFY_TYPE_BASE:
                return localModifyBase(mchDataPair);
            case MchModifyApplyment.MODIFY_TYPE_SETTLEMENT:
                return localModifySettlement(mchDataPair);
            default:
                return mchDataPair;
        }
    }

    private String processChannelValue(String channelVal, JSONObject bizData) {
        JSONObject channelValJSON = StrUtil.isEmptyIfStr(channelVal) ? new JSONObject() : JSON.parseObject(channelVal);
        ApplymentSignInfo signInfo = new ApplymentSignInfo();
        signInfo.setSignUrl(bizData.getString("signUrl"));
        signInfo.setState("签约中");
        signInfo.setOriginData(bizData.toJSONString());
        channelValJSON.putAll(((JSONObject) JSON.toJSON(signInfo)));

        return channelValJSON.toJSONString();
    }


    // 获取支付网关，用于进件回调
    protected String getCallbackUrl(String ifCode, String applyId) {
        return sysConfigService.getDBApplicationConfig().getPaySiteUrl() + "/api/mchApplyment/notify/" + ifCode + "/" + applyId;
    }
}
