package com.jeequan.jeepay.pay.ctrl.applyment;

import com.jeequan.jeepay.components.mq.model.MchAuditThirdNotifyMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.converter.MchInfoConverter;
import com.jeequan.jeepay.core.ctrls.AbstractCtrl;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.exception.ResponseException;
import com.jeequan.jeepay.core.interfaces.paychannel.IIsvmchApplymentNotifyService;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.MchApplyment;
import com.jeequan.jeepay.service.impl.MchApplymentService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.MutablePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;

/**
 * 进件接口渠道侧的通知入口Controller
 *
 * @author terrfly
 * @date 2022/1/8 15:26
 */
@Slf4j
@Controller
public class MchApplymentChannelNotifyController extends AbstractCtrl {

    @Autowired
    private MchApplymentService mchApplymentService;

    @Autowired
    private IMQSender mqSender;

    @Autowired
    private MchInfoConverter mchInfoConverter;

    /**
     * 异步回调入口
     *
     * @param request
     * @param ifCode
     * @param customApplyId 通道方返回的参数，一般来说，该值由我方自定义。若回调地址不可变更，该参数将不存在
     * @return
     */
    @ResponseBody
    @RequestMapping(value = {"/api/mchApplyment/notify/{ifCode}", "/api/mchApplyment/notify/{ifCode}/{customApplyId}"})
    public ResponseEntity doNotify(HttpServletRequest request, @PathVariable("ifCode") String ifCode, @PathVariable(value = "customApplyId", required = false) String customApplyId) {

        String applyId = null;
        String logPrefix = "进入[" + ifCode + "]进件回调：urlApplyId：[" + StringUtils.defaultIfEmpty(customApplyId, "") + "] ";
        log.info("===== {} =====", logPrefix);

        IIsvmchApplymentNotifyService notifyService = null;
        try {

            // 参数有误
            if (StringUtils.isEmpty(ifCode)) {
                return ResponseEntity.badRequest().body("ifCode is empty");
            }

            //查询支付接口是否存在
            notifyService = SpringBeansUtil.getBean(ifCode + "IsvmchApplymentNotifyService", IIsvmchApplymentNotifyService.class);

            // 解析申请单号 和 请求参数
            MutablePair<String, Object> mutablePair = notifyService.parseParams(request, customApplyId);
            if (mutablePair == null) { // 解析数据失败， 响应已处理
                log.error("{}, mutablePair is null ", logPrefix);
                throw new BizException("解析数据异常！"); //需要实现类自行抛出ResponseException, 不应该在这抛此异常。
            }

            //解析到订单号
            applyId = mutablePair.left;
            log.info("{}, 解析数据为：applyId:{}, params:{}", logPrefix, applyId, mutablePair.getRight());

            //获取进件数据 和 订单数据
            MchApplyment dbTbMchApplyment = mchApplymentService.getById(applyId);

            // 订单不存在
            if (dbTbMchApplyment == null) {
                log.error("{}, 进件数据不存在. applyId={} ", logPrefix, applyId);
                return ResponseEntity.ok("SUCCESS");
            }

            // 状态不是待审核, 先去掉看看效果
//            if(dbTbMchApplyment.getState() != MchApplyment.STATE_AUDITING){
//                log.error("{}, 进件状态不是审核中. applyId={}, state={}", logPrefix, applyId, dbTbMchApplyment.getState());
//                return notifyService.retOk(mutablePair.getRight());
//            }

            //调起接口的回调判断
            MutablePair<com.jeequan.jeepay.core.entity.MchApplyment, ResponseEntity> notifyResult = notifyService.doNotify(request, mutablePair.getRight(), mchInfoConverter.toModel(dbTbMchApplyment));

            if (notifyResult.left == null) {
                return notifyService.retOk(null);
            }

            MchApplyment result = mchInfoConverter.toDbEntity(notifyResult.left);
            result.setApplyId(dbTbMchApplyment.getApplyId());
            mchApplymentService.updateById(result);

            // 自动配置商户应用参数，进件成功 && 状态发生变化 && 自动配置应用不为空
            if ((result.getState() == MchApplyment.STATE_SUCCESS || result.getState() == MchApplyment.STATE_SUCCESS_NEED_SECOND_VERIFY) && !result.getState().equals(dbTbMchApplyment.getState())) {

                mchApplymentService.onApplymentSuccess(result.getApplyId());
                mqSender.send(MchAuditThirdNotifyMQ.build(result.getApplyId(), MchAuditThirdNotifyMQ.TYPE_AUDIT));
            }

            log.info("===== {}, 进件通知完成。 applyId={}, parseState = {} =====", logPrefix, applyId, result.getState());
            return notifyService.retOk(mutablePair.getRight());

        } catch (BizException e) {
            log.error("{}, applyId={}, BizException", logPrefix, applyId, e);

            if (notifyService != null) {
                return notifyService.retOk(null);
            }
        } catch (ResponseException e) {
            log.error("{}, applyId={}, ResponseException", logPrefix, applyId, e);

            if (notifyService != null) {
                return notifyService.retOk(null);
            }

        } catch (Exception e) {
            log.error("{}, applyId={}, 系统异常", logPrefix, applyId, e);

            if (notifyService != null) {
                return notifyService.retOk(null);
            }
        }

        return ResponseEntity.ok("SUCCESS");
    }

}
