package cn.pluss.platform.task;

import cn.pluss.platform.MerchantAuditRecordService;
import cn.pluss.platform.dto.AccountDTO;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.mapper.*;
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.subMerchant.SubMerchantService;
import cn.pluss.platform.user.impl.GeneralPushUtil;
import cn.pluss.platform.util.IpUtils;
import cn.pluss.platform.util.LogExceptionUtils;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
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.dao.DuplicateKeyException;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.Map;

@Slf4j
@Component
@RequiredArgsConstructor
public class RyxMerAuditHandler {

    private final RestTemplate restTemplate;
    private final UserAppMapper userAppMapper;
    private final UserInfoMapper userInfoMapper;
    private final MerchantStoreMapper merchantStoreMapper;
    private final MerchantImageMapper merchantImageMapper;
    @Setter(onMethod_ = {@Lazy, @Autowired})
    private MerchantChannelStatusMapper mcsMapper;
    @Setter(onMethod_ = {@Lazy, @Autowired})
    private MerchantBaseInfoService merchantBaseInfoService;
    @Setter(onMethod_ = {@Autowired})
    private MerchantAuditRecordService merchantAuditRecordService;
    @Setter(onMethod_ = {@Autowired})
    private RyxService ryxService;
    @Setter(onMethod_ = {@Autowired})
    private MerchantChannelStatusService channelStatusService;
//    @Setter(onMethod_ = {@Autowired})
//    private PluginService ryxSfbPluginService;

    @Autowired
    private NoticeService noticeService;

    private final MerchantCashPlaceService cashPlaceService;

    @Autowired
    @Lazy
    private SxfMerAuditHandler sxfMerAuditHandler;

    @Autowired
    private MercIncomSetRateHandler mercIncomSetRateHandler;

    @Autowired
    @Lazy
    private RyxMerAuditHandler self;

    @Autowired
    private AccountService accountService;

    @Autowired
    private SubMerchantService subMerchantService;

    @Autowired
    private GeneralPushUtil generalPushUtil;


    @Async
    public void auditHandler(JSONObject auditResult) {
        log.info("进件回调数据：{}", auditResult.toJSONString());

        execute(auditResult);

        // 商户插件进件处理
//        ryxSfbPluginService.auditCallback(auditResult);
    }

    private void execute(JSONObject auditResult) {
        // 进件结果处理
        MerchantChannelStatus mcs = self.auditCallback(auditResult);
        if (mcs == null) {
            return;
        }

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

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

    @Transactional(rollbackFor = Exception.class)
    public MerchantChannelStatus auditCallback(JSONObject auditResult) {
        String applicationId = auditResult.getString("orderId").replace("-", "");

        MerchantChannelStatus mcs = new MerchantChannelStatus()
                .setChannel(3)
                .setApplicationId(applicationId);
        mcs = mcsMapper.selectOne(new QueryWrapper<>(mcs));
        if (mcs == null) {
            // 如果不是商户进件，即为插件进件
            return null;
        }

        String currentThirdStatus = mcs.getThirdStatus();

        if (MerchantChannelStatus.AUDIT_STATUS_SUCCESS.equals(mcs.getStatus())) {
            // 已经进件通过, 不再处理后续
            return mcs;
        }

        String taskStatus = auditResult.getString("status");
        String remark = auditResult.getString("memo");

        mcs.setThirdStatus(taskStatus);

        UserApp userApp = userAppMapper.selectByMerchantCode(mcs.getMerchantCode());
        // 暂时只处理成功和失败的状态

        if ("3".equals(taskStatus)) {
            String onlMerId = auditResult.getString("onlMerId");
            // 进件成功
            if (auditResult.getString("wxMerId") != null) {
                try {
                    // 保存微信子商户信息
                    SubMerchant subMerchant = new SubMerchant();
                    subMerchant.setMerchantId(onlMerId);
                    subMerchant.setSubMchType("WX");
                    subMerchant.setStatus(auditResult.getString("wxStatus"));
                    subMerchant.setChannelTypeId("3");
                    subMerchant.setRemark(auditResult.getString("wxResult"));
                    subMerchant.setSubMchId(auditResult.getString("wxMerId"));
                    subMerchantService.save(subMerchant);
                } catch (DuplicateKeyException e) {
                    log.warn("相同的微信子商户号, 不需要重复保存");
                } catch (Exception e) {
                    e.printStackTrace();
                    log.warn("保存微信子商户号错误");
                }
            }

            if (auditResult.getString("zfbMerId") != null) {
                try {
                    // 保存支付宝子商户信息
                    SubMerchant subMerchant = new SubMerchant();
                    subMerchant.setMerchantId(onlMerId);
                    subMerchant.setSubMchType("ZFB");
                    subMerchant.setStatus(auditResult.getString("zfbStatus"));
                    subMerchant.setChannelTypeId("3");
                    subMerchant.setRemark(auditResult.getString("zfbResult"));
                    subMerchant.setSubMchId(auditResult.getString("zfbMerId"));
                    subMerchantService.save(subMerchant);
                } catch (DuplicateKeyException e) {
                    log.warn("相同的支付宝子商户号, 不需要重复保存");
                } catch (Exception e) {
                    e.printStackTrace();
                    log.warn("保存支付宝子商户号错误");
                }
            }

            mcs.setStatus("3");
            mcs.setCallbackStatus("1");
            mcs.setMerchantId(onlMerId);
            mcs.setExtra(auditResult);
            mcs.setRemark("通过");
            channelStatusService.updateById(mcs);
            sxfMerAuditHandler.sendNotice(userApp, "收银呗审核通知", "商家审核通过", applicationId + "_" + System.currentTimeMillis());

            //TODO 统计当前进件商户的上级商户是否满足费率要求
            try {
                mercIncomSetRateHandler.installSuperMerchantRate(userApp);
            } catch (Exception e) {
                log.info("设置进件商户上级商户费率异常，异常信息:{}", e.getMessage());
            }
        }

        if ("4".equals(taskStatus)) {
            // 进件失败
            mcs.setStatus("2");
            mcs.setCallbackStatus("1");
            mcs.setRemark(remark);
            channelStatusService.updateById(mcs);
            sxfMerAuditHandler.sendNotice(userApp, "收银呗审核通知", remark, applicationId + "_" + System.currentTimeMillis());
        }

        boolean isCurrentSign = mcs.getStatus().equals(MerchantChannelStatus.AUDIT_STATUS_WAITING_SIGN);
        isCurrentSign = isCurrentSign || ("1".equals(mcs.getStatus()) && "5".equals(currentThirdStatus));
        if ("5".equals(taskStatus) && !isCurrentSign) {
            // 待签约状态
            mcs.setExtra(auditResult);
            mcs.setStatus(MerchantChannelStatus.AUDIT_STATUS_WAITING_SIGN);
            channelStatusService.updateById(mcs);

            MerchantBaseInfo mbi = merchantBaseInfoService.getMerchantBaseInfoByMerchantCode(mcs.getMerchantCode());
            AccountDTO account = accountService.getAccount(userApp.getUserId() + "");
            String merName;
            if ("1".equals(mbi.getMerchantType())) {
                merName = "商户" + account.getIdcard().getCertName();
            } else {
                merName = mbi.getBussAuthName();
            }

            try {
                merName = URLEncoder.encode(merName, "UTF-8");
            } catch (UnsupportedEncodingException ignored) {

            }

            Notice notice = new Notice();
            String uniqueKey = "RYX_QY" + System.currentTimeMillis();
            String title = "电子协议签约通知";
            String content = "尊敬的客户您好，请点此通知完成签约意愿授权。请注意，同意授权后，支付通道才会进行商户资料审核，否则会一直等待审核。";
            String urlTemplate = "https://rjp.ruiyinxin.com/mims2/ruijiaSign/index.html?merInId=%s&merName=%s";
            String url = String.format(urlTemplate, auditResult.getString("merInId"), merName);
            notice.setUniqueKey(uniqueKey);
            notice.setUserId(userApp.getUserId() + "");
            notice.setNoticeCode(uniqueKey);
            notice.setTypeFirst(1);
            notice.setTypeSecond(-1);
            notice.setTitle(title);
            notice.setUrl(url);
            notice.setDesc(content);
            noticeService.save(notice);

            generalPushUtil.sendAllPlatByAlias(Collections.singletonList(userApp.getUserId() + ""), title, content, "1");
        }

        MerchantAuditRecord lastRecord = merchantAuditRecordService.getLastRecord(mcs.getMerchantCode());
        if (lastRecord != null) {
            lastRecord.setStatus(mcs.getStatus());
            lastRecord.setThirdStatus(mcs.getThirdStatus());
            lastRecord.setRemark(auditResult.getString("memo"));
            merchantAuditRecordService.updateById(lastRecord);
        }

        return mcs;
    }

    public void createStore(MerchantChannelStatus merchantChannelStatus) {
        UserApp userApp = userAppMapper.selectByMerchantCode(merchantChannelStatus.getMerchantCode());
        UserInfo userInfo = userInfoMapper.selectById(userApp.getUserId());
        log.info("==============>当前需要同步的用户进件数据为：:{}<===================", JSONObject.toJSONString(merchantChannelStatus));
        if (userInfo != null) {
            MerchantStore merchantStore = new MerchantStore().setMerchantCode(merchantChannelStatus.getMerchantCode());
            merchantStore = merchantStoreMapper.selectOne(new QueryWrapper<>(merchantStore));
            MerchantBaseInfo merchantBaseInfo = merchantBaseInfoService.getMerchantBaseInfoByMerchantCode(merchantChannelStatus.getMerchantCode());
            QueryWrapper<MerchantImage> queryWrapper = new QueryWrapper<MerchantImage>()
                    .eq("merchantCode", merchantChannelStatus.getMerchantCode()).eq("photoType", "06");
            MerchantImage merchantImage = merchantImageMapper.selectOne(queryWrapper);
            String baseUrl = "https://life.sxczgkj.cn/web/wmerchant.php?c=site&a=entry&ctrl=store&ac=oauth&op=add_merchan&do=web&m=we7_wmall&i=1";
            StringBuffer sb = new StringBuffer(baseUrl);
            sb.append("&title=").append(merchantBaseInfo.getAlias());
            sb.append("&password=").append(userInfo.getPassword().toLowerCase());
            sb.append("&mobile=").append(userInfo.getLoginName());
            sb.append("&syb_m_id=").append(merchantStore.getId());
            String address = merchantBaseInfo.getProvince() + merchantBaseInfo.getCity() + merchantBaseInfo.getDistrict() + merchantBaseInfo.getAddress();
            String addressNo = merchantBaseInfo.getAddressNo();
            sb.append("&addressNo=").append(addressNo);
            String area = merchantBaseInfo.getProvince() +"-"+ merchantBaseInfo.getCity() +"-"+ merchantBaseInfo.getDistrict();
            try {
                String decodeAddress = URLEncoder.encode(address, "UTF-8");
                sb.append("&address=").append(decodeAddress);
                String decodeArea = URLEncoder.encode(area, "UTF-8");
                sb.append("&area=").append(decodeArea);
                String logo = URLEncoder.encode(merchantImage.getPicUrl(), "GBK");
                sb.append("&logo=").append(logo);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                log.error("=============>请求生成店铺logo门头照转码异常,异常信息:{}<===============", e.getMessage());
            }
            Map<String, String> lnxMap = IpUtils.getLocationByAddress(address);
            if (lnxMap != null) {
                sb.append("&location_x=").append(lnxMap.get("x"));
                sb.append("&location_y=").append(lnxMap.get("y"));
            }
            // 请求生成店铺j
            String result = restTemplate.getForObject(sb.toString(), String.class);
            log.info("=============>请求生成店铺URL：{}，请求响应返回的参数为:{}<===============", sb.toString(), result);
        }
    }
}
