package cn.qg.qaplatform.service.zdata.vcc.impl;

import cn.qg.qaplatform.config.SwitchDataSource;
import cn.qg.qaplatform.entity.zdata.XjfqGenProcessVo;
import cn.qg.qaplatform.enums.VccStatusEnum;
import cn.qg.qaplatform.mapper.zdata.VccAccountMapper;
import cn.qg.qaplatform.mapper.zdata.VccDataMapper;
import cn.qg.qaplatform.entity.zdata.VccOpenResultVo;
import cn.qg.qaplatform.entity.zdata.VccUserEntity;
import cn.qg.qaplatform.mapper.zdata.XyqbLoanDataMapper;
import cn.qg.qaplatform.process.Vcc;
import cn.qg.qaplatform.service.zdata.risk.RuleEngineService;
import cn.qg.qaplatform.service.zdata.vcc.VccDataService;
import cn.qg.qaplatform.utils.HttpClientUtils;
import cn.qg.qaplatform.utils.page.PageResult;
import cn.qg.qaplatform.utils.page.PageUtil;
import cn.qg.qaplatform.service.zdata.xyqb.XyqbBasicQueryService;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
@Slf4j
public class VccDataServiceImpl implements VccDataService {

    @Autowired
    VccDataMapper vccDataMapper;

    @Autowired
    VccAccountMapper vccAccountMapper;

    @Autowired
    RuleEngineService ruleEngineService;

    @Autowired
    XyqbBasicQueryService xyqbBasicQueryService;

    @Autowired
    XyqbLoanDataMapper xyqbLoanDataMapper;

    /**
     * vcc造数据
     * @param namespace 环境
     * @param phoneNo 手机号
     * @param openedChannel 创建渠道
     * @param status 1-授信成功，2-授信失败，3-开户成功，4-开户失败
     * @return
     * @throws Exception
     */
    @Override
    public VccOpenResultVo makeVccUser(String namespace, String phoneNo, String openedChannel, Integer status) throws Exception {
        VccOpenResultVo vccOpenResultVo = new VccOpenResultVo();
        vccOpenResultVo.setPhoneNo(phoneNo);
        vccOpenResultVo.setOpenedChannel(openedChannel);
        String vccChannel = null;
        if (openedChannel.equals("214")) {
            vccChannel = "159904";
        } else if (openedChannel.equals("217")) {
            vccChannel = "159905";
        } else {
            vccChannel = openedChannel;
        }
        // 登录
        Map loginResult = Vcc.login(namespace, phoneNo, openedChannel, openedChannel);
        String token = loginResult.get("token").toString();
        String uuid = loginResult.get("uuid").toString();
        vccOpenResultVo.setUuid(uuid);
        vccOpenResultVo.setUserId(xyqbBasicQueryService.getUserInfoByPhoneNo(namespace, phoneNo).getUserId());
        // 加入授信黑名单
        if (status == 2) {
            ruleEngineService.addBlackList(uuid);
            log.info("将用户 {} 加入授信黑名单！", uuid);
        }
        // 检查用户是否已有额度
        boolean haveQuota = Vcc.checkIfAlreadyHaveQuota(namespace, uuid);
        if (haveQuota) {
            vccOpenResultVo.setMsg("该用户已申请过，请更换新用户申请！");
            return vccOpenResultVo;
        }
        // credit url
        String vccToken = Vcc.creditUrl(namespace, token, vccChannel);
        // 身份证正面
//        Vcc.uploadFrontIdCard(vccToken, uuid, vccChannel);
        Vcc.uploadFrontIdCardNew(namespace, vccToken, uuid, vccChannel);
        // 身份证反面
//        Vcc.uploadBackIdCard(vccToken, uuid, vccChannel);
        Vcc.uploadBackIdCardNew(namespace, vccToken, uuid, vccChannel);
        // 放置身份证重复
        Vcc.modifyExistIdNo(namespace);
        // talos保存用户信息
        Vcc.saveUserDetails(namespace, token, vccChannel);
        // 提交ocr
//        Vcc.submitOcr(vccToken, vccChannel);
        Vcc.submitOcrNew(namespace, vccToken, vccChannel);
        // 提交授信
        Vcc.submitCredit(namespace, token, vccChannel);
        // 授信结果查询
        int searchCreditCount = 0;
        while (true) {
            try {
                Thread.sleep(1000);
                searchCreditCount++;
                Map<String, Object> creditResult = Vcc.searchCreditResult(namespace, token, vccChannel);
                if (creditResult.get("status").equals("1") || creditResult.get("status").equals("2")) {
                    break;
                } else if (creditResult.get("status").equals("0") && searchCreditCount == 10) {
                    String riskNo = Vcc.getRiskNo(namespace, uuid);
                    if (status == 2) {
                        Vcc.vccWindControlCreditCallback(namespace, uuid, riskNo, false, 10000);
                    } else {
                        Vcc.vccWindControlCreditCallback(namespace, uuid, riskNo, true, 10000);
                    }
                    break;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        if (status == 1 || status == 2) {
            log.info("提交授信成功！");
            Thread.sleep(2000);
            VccUserEntity userInfo = queryUserVccStatus(namespace, phoneNo);
            vccOpenResultVo.setMsg(VccStatusEnum.getDescByCode(userInfo.getStatus()));
            return vccOpenResultVo;
        }
        // 人脸识别回调
        Vcc.appFaceCallback(namespace, token, vccChannel);
        // 基本信息
        Vcc.basicInfo(namespace, token, vccChannel);
        // 发送验证码
        String requestId = Vcc.bindCardSms(namespace, token, vccChannel, "ABC", "6228272537046278993");
        // 额度激活
        JSONObject quotaActivationResult = Vcc.quotaActivation(namespace, token, vccChannel, "6228272537046278993", requestId);
        if (status == 3) {
            // 开户结果
            JSONObject result = Vcc.openResult(namespace, token, vccChannel);
            Map data = (Map) result.get("data");
            String amount = data.get("amount").toString();
            String eacctNo = data.get("eacctNo").toString();
            vccOpenResultVo.setAmount(amount);
            vccOpenResultVo.setEacctNo(eacctNo);
            vccOpenResultVo.setMsg("开户成功");
        }
        if (status == 4) {
            Map data = (Map) quotaActivationResult.get("data");
            if (data.get("status").equals("2")) {
                vccOpenResultVo.setMsg("开户失败");
            } else {
                vccOpenResultVo.setMsg("请找开发手动设置结果为开户失败！");
            }
        }
        return vccOpenResultVo;
    }

    /**
     * vcc捞数据
     * @param namespace 环境
     * @param status 状态
     * @return
     */
    @Override
    public PageResult getVccData(String namespace, Integer status, Integer pageNum, Integer pageSize) {
        SwitchDataSource.dataSourceSwitch(namespace, "vcc_talos");
        PageHelper.startPage(pageNum, pageSize);
        List<VccUserEntity> result =  vccDataMapper.queryVccDataByStatus(status);
        PageInfo<VccUserEntity> pageList = new PageInfo<>(result);
        PageResult pageResult = PageUtil.getPageResult(pageList, pageNum, pageSize);
        return pageResult;
    }

    /**
     * 根据手机号获取用户vcc状态
     * @param namespace 环境
     * @param phoneNo 手机号
     * @return QueryVccUser实体
     */
    @Override
    public VccUserEntity queryUserVccStatus(String namespace, String phoneNo) {
        SwitchDataSource.dataSourceSwitch(namespace, "vcc_talos");
        return vccDataMapper.queryUserVccStatus(phoneNo);
    }

    /**
     * vcc手动风控回调
     * @param namespace 环境
     * @param phoneNo 手机号
     * @param result 结果，true/false
     * @param amount 授信金额
     * @return
     */
    @Override
    public Boolean vccManualRiskControl(String namespace, String phoneNo, Boolean result, Integer amount) {
        SwitchDataSource.dataSourceSwitch(namespace, "xyqb_user");
        XjfqGenProcessVo xjfqGenProcessVo = xyqbLoanDataMapper.getUserInfoByPhoneNo(phoneNo);
        if (xjfqGenProcessVo == null) {
            return false;
        }
        String  uuid = xjfqGenProcessVo.getUuid();
        SwitchDataSource.dataSourceSwitch(namespace, "vcc_talos");
        Map<String, Object> riskRecord = vccDataMapper.getVccRiskRecord(uuid);
        if (riskRecord == null) {
            return false;
        }
        String riskNo = riskRecord.get("risk_no").toString();
        JSONObject creditResult = Vcc.vccWindControlCreditCallback(namespace, uuid, riskNo, result, amount);
        return creditResult.get("content").toString().equals("success");
    }

    /**
     * vcc还款回调
     * @param namespace 环境
     * @param phoneNo 手机号
     * @param result 回调结果，true/false
     * @return
     */
    @Override
    public JSONObject vccRepayCallback(String namespace, String phoneNo, Integer result) {
        String url = "https://acs-" + namespace + ".liangkebang.net/ex/paycenter/repay_notify";
        SwitchDataSource.dataSourceSwitch(namespace, "xyqb_user");
        XjfqGenProcessVo xjfqGenProcessVo = xyqbLoanDataMapper.getUserInfoByPhoneNo(phoneNo);
        SwitchDataSource.dataSourceSwitch(namespace, "acsdb");
        Integer orderNo = vccAccountMapper.getNewestRepayOrderNo(xjfqGenProcessVo.getUserId());
        Map<String, Object> formData = new HashMap<>();
        formData.put("orderNo", orderNo);
        if (result.equals(1)) {
            formData.put("remark", "还款成功");
        }
        if (result.equals(2)) {
            formData.put("remark", "还款失败");
        }
        formData.put("payStatus", result);
        formData.put("orderData", "{\"payApproachDesc\":\"易宝-广达小贷-VCC专用\",\"orderId\":\"79884519018498\",\"payApproach\":\"65\",\"payApproachName\":\"YEE_PAY_GDXD_VCC\",\"payGateway\":\"0\",\"cardNo\":\"6217000025253636858\",\"payGatewayName\":\"YEE_PAY\"}");
        JSONObject response = HttpClientUtils.doPost(url, formData);
        log.info("vcc还款回调结果：{}", response);
        return response;
    }

}
