package cn.pluss.platform.job;

import cn.pluss.platform.BankCardService;
import cn.pluss.platform.channel.MerchantAuditService;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.merchant.AccountService;
import cn.pluss.platform.merchant.MerchantBaseInfoService;
import cn.pluss.platform.merchant.MerchantCashPlaceService;
import cn.pluss.platform.merchantChannelStatus.MerchantChannelStatusService;
import cn.pluss.platform.notice.NoticeService;
import cn.pluss.platform.ryx.RyxService;
import cn.pluss.platform.sxf.SxfService;
import cn.pluss.platform.task.RyxMerAuditHandler;
import cn.pluss.platform.task.SxfMerAuditHandler;
import cn.pluss.platform.user.impl.GeneralPushUtil;
import cn.pluss.platform.util.LogExceptionUtils;
import cn.pluss.platform.util.RyxConfig;
import cn.pluss.platform.util.SxfConfg;
import cn.pluss.platform.yinsheng.v20210929.ReqMethod;
import cn.pluss.platform.ys.impl.v20210929.YsConfigV2;
import cn.pluss.platform.ys.impl.v20210929.YsServiceV2;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.*;

/**
 * 定时任务查询进件状态
 */
@Slf4j
@Configuration
@ConditionalOnProperty(prefix = "scheduling", name = "enabled", havingValue = "true")
public class CheckMerchAuditStatusJob {

    public static final int MAX_SIZE = 100;

    @Autowired
    @Lazy
    private SxfMerAuditHandler sxfMerAuditHandler;

    @Autowired
    private MerchantBaseInfoService mbiService;

    @Autowired
    private AccountService accountService;

    @Autowired
    private BankCardService bankCardService;

    @Autowired
    private MerchantChannelStatusService mcsService;

    @Autowired
    private MerchantAuditService ysAuditService;

    @Autowired
    private YsServiceV2 ysServiceV2;

    @Autowired
    private MerchantAuditService ysAuditServiceV2;

    @Autowired
    private SxfService sxfService;

    @Autowired
    private RyxService ryxService;

    @Autowired
    private MerchantAuditService ryxMerchantAuditService;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private RyxMerAuditHandler ryxMerAuditHandler;

    @Autowired
    private NoticeService noticeService;

    @Autowired
    @Lazy
    private MerchantCashPlaceService cashPlaceService;

    @Autowired
    private GeneralPushUtil generalPushUtil;

    public void process() {
        checkSxfMerchEditStatus();

        checkRyxMerchEditStatus();

        checkYsMerchStatusV2();

        checkYsMerchEditStatus();

        checkRyxMerchStatus();
    }

    /**
     * 查询随行付银行卡修改结果
     */
    @Scheduled(fixedDelay = 3 * 60 * 1000)
    public void checkSxfMerchEditStatus() {
        log.info("======开始查询随行付商户修改结果======");
        MerchantChannelStatus mcsCondition = new MerchantChannelStatus();
        mcsCondition.setStatus(MerchantChannelStatus.AUDIT_STATUS_DATA_EDIT);
        mcsCondition.setChannel(1);
        List<MerchantChannelStatus> mcsList = mcsService.list(new QueryWrapper<>(mcsCondition));

        for (MerchantChannelStatus mcs : mcsList) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            try {
                JSONObject param = new JSONObject();
                param.put("applicationId", mcs.getApplicationId());
                JSONObject result = sxfService.requestApi(SxfConfg.SXF_UPDATE_MERCHANT_INFO_RESULT, param);

                try {
                    sxfService.checkSign(result);
                } catch (Exception e) {
                    log.error("验签异常");
                    MsgException.throwException(e.getMessage());
                }

                String reqId = result.getString("reqId");

                if (!Objects.equals(SxfConfg.SXF_SUCCESS_CODE, result.get("code"))) {
                    String msg = result.getString("msg");
                    log.error("查询随行付修改结果异常: {}", msg);
                }

                JSONObject respData = result.getJSONObject("respData");
                if (!Objects.equals(SxfConfg.SXF_SUCCESS_CODE, respData.get("bizCode"))) {
                    String msg = result.getString("bizMsg");
                    log.error("查询随行付修改结果异常: {}", msg);
                }

                String taskStatus = respData.getString("taskStatus");

                if (Objects.equals(taskStatus, "5")) {
                    // 修改成功
                    accountService.editSuccess(mcs, Account.CHANNEL_TYPE_D1);
                }

                if (Objects.equals(taskStatus, "6")) {
                    // 修改失败
                    accountService.editFail(mcs, reqId + "_" + System.currentTimeMillis(), result.getString("suggestion"), Account.CHANNEL_TYPE_D1);
                }

            } catch (Exception e) {
                log.info("查询随行付修改结果异常");
            }
        }

        log.info("======结束查询随行付商户修改结果======");
    }

    /**
     * 查询瑞银信商户进件修改的状态
     */
    @Scheduled(fixedDelay = 3 * 60 * 1000)
    public void checkRyxMerchEditStatus() {
        log.info("======开始查询瑞银信商户修改结果======");
        MerchantChannelStatus mcsCondition = new MerchantChannelStatus();
        mcsCondition.setStatus(MerchantChannelStatus.AUDIT_STATUS_DATA_EDIT);
        mcsCondition.setChannel(3);
        List<MerchantChannelStatus> mcsList = mcsService.list(new QueryWrapper<>(mcsCondition));

        for (MerchantChannelStatus mcs : mcsList) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                JSONObject param = new JSONObject();
                String merInId = mcs.getExtra().getString("merInId");
                param.put("merInId", merInId);
                param.put("flag", "1");

                RyxAccessResp resp = ryxService.reqCommon(param, null, RyxConfig.merchantInfo);
                JSONObject result = resp.getResult();

                JSONObject merchBase = result.getJSONObject("merchBase");

                String merStatus = merchBase.getString("merStatus");

                String reason = merchBase.getString("finalAuditNoMemo");

                if (Objects.equals("00", merStatus)) {
                    // 审核通过
                    accountService.editSuccess(mcs, Account.CHANNEL_TYPE_D1);
                }

                if (Objects.equals("32", merStatus)) {
                    // 修改失败
                    accountService.editFail(mcs, UUID.randomUUID().toString().replace("-", "") + "_" + System.currentTimeMillis(), reason, Account.CHANNEL_TYPE_D1);
                }

            } catch (Exception e) {
                log.info("查询随行付修改结果异常");
            }
        }

        log.info("======结束查询瑞银信商户修改结果======");
    }

    /**
     * 查询瑞银信进件商户的状态
     */
    @Scheduled(fixedDelay = 3 * 60 * 1000)
    public void checkRyxMerchStatus() {
        log.info("==========查询瑞银信商户进件状态开始==========");
        LambdaQueryWrapper<MerchantChannelStatus> qW = Wrappers.lambdaQuery();
        qW.in(MerchantChannelStatus::getStatus, MerchantChannelStatus.AUDIT_STATUS_EXAMINING, MerchantChannelStatus.AUDIT_STATUS_WAITING_SIGN)
                .eq(MerchantChannelStatus::getChannel, 3)
                .ne(MerchantChannelStatus::getThirdStatus, MerchantChannelStatus.AUDIT_THIRD_STATUS_WAITING)
                .orderByDesc(MerchantChannelStatus::getUpdateTime)
                .last("limit " + MAX_SIZE);

        List<MerchantChannelStatus> mcsList = mcsService.list(qW);

        for (MerchantChannelStatus mcs : mcsList) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            String applicationId = mcs.getApplicationId();
            if (StringUtils.isBlank(applicationId)) {
                continue;
            }

            // 拼接成真正的orderId
            String orderId = applicationId.substring(0, 8) + "-" +
                    applicationId.substring(8, 12) + "-" +
                    applicationId.substring(12, 16) + "-" +
                    applicationId.substring(16, 20) + "-" +
                    applicationId.substring(20);

            try {
                Map<String, Object> param = new HashMap<>();
                param.put("orderId", orderId);
                JSONObject jsonObject = ryxMerchantAuditService.merchantAuditResult(param);

                ryxMerAuditHandler.auditCallback(jsonObject);

                MerchantChannelStatus mcsCurrent = mcsService.getById(mcs.getId());

                if (!mcsCurrent.getStatus().equals(MerchantChannelStatus.AUDIT_STATUS_SUCCESS)) {
                    continue;
                }

                // 以下代码为进件结果处理后的操作
                // 创建线上店铺
                try {
                    log.info("===================>进件回调，创建店铺开始,商户编号memo为:{}<=====================", jsonObject.getString("memo"));
                    ryxMerAuditHandler.createStore(mcs);
                } catch (Exception e) {
                    e.printStackTrace();
                    log.info("创建店铺信息异常,异常信息:{}", e.getMessage());
                }

                try {
                    MerchantBaseInfo merchantBaseInfo = mbiService.getMerchantBaseInfoByMerchantCode(mcs.getMerchantCode());
                    if (StringUtils.isNotBlank(merchantBaseInfo.getUserId())) {
                        cashPlaceService.createDefaultCashPlace(Long.parseLong(merchantBaseInfo.getUserId()));
                    }
                } catch (Exception e) {
                    LogExceptionUtils.printStack(log, e, "创建默认收银点失败,异常信息:{}");
                }
            } catch (Exception ignored) {
            }
        }

        log.info("==========查询瑞银信商户进件状态结束==========");
    }

    /**
     * 查询银盛进件商户的状态
     */
    private void checkYsMerchStatus() {
        log.info("==========查询银盛商户进件状态开始==========");
        LambdaQueryWrapper<MerchantChannelStatus> qW = Wrappers.lambdaQuery();
        qW.in(MerchantChannelStatus::getStatus, MerchantChannelStatus.AUDIT_STATUS_EXAMINING, MerchantChannelStatus.AUDIT_STATUS_WAITING_SIGN)
                .eq(MerchantChannelStatus::getChannel, 4)
                .isNull(MerchantChannelStatus::getApplicationId)
                .notIn(MerchantChannelStatus::getThirdStatus, MerchantChannelStatus.AUDIT_THIRD_STATUS_WAITING, MerchantChannelStatus.AUDIT_THIRD_STATUS_AUDITING)
                .orderByDesc(MerchantChannelStatus::getUpdateTime)
                .last("limit " + MAX_SIZE);

        List<MerchantChannelStatus> mcsList = mcsService.list(qW);

        for (MerchantChannelStatus mcs : mcsList) {
            try {
                JSONObject params = new JSONObject();
                params.put("merchantCode", mcs.getMerchantCode());
                ysAuditService.merchantAuditResult(params);
            } catch (Exception e) {
                log.warn("银盛查询商户进件状态失败");
            }
        }
        log.info("==========查询银盛商户进件状态结束==========");
    }

    /**
     * 银盛-云商服进件商户的状态查询
     */
    @Scheduled(fixedDelay = 3 * 60 * 1000)
    public void checkYsMerchStatusV2() {
        log.info("==========查询银盛-云商服商户进件状态开始==========");
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.WEEK_OF_YEAR, -1);
        LambdaQueryWrapper<MerchantChannelStatus> qW = Wrappers.lambdaQuery();
        qW.in(MerchantChannelStatus::getStatus,
                        MerchantChannelStatus.AUDIT_STATUS_EXAMINING,
                        MerchantChannelStatus.AUDIT_STATUS_WAITING_SIGN,
                        MerchantChannelStatus.AUDIT_STATUS_SIGNED)
                .eq(MerchantChannelStatus::getChannel, 4)
                .isNotNull(MerchantChannelStatus::getApplicationId)
                .notIn(MerchantChannelStatus::getThirdStatus,
                        MerchantChannelStatus.AUDIT_THIRD_STATUS_WAITING,
                        MerchantChannelStatus.AUDIT_THIRD_STATUS_AUDITING)
                .orderByDesc(MerchantChannelStatus::getUpdateTime)
                .ge(MerchantChannelStatus::getUpdateTime, calendar.getTime())
                .last("limit " + MAX_SIZE);

        List<MerchantChannelStatus> mcsList = mcsService.list(qW);

        for (MerchantChannelStatus mcs : mcsList) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            JSONObject params = new JSONObject();
            if (mcs.getApplicationId() == null) {
                continue;
            }
            params.put("sysFlowId", mcs.getApplicationId());
            try {
                ysAuditServiceV2.merchantAuditResult(params);
            } catch (Exception e) {
                log.warn("银盛查询商户进件状态失败: {}", e.getMessage());
                e.printStackTrace();
            }
        }
        log.info("==========查询银盛-云商服商户进件状态结束==========");
    }

    /**
     * 银盛-云商服，商户修改信息
     */
    @Scheduled(fixedDelay = 3 * 60 * 1000)
    public void checkYsMerchEditStatus() {
        log.info("==========查询银盛-云商服商户变更状态开始==========");
        LambdaQueryWrapper<MerchantChannelStatus> qWrapper = Wrappers.lambdaQuery();
        qWrapper.eq(MerchantChannelStatus::getStatus, MerchantChannelStatus.AUDIT_STATUS_DATA_EDIT)
                .eq(MerchantChannelStatus::getChannel, 4)
                .last("limit " + MAX_SIZE);

        List<MerchantChannelStatus> editList = mcsService.list(qWrapper);

        for (MerchantChannelStatus mcs : editList) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            String changeFlowId = mcs.getExtra().getString("changeFlowId");

            if (StringUtils.isEmpty(changeFlowId)) {
                continue;
            }

            JSONObject param = new JSONObject();
            param.put("changeFlowId", changeFlowId);

            JSONObject result;
            try {
                result = ysServiceV2.req(YsConfigV2.MER_EDIT_RESULT, ReqMethod.MERCHANT_EDIT_RESULT, param);
            } catch (Exception e) {
                continue;
            }

            String modifyType = result.getString("modifyType");

            transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                @Override
                protected void doInTransactionWithoutResult(TransactionStatus status) {
                    if ("02".equals(modifyType)) {
                        if ("02".equals(result.getString("status"))) {
                            accountService.editSuccess(mcs, Account.CHANNEL_TYPE_D0);
                        }

                        if ("90".equals(result.getString("status"))) {
                            accountService.editFail(mcs, UUID.randomUUID().toString().replace("-", ""), result.getString("remark"), Account.CHANNEL_TYPE_D0);
                        }
                    }
                }
            });
        }
        log.info("==========查询银盛-云商服商户变更状态结束==========");
    }
}
