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

import cn.qg.qaplatform.config.SwitchDataSource;
import cn.qg.qaplatform.zdata.enums.VccStatusEnum;
import cn.qg.qaplatform.zdata.mapper.VccDataMapper;
import cn.qg.qaplatform.zdata.entity.VccOpenResultVo;
import cn.qg.qaplatform.zdata.entity.VccUserEntity;
import cn.qg.qaplatform.zdata.process.Vcc;
import cn.qg.qaplatform.zdata.service.risk.RuleEngineService;
import cn.qg.qaplatform.zdata.service.vcc.VccDataService;
import cn.qg.qaplatform.utils.page.PageResult;
import cn.qg.qaplatform.utils.page.PageUtil;
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.List;
import java.util.Map;


@Service
@Slf4j
public class VccDataServiceImpl implements VccDataService {

    @Autowired
    VccDataMapper vccDataMapper;

    @Autowired
    RuleEngineService ruleEngineService;

    /**
     * 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";
        }
        if (openedChannel.equals("217")) {
            vccChannel = "159905";
        }
        if (vccChannel == null) {
            return null;
        }
        // 登录
        Map loginResult = Vcc.login(namespace, phoneNo, openedChannel, openedChannel);
        String token = loginResult.get("token").toString();
        String uuid = loginResult.get("uuid").toString();
        // 加入授信黑名单
        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.uploadBackIdCard(vccToken, uuid, vccChannel);
        // 放置身份证重复
        Vcc.modifyExistIdNo(namespace);
        // talos保存用户信息
        Vcc.saveUserDetails(namespace, token, vccChannel);
        // 提交ocr
        Vcc.submitOcr(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);
                    } else {
                        Vcc.vccWindControlCreditCallback(namespace, uuid, riskNo, true);
                    }
                    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);
    }
}
