package cn.pluss.platform.task;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.pluss.platform.BankCardService;
import cn.pluss.platform.MerchantAuditRecordService;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.klk.LaKaLaUtility;
import cn.pluss.platform.klk.LakalaConfig;
import cn.pluss.platform.klk.service.LklPayService;
import cn.pluss.platform.klk.service.impl.LaKalaInterfaceImpl;
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.notice.NoticeService;
import cn.pluss.platform.suixingfu.SxfConstants;
import cn.pluss.platform.user.impl.GeneralPushUtil;
import cn.pluss.platform.userApp.UserAppService;
import cn.pluss.platform.util.IpUtils;
import cn.pluss.platform.util.LogExceptionUtils;
import com.alibaba.fastjson.JSONArray;
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.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
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.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
@RequiredArgsConstructor
public class LklMerAuditHandler {


    @Setter(onMethod_ = {@Lazy, @Autowired})
    private MerchantChannelStatusMapper mcsMapper;

    @Setter(onMethod_ = {@Lazy, @Autowired})
    private MerchantBackLklMapper backLklMapper;


    @Autowired
    @Lazy
    private LklMerAuditHandler self;


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


    @Setter(onMethod_ = {@Autowired, @Lazy})
    private MerchantCashPlaceService cashPlaceService;


    @Setter(onMethod_ = {@Autowired})
    private MerchantAuditRecordService merchantAuditRecordService;


    private final UserAppMapper userAppMapper;
    private final UserInfoMapper userInfoMapper;
    private final MerchantStoreMapper merchantStoreMapper;
    private final MerchantImageMapper merchantImageMapper;

    private final LaKalaInterfaceImpl laKalaInterface;

    private final RestTemplate restTemplate;


    @Lazy
    @Autowired
    private LakalaConfig lakalaConfig;


    @Autowired
    private GeneralPushUtil generalPushUtil;


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

    @Autowired
    private UserAppService uaService;

    @Autowired
    AccountService accountService;

    @Setter(onMethod_ = {@Autowired})
    private BankCardService bankCardService;

    @Autowired
    private MerchantChannelFeeMapper merchantChannelFeeMapper;


    public void auditHandler(Map<String, Object> map) {
        execute(map);
    }


    public void execute(Map<String, Object> map) {

        log.info("拉卡拉开户通知接口返回解密数据:{}", JSONUtil.toJsonStr(map));

        if (ObjectUtil.isEmpty(map) || !map.containsKey("status")) {
            log.error("回调数据为空");
            return;
        }


        MerchantChannelStatus mcs = self.auditCallback(map);

        if (ObjectUtil.isNotEmpty(mcs)) {
            try {

                log.info("===================>进件回调，创建店铺开始,商户编号mno为:{}<=====================", map.get("customerNo").toString());
                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, "创建默认收银点失败,异常信息:{}");
            }
        }


    }


    public void auditEditHandler(Map<String,Object> map){
        log.info("拉卡拉修改通知接口返回解密数据:{}", JSONUtil.toJsonStr(map));

        if (ObjectUtil.isEmpty(map) || !map.containsKey("reviewPass")) {
            log.error("回调数据为空");
            return;
        }

        if("PASS".equals(map.get("reviewPass").toString())){
            String applicationId=map.get("reviewRelatedId")+"";

            MerchantAuditRecord auditRecord = new MerchantAuditRecord();
            auditRecord.setChannel(5);
            auditRecord.setApplicationId(applicationId);
            auditRecord = merchantAuditRecordService.getOne(new QueryWrapper<>(auditRecord));
            if (auditRecord == null) {
                log.error("未查询到对应的工单信息");
                return;
            }
            auditRecord.setRemark("审核成功");
            auditRecord.setThirdStatus("1");
            UpdateWrapper<MerchantAuditRecord> wrapper = new UpdateWrapper<>();
            wrapper.eq("applicationId", applicationId);
            merchantAuditRecordService.update(auditRecord, wrapper);


            MerchantChannelStatus channelStatus = new MerchantChannelStatus();
            channelStatus.setStatus("3");
            UpdateWrapper<MerchantChannelStatus> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("merchantCode", auditRecord.getMerchantCode())
                    .eq("channel", 5);

            String merchantCode = auditRecord.getMerchantCode();
            UserApp userApp = new UserApp().setMerchantCode(merchantCode).setUserType("promoter");
            userApp = userAppMapper.selectOne(new QueryWrapper<>(userApp));

            Account account = new Account().setUserId(userApp.getUserId() + "");
            account = accountService.getOne(new QueryWrapper<>(account));

            // 修改后的银行卡信息
            JSONObject bak = account.getBak();
            BankCard newBankCard = JSONObject.toJavaObject(bak, BankCard.class);
            newBankCard.setAccountType(BankCard.ACCOUNT_TYPE_PRIVATE);
            account.setBak(null);
            int count = accountService.count(new QueryWrapper<Account>().eq("bankCardId", account.getBankCardId()));
            if (count == 1) {
                newBankCard.setId(Integer.parseInt(account.getBankCardId()));
                bankCardService.updateById(newBankCard);
            } else {
                bankCardService.save(newBankCard);
                account.setBankCardId(newBankCard.getId() + "");
                accountService.updateById(account);
            }
            // 商户修改通过后，修改为最新的业务id
            channelStatus.setApplicationId(applicationId);

            mcsMapper.update(channelStatus, updateWrapper);

            MerchantBaseInfo mbi = merchantBaseInfoService.getMerchantBaseInfoByMerchantCode(merchantCode);

            noticeService.sendEditApplySuccessNotice(userApp.getUserId() + "", mbi.getAlias(), "次日到账");

            sendNotice(userApp, "结算账户修改通知", "结算账户修改成功", applicationId + "_" + System.currentTimeMillis());

        }



    }


    public MerchantChannelStatus queryMerchatChannelstatus(String customerNo, String externalCustomerNo) {
        Map map = laKalaInterface.queryMerchat(customerNo, externalCustomerNo);
        if (ObjectUtil.isEmpty(map)) {
            return null;
        }
        if (map.containsKey("code") && "000000".equals(map.get("code").toString()) && map.containsKey("data") && ObjectUtil.isNotEmpty(map.get("data"))) {
            String data = LaKaLaUtility.decrypt(lakalaConfig.getPubKey(), map.get("data").toString());
            JSONObject object = JSONObject.parseObject(data);
            Map<String, Object> reqMap = new HashMap<>();

            reqMap.put("customerNo", object.getJSONObject("customer").getString("customerNo"));
            reqMap.put("contractId", "query".concat(object.getJSONObject("customer").getString("openTime")));
            reqMap.put("userNo", LaKalaInterfaceImpl.userNo);
            reqMap.put("externalCustomerNo", object.getJSONObject("customer").getString("externalCustomerNo"));
            reqMap.put("termNos", object.getJSONObject("customer").getString("termNo"));

            reqMap.put("agencyNo", object.getJSONObject("customer").getString("agencyNo"));
            reqMap.put("activeNo", object.getJSONObject("customer").getString("activeNo"));
            reqMap.put("coreTermIds", object.getJSONArray("terminalInfo").toString());

            return auditCallback(reqMap);

        }
        return null;

    }


    @Transactional(rollbackFor = Exception.class)
    public MerchantChannelStatus auditCallback(Map<String, Object> map) {
        MerchantChannelStatus merchantChannelStatus = new MerchantChannelStatus()
                .setChannel(5)
                .setMerchantId(map.get("customerNo").toString());
        merchantChannelStatus = mcsMapper.selectOne(new QueryWrapper<>(merchantChannelStatus));

        if (merchantChannelStatus.getStatus().equals("3")) {
            log.error("此商户已经审核完成");
            return merchantChannelStatus;
        }

        if ("SUCCESS".equals(map.get("status").toString()) || "REVIEW_PASS".equals(map.get("status").toString())) {
            merchantChannelStatus.setApplicationId(map.get("contractId").toString());
            merchantChannelStatus.setStatus("3");
            merchantChannelStatus.setExtra(JSONObject.parseObject("{\n" +
                    "\t\"code\": \"SUCCESS\",\n" +
                    "\t\"msg\": \"成功\"\n" +
                    "}"));
            merchantChannelStatus.setRemark("成功");
            merchantChannelStatus.setUpdateTime(new Date());


            QueryWrapper<MerchantBackLkl> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("merchant_code", merchantChannelStatus.getMerchantCode());
            queryWrapper.eq("merchant_id", map.get("customerNo").toString());
            queryWrapper.eq("channel", "5");
            queryWrapper.eq("user_no", map.get("userNo").toString());

            MerchantBackLkl merchantBackLkl = backLklMapper.selectOne(queryWrapper);
            if (ObjectUtil.isEmpty(merchantBackLkl)) {
                merchantBackLkl = new MerchantBackLkl();
                merchantBackLkl.setMerchantCode(merchantChannelStatus.getMerchantCode());
                merchantBackLkl.setMerchantId(map.get("customerNo").toString());
                merchantBackLkl.setChannel("5");
                merchantBackLkl.setUserNo(map.get("userNo").toString());
                merchantBackLkl.setCustomerNo(map.get("customerNo").toString());
                merchantBackLkl.setExternalCustomerNo(map.get("externalCustomerNo").toString());
                merchantBackLkl.setTermNos(map.get("termNos").toString());
                merchantBackLkl.setAgencyNo(map.get("agencyNo").toString());
                merchantBackLkl.setActiveNo(map.get("activeNo").toString());
                merchantBackLkl.setContractId(map.get("contractId").toString());
                merchantBackLkl.setCoreTermIds(map.get("coreTermIds").toString());
                merchantBackLkl.setCreateTime(new Date());
                backLklMapper.insert(merchantBackLkl);
            }


            MerchantAuditRecord lastRecord = merchantAuditRecordService.getLastRecord(merchantChannelStatus.getMerchantCode());
            if (lastRecord != null) {
                lastRecord.setStatus(merchantChannelStatus.getStatus());
                lastRecord.setThirdStatus("1");
                lastRecord.setRemark("成功");
                merchantAuditRecordService.updateById(lastRecord);
                mcsMapper.updateById(merchantChannelStatus);
            }


            QueryWrapper<MerchantBaseInfo> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("merchantCode", merchantChannelStatus.getMerchantCode());

            MerchantBaseInfo baseInfo = merchantBaseInfoService.getOne(queryWrapper1);
            if (ObjectUtil.isNotEmpty(baseInfo)) {
                LambdaQueryWrapper<UserApp> qWrapper2 = Wrappers.lambdaQuery();
                qWrapper2.eq(UserApp::getUserId, baseInfo.getUserId());
                UserApp userApp = uaService.getOne(qWrapper2);
                sendNotice(userApp, "收银呗审核通知", "拉卡拉进件成功", merchantChannelStatus.getApplicationId());
            }
            return merchantChannelStatus;

        } else {
            merchantChannelStatus.setApplicationId(map.get("contractId").toString());
            merchantChannelStatus.setStatus("2");
            merchantChannelStatus.setExtra(JSONObject.parseObject("{\n" +
                    "\t\"code\": \"" + map.get("status") + "\",\n" +
                    "\t\"msg\": \"" + map.get("remark") + "\"\n" +
                    "}"));
            merchantChannelStatus.setRemark(map.get("remark")+"");
            merchantChannelStatus.setUpdateTime(new Date());

            MerchantAuditRecord lastRecord = merchantAuditRecordService.getLastRecord(merchantChannelStatus.getMerchantCode());
            if (lastRecord != null) {
                lastRecord.setStatus("2");
                lastRecord.setThirdStatus("1");
                lastRecord.setRemark(map.get("remark") + "");
                merchantAuditRecordService.updateById(lastRecord);
                mcsMapper.updateById(merchantChannelStatus);
            }

            QueryWrapper<MerchantBaseInfo> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("merchantCode", merchantChannelStatus.getMerchantCode());
            MerchantBaseInfo baseInfo = merchantBaseInfoService.getOne(queryWrapper1);
            if (ObjectUtil.isNotEmpty(baseInfo)) {
                LambdaQueryWrapper<UserApp> qWrapper2 = Wrappers.lambdaQuery();
                qWrapper2.eq(UserApp::getUserId, baseInfo.getUserId());
                UserApp userApp = uaService.getOne(qWrapper2);
                sendNotice(userApp, "收银呗审核通知", map.get("remark")+"", merchantChannelStatus.getApplicationId());
            }
            return null;

        }

    }


    public void createStore(MerchantChannelStatus merchantChannelStatus) {
//        if (!"4".equals(merchantChannelStatus.getStatus()) && !"3".equals(merchantChannelStatus.getStatus())) {
//            return;
//        }
        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";
            String baseUrl = "https://kysh.sxczgkj.cn/javaApi/java-api/add-store";
            StringBuilder sb = new StringBuilder(baseUrl);
            sb.append("?title=").append(merchantBaseInfo.getAlias());
            sb.append("&password=").append(userInfo.getPassword().toLowerCase());
            sb.append("?mcc=").append(merchantBaseInfo.getMcc());
            sb.append("?mccName=").append(merchantBaseInfo.getMccName());
            sb.append("&mobile=").append(userInfo.getLoginName());
            sb.append("&syb_m_id=").append(merchantStore.getId());
            sb.append("&addressNo=").append(merchantBaseInfo.getAddressNo());
            sb.append("&merchantCode=").append(merchantBaseInfo.getMerchantCode());
            String address = merchantBaseInfo.getProvince() + merchantBaseInfo.getCity() + merchantBaseInfo.getDistrict() + merchantBaseInfo.getAddress();
            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);
        }
    }


    public void sendNotice(UserApp userApp, String title, String msg, String uniqueKey) {
        Notice notice = new Notice(1, 1, userApp);
        notice.setNoticeCode(uniqueKey);
        notice.setConrtent(msg);
        noticeService.saveMerAuthNotice(notice);

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


}
