package cn.pluss.platform.ryx.impl;

import cn.pluss.platform.SubMerchantApplyOrderService;
import cn.pluss.platform.channel.MerchantCertService;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.merchant.MerchantPluginService;
import cn.pluss.platform.merchant.MerchantBaseInfoService;
import cn.pluss.platform.merchantChannelStatus.MerchantChannelStatusService;
import cn.pluss.platform.notice.NoticeService;
import cn.pluss.platform.ryx.RyxConstants;
import cn.pluss.platform.ryx.RyxService;
import cn.pluss.platform.userApp.UserAppService;
import cn.pluss.platform.user.impl.GeneralPushUtil;
import cn.pluss.platform.util.OssOperatUtil;
import cn.pluss.platform.util.RyxConfig;
import cn.pluss.platform.util.SendMsgUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.util.*;

/**
 * @author DJH
 */
@Slf4j
@Service("ryxCertService")
public class RyxCertServiceImpl implements MerchantCertService {

    @Setter(onMethod_ = {@Autowired})
    private MerchantChannelStatusService mcsService;

    @Setter(onMethod_ = {@Autowired})
    private MerchantPluginService merchantPluginService;

    @Setter(onMethod_ = {@Autowired})
    private SubMerchantApplyOrderService merchantApplyOrderService;

    @Setter(onMethod_ = {@Autowired})
    private RyxService ryxService;

    @Setter(onMethod_ = {@Autowired})
    private NoticeService noticeService;

    @Setter(onMethod_ = {@Autowired,@Lazy})
    private UserAppService userAppService;

    @Setter(onMethod_ = {@Autowired})
    private SendMsgUtil sendMsgUtil;

    @Setter(onMethod_ = {@Autowired})
    private MerchantBaseInfoService merchantBaseInfoService;

    @Autowired
    private GeneralPushUtil generalPushUtil;

    @Override
    public void wxCert(String merchantId, String merchantCode) {
        // 不需要进行微信认证
    }

    @Override
    public void wxReCert(String merchantId, String merchantCode) {
        // 不需要进行微信认证
    }

    /**
     * 通过商户编码查询商户信息，并获得微信认证结果
     *
     * eg. 微信认证json
     * {
     * 	 "applymentState": "待确认联系信息",
     * 	 "rejectReason": "请扫描微信支付返回的小程序码确认联系信息。",
     * 	 "certificationType": "1",
     * 	 "docId": "",
     * 	 "qrcodeData": "data:image/png;base64,[encoded data, 15240 characters]",
     * 	 "contactPersonCred": "4212**************",
     * 	 "docPath": ""
     * }
     * @param merchantId 商户编号
     */
    @Override
    public JSONObject wxCertResult(String merchantId, String wxApplyNo) {
        // 查询商户微信认证结果
        wxCertResultMain(merchantId);
        // 查询商户插件微信认证结果
//        wxCertResultPlugin(merchantId);

        return null;
    }

    @Override
    public JSONObject wxCertCallback(JSONObject certResult) {
        // 不存在回调
        return null;
    }

    @Override
    public void wxCertCancel(String merchantId, SubMerchantApplyOrder subMerchantApplyOrder) {
        // 不需要主动进行微信认证
    }

    private void wxCertResultMain(String merchantId) {
        MerchantChannelStatus existData = new MerchantChannelStatus();
        existData.setChannel(3);
        existData.setMerchantId(merchantId);

        existData = mcsService.getOne(new QueryWrapper<>(existData));
        if (existData == null) {
            return;
        }

        UserApp userApp = new UserApp();
        userApp.setMerchantCode(existData.getMerchantCode());
        userApp.setUserType("promoter");
        userApp = userAppService.queryUserApp(userApp);

        JSONObject extra = existData.getExtra();
        // 瑞银信内部进件序号
        String merInId = extra.getString(RyxConstants.MER_IN_ID);

        Map<String, Object> map = new HashMap<>();
        map.put("merInId", merInId);

        RyxAccessResp resp = ryxService.reqCommon(map, null, RyxConfig.merchantInfo);
        log.debug("解密出的商户信息===== \n{}", JSON.toJSONString(resp));

        resultProcess(userApp, 3, resp);
    }

//    private void wxCertResultPlugin(String merchantId) {
//        MerchantPlugin merchantPlugin = new MerchantPlugin();
//        merchantPlugin.setChannel(RyxSfbPluginServiceImpl.SFB_PLUGIN_CHANNEL);
//        merchantPlugin.setPluginId(merchantId);
//        merchantPlugin = merchantPluginService.getOne(new QueryWrapper<>(merchantPlugin));
//
//        if (merchantPlugin == null) {
//            return;
//        }
//
//        UserApp userApp = new UserApp();
//        userApp.setUserId(merchantPlugin.getUserId().longValue());
//        userApp = userAppService.queryUserApp(userApp);
//
//        JSONObject extra = merchantPlugin.getExtra();
//        // 瑞银信内部进件序号
//        String merInId = extra.getString(RyxConstants.MER_IN_ID);
//
//        Map<String, Object> map = new HashMap<>();
//        map.put("merInId", merInId);
//
//        RyxAccessResp resp = ryxService.reqSfbCommon(map, null, RyxConfig.merchantInfo);
//        log.debug("解密出的商户信息===== \n{}", JSON.toJSONString(resp));
//
//        resultProcess(userApp, RyxSfbPluginServiceImpl.SFB_PLUGIN_CHANNEL, resp);
//    }

    private void resultProcess(UserApp userApp, int channelId, RyxAccessResp resp) {
        JSONObject wxCertificationInfo = resp.getResult().getJSONObject("wxCertificationInfo");

        SubMerchantApplyOrder subMerApplyOrder = new SubMerchantApplyOrder();
        subMerApplyOrder.setChannelId(channelId);
        subMerApplyOrder.setMerchantCode(userApp.getMerchantCode());
        QueryWrapper<SubMerchantApplyOrder> qW = new QueryWrapper<>(subMerApplyOrder).orderByDesc("createTime").last("limit 1");
        SubMerchantApplyOrder existApplyOrder = merchantApplyOrderService.getOne(qW);

        String applymentState = wxCertificationInfo.getString("applymentState");
        String rejectReason = wxCertificationInfo.getString("rejectReason");

        if (existApplyOrder != null) {
            subMerApplyOrder = existApplyOrder;

            boolean isSameStatus = StringUtils.isNotBlank(subMerApplyOrder.getResultStatus()) && subMerApplyOrder.getResultStatus().equals(applymentState);
            boolean isSameReason = StringUtils.isNotBlank(subMerApplyOrder.getRemark()) && subMerApplyOrder.getRemark().equals(rejectReason);

            if (isSameStatus && isSameReason) {
                // 如果是一个状态，同一个驳回理由，那么不再处理
                return;
            }
        }

        subMerApplyOrder.setRemark(rejectReason);
        subMerApplyOrder.setSubMchType("WX");
        subMerApplyOrder.setStatus("1");

        subMerApplyOrder.setResultStatus(applymentState);
        String qrcodeData = wxCertificationInfo.getString("qrcodeData");
        String wxAuthorizationStatusName = wxCertificationInfo.getString("wxAuthorizationStatusName");
        if (Objects.equals("已授权", wxAuthorizationStatusName)) {
            LambdaUpdateWrapper<MerchantChannelStatus> uWrapper = Wrappers.lambdaUpdate();
            uWrapper.set(MerchantChannelStatus::getAuthorizationStatus, MerchantChannelStatus.AUTHORIZATION_STATUS_AUTHORIZED);
            uWrapper.eq(MerchantChannelStatus::getMerchantCode, userApp.getMerchantCode())
                    .eq(MerchantChannelStatus::getChannel, channelId);
            mcsService.update(uWrapper);
        }


        Notice notice = new Notice(1, 1, userApp);

        String pushMsg;
        switch (subMerApplyOrder.getResultStatus()) {
            case "审核中":
                pushMsg = subMerApplyOrder.getRemark();
                generalPushUtil.sendAllPlatByAlias(Collections.singletonList(userApp.getUserId().toString()), "商户微信认证通知", pushMsg, "1");
                notice.setConrtent(subMerApplyOrder.getRemark());
                noticeService.saveNotice(notice);
                break;
            case "未提交":
            case "审核驳回":
                pushMsg = "您好！您的商户微信认证因“##”被驳回，请联系收银呗客服修改资料并重新审核";
                pushMsg = pushMsg.replace("##", subMerApplyOrder.getRemark());
                generalPushUtil.sendAllPlatByAlias(Collections.singletonList(userApp.getUserId().toString()), "商户微信认证通知", pushMsg, "1");
                notice.setConrtent(pushMsg);
                noticeService.saveNotice(notice);
                break;
            case "审核通过":
            case "待确认联系信息":
                // 将base64转为inputStream
                qrcodeData = qrcodeData.replace("data:image/png;base64,", "");

                byte[] decode = Base64.getDecoder().decode(qrcodeData);
                ByteArrayInputStream bais = new ByteArrayInputStream(decode);
                String path = OssOperatUtil.upload(bais, UUID.randomUUID().toString(), "png");
                subMerApplyOrder.setInfoQrcode(path);

                String content = "请商户进行" + (channelId == 3? "": "插件") + "微信实名认证，短信将发送至商户联系人手机号，已认证可忽略";
                generalPushUtil.sendAllPlatByAlias(Collections.singletonList(userApp.getUserId().toString()), "商户微信认证通知", content, "1");

                notice.setConrtent(content);
                noticeService.saveNotice(notice);

                QueryWrapper<MerchantBaseInfo> queryWrapper = new QueryWrapper<MerchantBaseInfo>().eq("userId",userApp.getUserId());
                MerchantBaseInfo merchantBaseInfo = merchantBaseInfoService.getOne(queryWrapper);

                try {
                    sendMsgUtil.verifyMsg(merchantBaseInfo.getContactMobile(), userApp.getMerchantCode() + "?i=" + channelId);
                } catch (MsgException e) {
                    log.error(e.getMessage());
                }
                break;
            default:
                // 未提交、已作废 等不做处理
                break;
        }

        merchantApplyOrderService.saveOrUpdate(subMerApplyOrder);
    }

    @Override
    public void wxCertAuthStatus(String merchantId) {
        MerchantChannelStatus mcs = new MerchantChannelStatus();
        mcs.setMerchantId(merchantId);
        mcs = mcsService.getOne(Wrappers.query(mcs).last("limit 1"));

        JSONObject extra = mcs.getExtra();
        String merInId = extra.getString(RyxConstants.MER_IN_ID);

        Map<String, Object> map = new HashMap<>();
        map.put("merInId", merInId);

        RyxAccessResp merchantInfo = ryxService.reqCommon(map, null, RyxConfig.merchantInfo);
        log.debug("解密出的商户信息=====");
        log.debug(JSON.toJSONString(merchantInfo));

        JSONObject result = merchantInfo.getResult();
        if (result == null) {
            return;
        }

        JSONObject wxCertificationInfo = result.getJSONObject("wxCertificationInfo");
        if (wxCertificationInfo == null) {
            return;
        }

        String wxAuthorizationStatusName = wxCertificationInfo.getString("wxAuthorizationStatusName");
        if ("已授权".equals(wxAuthorizationStatusName)) {
            LambdaUpdateWrapper<MerchantChannelStatus> uWrapper = Wrappers.lambdaUpdate();
            uWrapper.set(MerchantChannelStatus::getAuthorizationStatus, MerchantChannelStatus.AUTHORIZATION_STATUS_AUTHORIZED);
            uWrapper.eq(MerchantChannelStatus::getId, mcs.getId());
            mcsService.update(uWrapper);
        }
    }
}
