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

import cn.hutool.core.util.ObjUtil;
import com.alibaba.fastjson.JSON;
import com.alipay.api.domain.*;
import com.alipay.api.request.AntMerchantExpandIndirectZftModifyRequest;
import com.alipay.api.request.AntMerchantExpandIndirectZftorderQueryRequest;
import com.alipay.api.response.AntMerchantExpandIndirectZftModifyResponse;
import com.alipay.api.response.AntMerchantExpandIndirectZftorderQueryResponse;
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.MchModifyApplymentModel;
import com.jeequan.jeepay.core.model.applyment.ZftpayApplymentInfo;
import com.jeequan.jeepay.core.model.params.zftpay.ZftpayIsvParams;
import com.jeequan.jeepay.db.entity.BankBranchZft;
import com.jeequan.jeepay.service.impl.BankBranchZftService;
import com.jeequan.jeepay.thirdparty.service.ConfigContextQueryService;
import org.apache.commons.lang3.tuple.MutablePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.Collections;

/**
 * TODO
 *
 * @author deng
 * @since 2024/4/17
 */
@Service
public class ZftpayIsvmchModifyApplymentService implements IIsvmchModifyApplymentService {

    @Autowired
    private ConfigContextQueryService configContextQueryService;

    @Autowired
    private BankBranchZftService bankBranchZftService;

    @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();
        ZftpayApplymentInfo originMchModifyData = JSON.parseObject(originApplyDetailInfo, ZftpayApplymentInfo.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();
        ZftpayApplymentInfo originMchModifyData = JSON.parseObject(originApplyDetailInfo, ZftpayApplymentInfo.class);
        resultMchApplyment.setApplyDetailInfo(JSON.toJSONString(originMchModifyData));

        originMchModifyData.setDefaultSettleType(mchModifyData.getDefaultSettleType());

        if (!ObjUtil.isEmpty(mchModifyData.getDefaultSettleType())) {
            // 支付宝支付
            originMchModifyData.setAlipayLogonId(mchModifyData.getAlipayLogonId());
        } else {
            originMchModifyData.setSettAccountLicenseImg(mchModifyData.getSettAccountLicenseImg());
            originMchModifyData.setSettAccountName(mchModifyData.getSettAccountName());
            originMchModifyData.setSettAccountNo(mchModifyData.getSettAccountNo());
            originMchModifyData.setSettAccountBankBranchAreaCode(mchModifyData.getSettAccountBankBranchAreaCode());
            originMchModifyData.setSettAccountBankBranchCode(mchModifyData.getBankSubCode());
            originMchModifyData.setSettAccountBankName(mchModifyData.getSettAccountBankName());
        }

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

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

    @Override
    public MutablePair<MchModifyApplyment, MchApplyment> syncChannelModifyBase(MutablePair<MchModifyApplyment, MchApplyment> mchDataPair) {
        MchApplyment mchApplyment = mchDataPair.right;
        MchModifyApplyment modifyApplyment = mchDataPair.left;
        MchModifyApplyment result = new MchModifyApplyment();
        result.setModifyApplyId(modifyApplyment.getModifyApplyId());

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

        MchModifyApplymentModel mchModifyApplymentModel = JSON.parseObject(modifyApplyment.getApplyDetailInfo(), MchModifyApplymentModel.class);
        String mchShortName = mchModifyApplymentModel.getMchShortName();

        AntMerchantExpandIndirectZftModifyModel zftModifyModel = new AntMerchantExpandIndirectZftModifyModel();
        zftModifyModel.setAliasName(mchShortName);
        zftModifyModel.setSmid(mchApplyment.getChannelMchNo());
        AntMerchantExpandIndirectZftModifyRequest request = new AntMerchantExpandIndirectZftModifyRequest();
        request.setBizModel(zftModifyModel);

        AntMerchantExpandIndirectZftModifyResponse response = ZftpayKit.req(isvParams, request);
        String orderId = response.getOrderId();

        result.setChannelMchNo(orderId);
        result.setState(MchApplyment.STATE_AUDITING);

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

    @Override
    public MutablePair<MchModifyApplyment, MchApplyment> syncChannelModifySettlement(MutablePair<MchModifyApplyment, MchApplyment> mchDataPair) {
        MchApplyment mchApplyment = mchDataPair.right;
        MchModifyApplyment modifyApplyment = mchDataPair.left;
        MchModifyApplyment result = new MchModifyApplyment();
        result.setModifyApplyId(modifyApplyment.getModifyApplyId());

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

        MchModifyApplymentModel mchModifyApplymentModel = JSON.parseObject(modifyApplyment.getApplyDetailInfo(), MchModifyApplymentModel.class);
        String mchShortName = mchModifyApplymentModel.getMchShortName();

        AntMerchantExpandIndirectZftModifyModel zftModifyModel = new AntMerchantExpandIndirectZftModifyModel();
        AntMerchantExpandIndirectZftModifyRequest request = new AntMerchantExpandIndirectZftModifyRequest();
        request.setBizModel(zftModifyModel);
        zftModifyModel.setSmid(mchApplyment.getChannelMchNo());

        DefaultSettleRule defaultSettleRule = new DefaultSettleRule();
        zftModifyModel.setDefaultSettleRule(defaultSettleRule);
        defaultSettleRule.setDefaultSettleType(mchModifyApplymentModel.getDefaultSettleType());

        if ("bankCard".equals(mchModifyApplymentModel.getDefaultSettleType())) {
            // 银行卡支付
            SettleCardInfo bizCard = new SettleCardInfo();
            bizCard.setAccountNo(mchModifyApplymentModel.getSettAccountNo());

            Assert.notNull(mchModifyApplymentModel.getBankSubCode(), "支行联行号不能为空");
            BankBranchZft branchZft = bankBranchZftService.lambdaQuery()
                    .eq(BankBranchZft::getBranchNo, mchModifyApplymentModel.getBankSubCode())
                    .one();

            bizCard.setAccountInstName(branchZft.getBankName());
            bizCard.setAccountInstId(branchZft.getBankAbbr());
            bizCard.setBankCode(branchZft.getBranchNo());
            bizCard.setAccountNo(mchModifyApplymentModel.getSettAccountNo());
            defaultSettleRule.setDefaultSettleTarget(mchModifyApplymentModel.getSettAccountNo());

            zftModifyModel.setBizCards(Collections.singletonList(bizCard));
        } else {
            // 支付宝支付
            zftModifyModel.setAlipayLogonId(mchModifyApplymentModel.getAlipayLogonId());
            defaultSettleRule.setDefaultSettleTarget(mchModifyApplymentModel.getAlipayLogonId());
        }

        AntMerchantExpandIndirectZftModifyResponse response = ZftpayKit.req(isvParams, request);
        String orderId = response.getOrderId();

        result.setChannelMchNo(orderId);
        result.setState(MchApplyment.STATE_AUDITING);

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

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

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

    @Override
    public MutablePair<MchModifyApplyment, MchApplyment> queryModifyResult(MutablePair<MchModifyApplyment, MchApplyment> mchDataPair) {
        MchApplyment mchApplyment = mchDataPair.right;
        MchModifyApplyment modifyApplyment = mchDataPair.left;
        MchModifyApplyment result = new MchModifyApplyment();
        result.setModifyApplyId(modifyApplyment.getModifyApplyId());
        result.setState(MchApplyment.STATE_REJECT_WAIT_MODIFY);

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

        AntMerchantExpandIndirectZftorderQueryModel queryModel = new AntMerchantExpandIndirectZftorderQueryModel();
        AntMerchantExpandIndirectZftorderQueryRequest request = new AntMerchantExpandIndirectZftorderQueryRequest();
        queryModel.setOrderId(modifyApplyment.getApplyId());

        AntMerchantExpandIndirectZftorderQueryResponse response = ZftpayKit.req(isvParams, request);

        for (ZftSubMerchantOrder order : response.getOrders()) {
            if (order.getOrderId().equals(modifyApplyment.getApplyId())) {
                if ("99".equals(order.getStatus())) {
                    // 成功
                    switch (modifyApplyment.getModifyApplyType()) {
                        case MchModifyApplyment.MODIFY_TYPE_BASE:
                            return localModifyBase(mchDataPair);
                        case MchModifyApplyment.MODIFY_TYPE_SETTLEMENT:
                            return localModifySettlement(mchDataPair);
                    }
                }

                if ("-1".equals(order.getStatus())) {
                    // 失败
                    result.setState(MchApplyment.STATE_REJECT_WAIT_MODIFY);
                }

                break;
            }
        }

        return new MutablePair<>(result, mchApplyment);
    }
}
