package com.mmc.iuav.user.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.mmc.iuav.page.PageResult;
import com.mmc.iuav.response.ResultBody;
import com.mmc.iuav.response.ResultEnum;
import com.mmc.iuav.user.controller.userpoints.config.NumberOfUserPoints;
import com.mmc.iuav.user.controller.userpoints.config.UserPointsEnum;
import com.mmc.iuav.user.dao.RealNameAuthDao;
import com.mmc.iuav.user.dao.UserServiceDao;
import com.mmc.iuav.user.dao.userpoints.UserPointsDao;
import com.mmc.iuav.user.dao.userpoints.UserPointsDetailsDao;
import com.mmc.iuav.user.entity.RealNameAuthDO;
import com.mmc.iuav.user.entity.UserAccountDO;
import com.mmc.iuav.user.entity.userpoints.UserPointsDO;
import com.mmc.iuav.user.entity.userpoints.UserPointsDetails;
import com.mmc.iuav.user.model.dto.RealNameAuthDTO;
import com.mmc.iuav.user.model.dto.RealNameAuthDetailDTO;
import com.mmc.iuav.user.model.qo.RealNameAuthQO;
import com.mmc.iuav.user.model.vo.RealNameAuthVO;
import com.mmc.iuav.user.model.vo.UserAccountVO;
import com.mmc.iuav.user.model.vo.userpoints.UserPointsVO;
import com.mmc.iuav.user.service.RealNameAuthService;
import com.mmc.iuav.user.service.UserAccountService;
import com.mmc.iuav.user.util.RealNameAuthUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: zj
 * @Date: 2023/7/27 10:07
 */
@Service
@Slf4j
public class RealNameAuthServiceImpl implements RealNameAuthService {
    @Autowired
    private RealNameAuthDao realNameAuthDao;

    @Autowired
    private UserPointsDao userPointsDao;

    @Autowired
    private UserPointsDetailsDao userPointsDetailsDao;
    @Autowired
    private UserServiceDao userServiceDao;

    @Override
    public ResultBody add(RealNameAuthVO realNameAuthVO) {
        log.info("RealNameAuthVO:{}", JSONObject.toJSONString(realNameAuthVO));
        UserAccountDO userAccountById = userServiceDao.getUserAccountById(realNameAuthVO.getUserAccountId());
        realNameAuthVO.setUnionId(userAccountById.getUnionId());
        RealNameAuthDO realNameAuthDO0 = realNameAuthDao.getRealNameAuthByUId(realNameAuthVO.getUserAccountId());
        if (realNameAuthDO0 != null && realNameAuthDO0.getCheckStatus().equals(1)) {
            return ResultBody.error(ResultEnum.REAL_NAME_PASS_ERROR);
        }
        // 查询是否已认证
        RealNameAuthDO realNameAuthDO1 = realNameAuthDao.existHasBeenAuth(realNameAuthVO.getUnionId(), realNameAuthVO.getIdNumber());
        if (realNameAuthDO1 != null) {
            return ResultBody.error(ResultEnum.IDENTITY_HAS_BEEN_AUTHENTICATED);
        }
        // 校验正面
        ResultBody faceResult = RealNameAuthUtil.deal(realNameAuthVO.getFrontIdImg(), "face");
        // 校验反面
        ResultBody backResult = RealNameAuthUtil.deal(realNameAuthVO.getBackIdImg(), "back");
        String faceMsg = JSONObject.parseObject(faceResult.toString()).getString("code");
        String backMsg = JSONObject.parseObject(backResult.toString()).getString("code");
        // 都解析通过
        if (faceMsg.equals("200") && backMsg.equals("200")) {
            // 处理正面
            JSONObject faceResultJson = JSONObject.parseObject(
                    JSONObject.parseObject(faceResult.toString()).getString("result"));
            JSONObject backResultJson = JSONObject.parseObject(
                    JSONObject.parseObject(backResult.toString()).getString("result"));
            // 正面解析成功的时候，拿用户输入的信息与解析的数据作对比，一致再进行下一步，不一致提醒"用户输入的信息与身份证的不一致,请重新上传"
            if (!faceResultJson.getString("name").equals(realNameAuthVO.getUserName())
                    || !realNameAuthVO.getIdNumber().equals(faceResultJson.getString("num"))) {
                return ResultBody.error(ResultEnum.ID_INFO_AND_ID_card_MISMATCH);
            }
            RealNameAuthDO realNameAuthDO = new RealNameAuthDO();
            realNameAuthDO.setCheckStatus(1);
            realNameAuthDO.setUserAccountId(realNameAuthVO.getUserAccountId());
            realNameAuthDO.setFrontIdImg(realNameAuthVO.getFrontIdImg());
            realNameAuthDO.setBackIdImg(realNameAuthVO.getBackIdImg());
            realNameAuthDO.setUserName(faceResultJson.getString("name"));
            realNameAuthDO.setIdNumber(faceResultJson.getString("num"));
            realNameAuthDO.setAddress(faceResultJson.getString("address"));
            realNameAuthDO.setNationality(faceResultJson.getString("nationality"));
            realNameAuthDO.setIssue(backResultJson.getString("issue"));
            realNameAuthDO.setUnionId(realNameAuthVO.getUnionId());

            if (faceResultJson.getString("sex").equals("男")) {
                realNameAuthDO.setSex(1);
            } else if (faceResultJson.getString("sex").equals("女")) {
                realNameAuthDO.setSex(2);
            } else {
                realNameAuthDO.setSex(0);
            }
            if (faceResultJson.getString("is_fake").equals(false)) {
                realNameAuthDO.setFakeFront(1);
            } else {
                realNameAuthDO.setFakeFront(0);
            }
            if (backResultJson.getString("is_fake").equals(false)) {
                realNameAuthDO.setFakeBack(1);
            } else {
                realNameAuthDO.setFakeBack(0);
            }
            realNameAuthDO.setBirthday(this.getDate(faceResultJson.getString("birth"), "yyyyMMdd"));
            realNameAuthDO.setStartDate(this.getDate(backResultJson.getString("start_date"), "yyyyMMdd"));

            if (backResultJson.getString("end_date").equals("长期")) {
                realNameAuthDO.setEndDate(null);
            } else {
                realNameAuthDO.setEndDate(this.getDate(backResultJson.getString("end_date"), "yyyyMMdd"));
            }
            // 记录到数据库
            // 判断之前有没有认证成功
            RealNameAuthDO beforeRealNameAuthDO = realNameAuthDao
                    .getRealNameAuthByUnionId(realNameAuthVO.getUnionId());
            if (beforeRealNameAuthDO == null) {
                realNameAuthDao.addRealNameAuth(realNameAuthDO);
            } else {
                Date date = new Date();
                realNameAuthDO.setCreateTime(date);
                realNameAuthDO.setId(beforeRealNameAuthDO.getId());
                realNameAuthDao.updateRealNameAuth(realNameAuthDO);
            }
            //积分 todo
            extracted(realNameAuthDO.getUserAccountId());

            return ResultBody.success();
        } else {
            return ResultBody.error(ResultEnum.PHOTO_FORMAT_ERROR);
        }
    }


    private void extracted(Integer id) {
        UserPointsVO userPointsVO = new UserPointsVO(id, NumberOfUserPoints.match(1).getMessage());
        //积分
        UserPointsDO pointsDO = userPointsDao.selectUserPoints(userPointsVO.getUserAccountId());
        UserPointsDO points = null;
        if (pointsDO != null) {
            Integer totalPoints = userPointsVO.getTotalPoints();
            Integer totalPoints1 = pointsDO.getTotalPoints();
            totalPoints += totalPoints1;
            userPointsVO.setTotalPoints(totalPoints);
            points = new UserPointsDO(userPointsVO);
            userPointsDao.updatePoints(points);
        } else if (pointsDO == null) {
            points = new UserPointsDO(userPointsVO);
            userPointsDao.insertPoints(points);
        }
        UserPointsDetails userPointsDetails = new UserPointsDetails(id, NumberOfUserPoints.match(1).getMessage(), UserPointsEnum.match(1).getMessage());
        userPointsDetailsDao.insertPointsDetails(userPointsDetails);
    }

    @Override
    public ResultBody<RealNameAuthDetailDTO> detail(Integer id) {
        RealNameAuthDO realNameAuthDO = realNameAuthDao.getRealNameAuthById(id);
        if (realNameAuthDO != null) {
            UserAccountDO userAccountById = userServiceDao.getUserAccountById(realNameAuthDO.getUserAccountId());
            if(realNameAuthDO.getUnionId() == null || realNameAuthDO.getUnionId().equals("")){
                realNameAuthDO.setUnionId(userAccountById.getUnionId());
                realNameAuthDao.updateRealNameAuth(realNameAuthDO);
            }
            return ResultBody.success(realNameAuthDO.buildRealNameAuthDetailDTO());
        }
        return ResultBody.success();
    }

    @Override
    public ResultBody<RealNameAuthDTO> listPage(RealNameAuthQO realNameAuthQO) {
        int count = realNameAuthDao.countListRealNameAuth(realNameAuthQO);
        if (count == 0) {
            return ResultBody.success(PageResult.buildPage(realNameAuthQO.getPageNo(), realNameAuthQO.getPageSize(), count));
        }
        int pageNo = realNameAuthQO.getPageNo();
        realNameAuthQO.buildCurrentPage();
        List<RealNameAuthDO> list = realNameAuthDao.listRealNameAuth(realNameAuthQO);
        List<RealNameAuthDTO> pageList = list.stream().map(d -> {
            return d.buildRealNameAuthDTO();
        }).collect(Collectors.toList());
        return ResultBody.success(PageResult.buildPage(pageNo, realNameAuthQO.getPageSize(), count, pageList));
    }

    @Override
    public ResultBody<RealNameAuthDTO> userDetail(Integer userAccountId) {
        RealNameAuthDO realNameAuthDO = realNameAuthDao.userDetail(userAccountId);
        if (realNameAuthDO != null) {
            UserAccountDO userAccountById = userServiceDao.getUserAccountById(realNameAuthDO.getUserAccountId());
            if(realNameAuthDO.getUnionId() == null || realNameAuthDO.getUnionId().equals("")){
                realNameAuthDO.setUnionId(userAccountById.getUnionId());
                realNameAuthDao.updateRealNameAuth(realNameAuthDO);
            }
            return ResultBody.success(realNameAuthDO.buildRealNameAuthDTO());
        }
        return ResultBody.success();
    }

    @Override
    public ResultBody updateRealNameAuthRemark(Integer id, String remark) {
        realNameAuthDao.updateRealNameAuthRemark(id, remark);
        return ResultBody.success();
    }

    public Date getDate(String str, String format) {
        Date date = null;
        try {
            // 设置日期格式
            SimpleDateFormat df = new SimpleDateFormat(format);
            // String dates=df.format(new Date());// new Date()为获取当前系统时间
            date = df.parse(str);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return date;
    }
}
