package com.xxfc.platform.universal.service;


import cn.hutool.core.collection.CollectionUtil;
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.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.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 tk.mybatis.mapper.weekend.WeekendSqls;

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


/**
 * 认证业务
 *
 * @author Administrator
 */
@Service
@Slf4j
public class CertificationService {
    @Autowired
    private UserAuthentication authentication;

    @Autowired
    private IdInformationMapper idInformationMapper;


    @Autowired
    private UserFeign userFeign;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private UserPictureParsing userPictureParsing;

    /**
     * 一、身份证图片进行实名认证
     *
     * @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().equals(name)) {
            ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE, "姓名不一致");
        }
        if (idInformation.getIdNumber().equals(number)) {
            ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE, "证件号不一致");
        }
        Example exa = new Example(IdInformation.class);
        Example.Criteria criteria = exa.createCriteria();
        criteria.andEqualTo("idNumber", idInformation.getIdNumber());
        List<IdInformation> idInformatics = idInformationMapper.selectByExample(exa);
        if (CollectionUtil.isNotEmpty(idInformatics)) {
            log.error("该身份证已存在,不要重复认证");
            log.info("图片已解析,未认证");
            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, "网络异常,请稍后再试");


    }

    /**
     * 二、认证通过保存到数据库当中
     *
     * @param idInformation
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ObjectRestResponse<Integer> addIdInformation(IdInformation idInformation) {
        log.info("----idInformation=========" + idInformation);
        //保存认证信息
        try {
            idInformation.setCrtTime(new Date());
            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().setRollbackOnly();
            return ObjectRestResponse.createFailedResult(ResultCode.INCOMPLETE_DATA, "认证失败,请重新认证");
        }
    }

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

    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(Integer userId) {

        try {
            int i = idInformationMapper.deleteByExample(Example
                    .builder(IdInformation.class)
                    .where(WeekendSqls.<IdInformation>custom()
                            .andEqualTo(IdInformation::getUserLoginId, userId)).build());
            if (i==1){
                return true;
            }else {
                log.info("删除行数= {}",i);
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            log.info("删除报错");
            return false;
        }

    }


}




