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

import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.converter.MchInfoConverter;
import com.jeequan.jeepay.core.beans.RequestKitBean;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.MchApplyment;
import com.jeequan.jeepay.core.interfaces.paychannel.IIsvmchApplymentNotifyService;
import com.jeequan.jeepay.core.model.params.zftpay.ZftpayIsvParams;
import com.jeequan.jeepay.db.entity.MchModifyApplymentEntity;
import com.jeequan.jeepay.service.impl.MchApplymentService;
import com.jeequan.jeepay.service.impl.MchModifyApplymentService;
import com.jeequan.jeepay.thirdparty.service.ConfigContextQueryService;
import org.apache.commons.lang3.tuple.MutablePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.Charset;

/**
 *
 * @author deng
 * @since 2024/4/7
 */
@Service
public class ZftpayIsvmchApplymentNotifyService implements IIsvmchApplymentNotifyService {

    @Autowired
    private RequestKitBean requestKitBean;

    @Autowired
    private MchApplymentService mchApplymentService;

    @Autowired
    private MchModifyApplymentService mchModifyApplymentService;

    @Autowired
    private ConfigContextQueryService configContextQueryService;

    @Autowired
    private MchInfoConverter mchInfoConverter;

    @Override
    public MutablePair<String, Object> parseParams(HttpServletRequest request, String urlApplyId) {
        JSONObject reqParamJSON = requestKitBean.getReqParamJSON();

        JSONObject bizContent = reqParamJSON.getJSONObject("biz_content");
        String orderId = bizContent.getString("order_id");

        com.jeequan.jeepay.db.entity.MchApplyment mchApplymentEntity = mchApplymentService.getByOrderId(orderId);
        MchApplyment mchApplyment;

        ZftpayIsvParams isvParams;
        if (mchApplymentEntity != null) {
            // 商户进件
            mchApplyment = mchInfoConverter.toModel(mchApplymentEntity);
        } else {
            // 商户信息变更
            MchModifyApplymentEntity mchModifyApplymentEntity = mchModifyApplymentService.getByOrderId(orderId, CS.IF_CODE.ZFTPAY);
            mchApplymentEntity = mchApplymentService.getById(mchModifyApplymentEntity.getApplyId());
            mchApplyment = mchInfoConverter.toModel(mchApplymentEntity);
        }

        Assert.notNull(mchApplyment, "未获取到商户信息");

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

        Charset charset = Charset.forName(reqParamJSON.getString("charset"));
        ZftpayKit.syncCheckSign(reqParamJSON, isvParams, charset);

        return new MutablePair<>(mchApplyment.getApplyId(), reqParamJSON);
    }

    @Override
    public MutablePair<MchApplyment, ResponseEntity> doNotify(HttpServletRequest request, Object params, MchApplyment mchApplyment) {
        JSONObject callbackData = (JSONObject) params;
        String msgMethod = callbackData.getString("msg_method");

        JSONObject bizContent = callbackData.getJSONObject("biz_content");
        String orderId = bizContent.getString("order_id");

        MchApplyment result = new MchApplyment();
        result.setApplyId(mchApplyment.getApplyId());
        result.setState(mchApplyment.getState());

        com.jeequan.jeepay.db.entity.MchApplyment mchApplymentEntity = mchApplymentService.getByOrderId(orderId);
        if (mchApplymentEntity == null) {
            // 商户信息变更
            return processMchModifyApplymentCallback(orderId, msgMethod, bizContent);
        } else {
            // 进件回调
            return processMchApplymentCallback(result, msgMethod, bizContent);
        }
    }

    private MutablePair<MchApplyment, ResponseEntity> processMchApplymentCallback(MchApplyment result, String msgMethod, JSONObject bizContent) {
        // ... 进件回调处理逻辑 ...
        result.setChannelVar1(bizContent.toJSONString());

        if ("ant.merchant.expand.indirect.zft.passed".equals(msgMethod)) {
            // 进件通过
            String smid = bizContent.getString("smid");
            String memo = bizContent.getString("memo");
            result.setState(MchApplyment.STATE_SUCCESS);
            result.setChannelMchNo(smid);
            result.setRemark("[" + memo + "]");

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

        if ("ant.merchant.expand.indirect.zft.rejected".equals(msgMethod)) {
            // 进件驳回
            String reason = bizContent.getString("reason");
            result.setState(MchApplyment.STATE_REJECT_WAIT_MODIFY);
            result.setApplyErrorInfo("[" + reason + "]");
            return new MutablePair<>(result, retOk(null));
        }

        return null;
    }

    private MutablePair<MchApplyment, ResponseEntity> processMchModifyApplymentCallback(String orderId, String msgMethod, JSONObject bizContent) {
        // ... 商户信息变更回调处理逻辑 ...
        MchModifyApplymentEntity modifyResult = new MchModifyApplymentEntity();

        MchModifyApplymentEntity mchModifyApplymentEntity = mchModifyApplymentService.getByOrderId(orderId, CS.IF_CODE.ZFTPAY);
        modifyResult.setModifyApplyId(mchModifyApplymentEntity.getModifyApplyId());
        modifyResult.setChannelVar1(bizContent.toJSONString());

        if ("ant.merchant.expand.indirect.zft.passed".equals(msgMethod)) {
            // 变更成功
            String smid = bizContent.getString("smid");
            String memo = bizContent.getString("memo");
            modifyResult.setState(MchApplyment.STATE_SUCCESS);
            modifyResult.setChannelMchNo(smid);
            modifyResult.setRemark("[" + memo + "]");

            mchModifyApplymentService.localModify(mchInfoConverter.toModel(mchModifyApplymentEntity));
            return new MutablePair<>(null, retOk(null));
        }

        if ("ant.merchant.expand.indirect.zft.rejected".equals(msgMethod)) {
            // 变更失败
            String reason = bizContent.getString("reason");
            modifyResult.setState(MchApplyment.STATE_REJECT_WAIT_MODIFY);
            modifyResult.setApplyErrorInfo("[" + reason + "]");
            return new MutablePair<>(null, retOk(null));
        }

        return null;
    }

    @Override
    public ResponseEntity<?> retOk(Object params) {
        return ResponseEntity.ok("success");
    }
}
