package com.xxfc.platform.universal.service;


import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.github.wxiaoqi.security.common.constant.RestCode;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.xxfc.platform.app.entity.Cofig;
import com.xxfc.platform.app.feign.ConfigFeign;
import com.xxfc.platform.universal.biz.UserMessage;
import com.xxfc.platform.universal.entity.IDCardInformation;
import com.xxfc.platform.universal.entity.IdInformation;
import com.xxfc.platform.universal.mapper.IdInformationMapper;
import com.xxfc.platform.universal.service.PictureParsing.UserPictureParsing;
import com.xxfc.platform.universal.service.authenticationInterface.UserAuthentication;
import com.xxfc.platform.universal.utils.CertifHttpUtils;
import com.xxfc.platform.universal.utils.Validation;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import tk.mybatis.mapper.entity.Example;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 认证业务
 *
 * @author Administrator
 */
@Service
@Slf4j
@AllArgsConstructor
@NoArgsConstructor
public class CertificationService {

    @Value("${certification.frequency:2}")
    private Integer FREQUENCY;

    @Autowired
    private ConfigFeign configFeign;

    @Autowired
    private UserAuthentication authentication;

    @Autowired
    private IdInformationMapper idInformationMapper;

    @Autowired
    private UserFeign userFeign;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private UserPictureParsing userPictureParsing;


    private String AUTHENTICATION_TYPE="100";

    /**
     * 一、身份证图片进行实名认证
     *
     * @param idInformation
     * @return
     */
    public ObjectRestResponse<Integer> certificate(IdInformation idInformation) {
        //1.认证前数据判断
        //判断是否bean是否为null
        if (idInformation == null) {
            return ObjectRestResponse.createFailedResult(ResultCode.INCOMPLETE_DATA, "无法识别,请重新上传");

        }
        //判断是否有填写身份证号
        if (StringUtils.isBlank(idInformation.getIdNumber())) {
            return ObjectRestResponse.createFailedResult(ResultCode.INCOMPLETE_DATA, "请填写证件号");
        }
        if (!Validation.isIdCard(idInformation.getIdNumber())) {
            return ObjectRestResponse.createFailedResult(ResultCode.WRONG_FORMAT_OF_ID_CARD, "证件格式错误");
        }
        //判断是有否填写名字
        if (StringUtils.isBlank(idInformation.getName())) {
            return ObjectRestResponse.createFailedResult(ResultCode.INCOMPLETE_DATA, "请填写姓名");
        }
        //判断是否有正面照片
        if (StringUtils.isBlank(idInformation.getFrontUrl())) {
            return ObjectRestResponse.createFailedResult(ResultCode.INCOMPLETE_DATA, "请上传正面照");
        }
        //判断是否有背面照片
        if (StringUtils.isBlank(idInformation.getBackUrl())) {
            return ObjectRestResponse.createFailedResult(ResultCode.INCOMPLETE_DATA, "请上传背面照");
        }
        //2.解析
        IDCardInformation credentialsData = userPictureParsing.analysis(idInformation.getFrontUrl(), idInformation.getBackUrl());
        //验证证件信息是否和填入的客户信息一致
        String name = credentialsData.getName();
        String number = credentialsData.getCode();
        if (!idInformation.getName().replaceAll(" ","").equals(name)) {
            return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE, "姓名不一致");
        }
        if (!idInformation.getIdNumber().replaceAll(" ","").equals(number)) {
            return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE, "证件号不一致");
        }
       //判断是否超过认证次数
        Example exa = new Example(IdInformation.class);
        exa.createCriteria().andEqualTo("idNumber", number);
        List<IdInformation> idInformatics = idInformationMapper.selectByExample(exa);

        if (CollectionUtils.isNotEmpty(idInformatics) && idInformatics.size() >=getCofig() ) {
            log.error("该身份证已超过最大认证次数");
            return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE, "该身份证已超过最大认证次数");
        }
        //3.验证
        boolean result = authentication.certificate(new UserMessage() {{
            setIdNumber(number);
            setName(name);
        }});
        log.info("----认证结果result=========" + result);
        //认证返回的参数是否为空
        if (result) {
            //认证成功后存入保存到数据库
            //获得身份证正面记录的身份证号和真实姓名
            //设置姓名
            idInformation.setName(name);
            //设置身份证号
            idInformation.setIdNumber(number);
            //获得到期时间
            String endDate = credentialsData.getExpiryDate();
            log.info("----获得到期时间endDate=========" + endDate);
            if (StringUtils.isBlank(endDate)) {
                return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE, "图片识别失败,请重新上传");
            }
            Date expirationDate = new Date();
            if (!Validation.isDate(endDate)) {
                Date date = new Date();
                Calendar c = Calendar.getInstance();
                c.setTime(date);
                c.add(Calendar.YEAR, 100);
                expirationDate = c.getTime();
            } else {
                SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
                formatter.setLenient(false);
                try {
                    expirationDate = formatter.parse(endDate);
                } catch (ParseException e) {
                    log.error(e.getMessage(), e);
                    return ObjectRestResponse.createFailedResult(ResultCode.INCOMPLETE_DATA, "无法识别,请重新上传");
                }
            }
            idInformation.setExpirationDate(expirationDate);
            CertificationService cs = applicationContext.getBean(this.getClass());
            return cs.addIdInformation(idInformation);

        }
        return ObjectRestResponse.createFailedResult(ResultCode.INCOMPLETE_DATA, "网络异常,请稍后再试");


    }

    /**
     * 获取认证次数
     * @return
     */
    public Integer getCofig() {
        List<Cofig> cofigs = null;
        try {
            cofigs = configFeign.getAllByType(AUTHENTICATION_TYPE).getData();
            log.info("cofigs={}",cofigs);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
        if (CollectionUtils.isEmpty(cofigs)) {
            return  FREQUENCY;
        }
        return Integer.valueOf(cofigs.get(0).getParams());
    }

    /**
     * 二、认证通过保存到数据库当中
     *
     * @param idInformation
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ObjectRestResponse<Integer> addIdInformation(IdInformation idInformation) {
        log.info("----idInformation=========" + idInformation);
        //保存认证信息
        try {
            idInformationMapper.insertSelective(idInformation);
            log.info("----addIdInformation---userid===" + idInformation.getUserLoginId() + "----name====" + idInformation.getName() + "---IdNumber===" + idInformation.getIdNumber());
            //认证成功后修改用户,用户认证状态
            userFeign.authentication(idInformation.getUserLoginId(), idInformation.getName(), idInformation.getIdNumber(), 1);
            return ObjectRestResponse.succ(idInformation.getId());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            TransactionAspectSupport.currentTransactionStatus();
            return ObjectRestResponse.createFailedResult(ResultCode.INCOMPLETE_DATA, "无法识别,请重新上传");
        }
    }

    public IdInformation getByUser(Integer userId) {
        return idInformationMapper.selectByUserId(userId);
    }

}




