package com.artfess.data.manager.impl;

import com.artfess.base.feign.UCFeignService;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.base.model.CommonResult;
import com.artfess.base.util.*;
import com.artfess.data.dao.*;
import com.artfess.data.dto.EditPersonalProfileDto;
import com.artfess.data.dto.PersonalProfileDto;
import com.artfess.data.manager.*;
import com.artfess.data.model.*;
import com.artfess.data.vo.ExamUserEvaluationVo;
import com.artfess.data.vo.PersonalProfileVo;
import com.artfess.examine.dao.ExamUserEvaluationDao;
import com.artfess.examine.dao.ExamUserEvaluationDetailDao;
import com.artfess.examine.dao.ExamUserEvaluationDetailTyDao;
import com.artfess.examine.model.ExamUserEvaluation;
import com.artfess.examine.model.ExamUserEvaluationDetail;
import com.artfess.examine.model.ExamUserEvaluationDetailTy;
import com.artfess.file.util.AppFileUtil;
import com.artfess.file.util.CheckFileFormatUtil;
import com.artfess.file.util.MinioUtil;
import com.artfess.poi.util.FileDownloadUtil;
import com.artfess.uc.api.impl.service.UserServiceImpl;
import com.artfess.uc.api.impl.util.ContextUtil;
import com.artfess.uc.api.model.IUser;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.api.client.util.IOUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 个人信息基本情况表 服务实现类
 *
 * @author 超级管理员
 * @company 阿特菲斯信息技术有限公司
 * @since 2024-12-27
 */
@Service
public class BizUserBasicManagerImpl extends BaseManagerImpl<BizUserBasicDao, BizUserBasic> implements BizUserBasicManager {

    private final BizUserBasicDao bizUserBasicDao;
    private final BizUserAchieveDetailDao bizUserAchieveDetailDao;
    private final BizUserAchieveStaticDao bizUserAchieveStaticDao;
    private final BizUserGradeDao bizUserGradeDao;
    private final BizUserGradeStaticDao bizUserGradeStaticDao;
    private final BizUserThroughStaticDao bizUserThroughStaticDao;
    private final BizUserThroughDetailDao bizUserThroughDetailDao;
    private final BizUserWorkDetailDao bizUserWorkDetailDao;
    private final UserServiceImpl userServiceImpl;
    private final ExamUserEvaluationDao examUserEvaluationDao;
    private final ExamUserEvaluationDetailDao examUserEvaluationDetailDao;
    private final ExamUserEvaluationDetailTyDao examUserEvaluationDetailTyDao;
    private final BizUserThroughStaticManager bizUserThroughStaticManager;
    private final BizUserGradeStaticManager bizUserGradeStaticManager;
    private final BizUserAchieveStaticManager bizUserAchieveStaticManager;

    @Resource
    UCFeignService ucFeignService;

    public BizUserBasicManagerImpl(BizUserBasicDao bizUserBasicDao, BizUserAchieveDetailDao bizUserAchieveDetailDao, BizUserAchieveStaticDao bizUserAchieveStaticDao, BizUserGradeDao bizUserGradeDao, BizUserGradeStaticDao bizUserGradeStaticDao, BizUserThroughStaticDao bizUserThroughStaticDao, BizUserThroughDetailDao bizUserThroughDetailDao, BizUserWorkDetailDao bizUserWorkDetailDao, UserServiceImpl userServiceImpl, ExamUserEvaluationDao examUserEvaluationDao, ExamUserEvaluationDetailDao examUserEvaluationDetailDao, ExamUserEvaluationDetailTyDao examUserEvaluationDetailTyDao, BizUserThroughStaticManager bizUserThroughStaticManager, BizUserGradeStaticManager bizUserGradeStaticManager, BizUserAchieveStaticManager bizUserAchieveStaticManager) {
        super();
        this.bizUserBasicDao = bizUserBasicDao;
        this.bizUserAchieveDetailDao = bizUserAchieveDetailDao;
        this.bizUserAchieveStaticDao = bizUserAchieveStaticDao;
        this.bizUserGradeDao = bizUserGradeDao;
        this.bizUserGradeStaticDao = bizUserGradeStaticDao;
        this.bizUserThroughStaticDao = bizUserThroughStaticDao;
        this.bizUserThroughDetailDao = bizUserThroughDetailDao;
        this.bizUserWorkDetailDao = bizUserWorkDetailDao;
        this.userServiceImpl = userServiceImpl;
        this.examUserEvaluationDao = examUserEvaluationDao;
        this.examUserEvaluationDetailDao = examUserEvaluationDetailDao;
        this.examUserEvaluationDetailTyDao = examUserEvaluationDetailTyDao;
        this.bizUserThroughStaticManager = bizUserThroughStaticManager;
        this.bizUserGradeStaticManager = bizUserGradeStaticManager;
        this.bizUserAchieveStaticManager = bizUserAchieveStaticManager;
    }


    @Resource
    private BizSubjectScoreCountManager subjectScoreCountManager;

    /**
     * 获取个人档案
     *
     * @return 个人档案
     */
    @Override
    public PersonalProfileVo getPersonalProfile() {
//        IUser currentUser = ContextUtil.getCurrentUser();
//        assert currentUser != null;
        String userId = ContextUtil.getCurrentUserId();

        PersonalProfileVo personalProfileVo = new PersonalProfileVo();

        QueryWrapper<BizUserBasic> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id_", userId);
        BizUserBasic bizUserBasic = bizUserBasicDao.selectOne(queryWrapper);
        personalProfileVo.setBizUserBasic(bizUserBasic);

        if (bizUserBasic != null) {

            // 获取XXX资质及成果表（按年度统计表）
            BizUserAchieveStatic bizUserAchieveStatic = bizUserAchieveStaticDao.selectOne(new QueryWrapper<BizUserAchieveStatic>().eq("user_archive_id_", bizUserBasic.getId()));
            personalProfileVo.setBizUserAchieveStatic(bizUserAchieveStatic);

            // 获取xxx成绩与奖惩表（按年度统计表）
            BizUserGradeStatic bizUserGradeStatic = bizUserGradeStaticDao.selectOne(new QueryWrapper<BizUserGradeStatic>().eq("user_archive_id_", bizUserBasic.getId()));
            personalProfileVo.setBizUserGradeStatic(bizUserGradeStatic);

            // 获取xxx经历表（按年统计表）
            List<BizUserThroughStatic> bizUserThroughStaticList = bizUserThroughStaticDao.selectList(new QueryWrapper<BizUserThroughStatic>().eq("user_archive_id_", bizUserBasic.getId()));
            personalProfileVo.setBizUserThroughStaticList(bizUserThroughStaticList);

            // 获取xxx工作简历表
            List<BizUserWorkDetail> bizUserWorkDetailList = bizUserWorkDetailDao.selectList(new QueryWrapper<BizUserWorkDetail>().eq("user_archive_id_", bizUserBasic.getId()));
            personalProfileVo.setBizUserWorkDetailList(bizUserWorkDetailList);

            List<ExamUserEvaluationVo> examUserEvaluationVoList = new ArrayList<>();
            QueryWrapper<ExamUserEvaluation> examUserEvaluationVoQueryWrapper = new QueryWrapper<>();
            examUserEvaluationVoQueryWrapper.eq("user_id_", userId);
            List<ExamUserEvaluation> examUserEvaluations = examUserEvaluationDao.selectList(examUserEvaluationVoQueryWrapper);
            if (CollectionUtils.isNotEmpty(examUserEvaluations)) {
                for (ExamUserEvaluation examUserEvaluation : examUserEvaluations) {
                    ExamUserEvaluationVo examUserEvaluationVo = new ExamUserEvaluationVo();
                    examUserEvaluationVo.setYear(examUserEvaluation.getYear());
                    examUserEvaluationVo.setExamUserEvaluation(examUserEvaluation);
//                    examUserEvaluationVo.setExamUserEvaluationDetailList(examUserEvaluationDetailDao.selectList(new QueryWrapper<ExamUserEvaluationDetail>().eq("user_id_", userId).eq("year_", examUserEvaluation.getYear())));
                    List<ExamUserEvaluationDetailTy> examUserEvaluationDetailTyList = examUserEvaluationDetailTyDao.selectList(new QueryWrapper<ExamUserEvaluationDetailTy>().eq("user_id_", userId).eq("year_", examUserEvaluation.getYear()));
                    examUserEvaluationVo.setProfessionalCommonDetail(examUserEvaluationDetailTyList.stream()
                            .filter(e -> e.getType() == 1)
                            .collect(Collectors.toList()));
                    examUserEvaluationVo.setProfessionalXXDetail(examUserEvaluationDetailTyList.stream()
                            .filter(e -> e.getType() == 2)
                            .collect(Collectors.toList()));
                    examUserEvaluationVo.setXXCommonDetail(examUserEvaluationDetailTyList.stream()
                            .filter(e -> e.getType() == 3)
                            .collect(Collectors.toList()));
                    examUserEvaluationVo.setXXSportsDetail(examUserEvaluationDetailTyList.stream()
                            .filter(e -> e.getType() == 4)
                            .collect(Collectors.toList()));
                    LambdaQueryWrapper<BizSubjectScoreCount> wrapper = new LambdaQueryWrapper<>();
                    wrapper.eq(BizSubjectScoreCount::getUserArchiveId, bizUserBasic.getId());
                    wrapper.eq(BizSubjectScoreCount::getYear, Integer.parseInt(examUserEvaluation.getYear()));
                    wrapper.orderByAsc(BizSubjectScoreCount::getSn);
                    examUserEvaluationVo.setSubjectScoreCounts(subjectScoreCountManager.list(wrapper));
                    // 获取XXX资质及成果表（按年明细记录表）
                    List<BizUserAchieveDetail> bizUserAchieveDetailList = bizUserAchieveDetailDao
                            .selectList(new QueryWrapper<BizUserAchieveDetail>().eq("user_archive_id_", bizUserBasic.getId()).eq("td_year_", Integer.parseInt(examUserEvaluation.getYear())));
                    examUserEvaluationVo.setBizUserAchieveDetailList(bizUserAchieveDetailList);
                    // 获取xxx成绩与奖惩表（按年成绩明细记录表）
                    List<BizUserGrade> bizUserGradeList = bizUserGradeDao.selectList(new QueryWrapper<BizUserGrade>().eq("user_archive_id_", bizUserBasic.getId()).eq("td_year_", Integer.parseInt(examUserEvaluation.getYear())));
                    examUserEvaluationVo.setBizUserGradeList(bizUserGradeList);
                    // 获取xxx经历表（按年明细记录表）
                    List<BizUserThroughDetail> bizUserThroughDetailList = bizUserThroughDetailDao.selectList(new QueryWrapper<BizUserThroughDetail>().eq("user_archive_id_", bizUserBasic.getId()));
                    examUserEvaluationVo.setBizUserThroughDetailList(bizUserThroughDetailList);
                    examUserEvaluationVoList.add(examUserEvaluationVo);
                }
            }

            personalProfileVo.setExamUserEvaluationVoList(examUserEvaluationVoList);

        }

        return personalProfileVo;
    }

    /**
     * 获取个人档案
     *
     * @param year
     * @param userId
     * @return 个人档案
     */
    @Override
    public PersonalProfileVo getPersonalProfile(String year, String userId) {

        PersonalProfileVo personalProfileVo = new PersonalProfileVo();

        QueryWrapper<BizUserBasic> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id_", userId);
        BizUserBasic bizUserBasic = bizUserBasicDao.selectOne(queryWrapper);
        personalProfileVo.setBizUserBasic(bizUserBasic);

        if (bizUserBasic != null) {

            // 获取XXX资质及成果表（按年度统计表）
            BizUserAchieveStatic bizUserAchieveStatic = bizUserAchieveStaticDao.selectOne(new QueryWrapper<BizUserAchieveStatic>().eq("user_archive_id_", bizUserBasic.getId()));
            personalProfileVo.setBizUserAchieveStatic(bizUserAchieveStatic);

            // 获取xxx成绩与奖惩表（按年度统计表）
            BizUserGradeStatic bizUserGradeStatic = bizUserGradeStaticDao.selectOne(new QueryWrapper<BizUserGradeStatic>().eq("user_archive_id_", bizUserBasic.getId()));
            personalProfileVo.setBizUserGradeStatic(bizUserGradeStatic);

            // 获取xxx经历表（按年统计表）
            List<BizUserThroughStatic> bizUserThroughStaticList = bizUserThroughStaticDao.selectList(new QueryWrapper<BizUserThroughStatic>().eq("user_archive_id_", bizUserBasic.getId()));
            personalProfileVo.setBizUserThroughStaticList(bizUserThroughStaticList);

            // 获取xxx工作简历表
            List<BizUserWorkDetail> bizUserWorkDetailList = bizUserWorkDetailDao.selectList(new QueryWrapper<BizUserWorkDetail>().eq("user_archive_id_", bizUserBasic.getId()));
            personalProfileVo.setBizUserWorkDetailList(bizUserWorkDetailList);

            List<ExamUserEvaluationVo> examUserEvaluationVoList = new ArrayList<>();
            QueryWrapper<ExamUserEvaluation> examUserEvaluationVoQueryWrapper = new QueryWrapper<>();
            examUserEvaluationVoQueryWrapper.eq("user_id_", userId);
            examUserEvaluationVoQueryWrapper.eq("year_", year);
            ExamUserEvaluation examUserEvaluation = examUserEvaluationDao.selectOne(examUserEvaluationVoQueryWrapper);
            if (!Objects.isNull(examUserEvaluation)) {
                ExamUserEvaluationVo examUserEvaluationVo = new ExamUserEvaluationVo();
                examUserEvaluationVo.setYear(examUserEvaluation.getYear());
                examUserEvaluationVo.setExamUserEvaluation(examUserEvaluation);
//                examUserEvaluationVo.setExamUserEvaluationDetailList(examUserEvaluationDetailDao.selectList(new QueryWrapper<ExamUserEvaluationDetail>().eq("user_id_", userId).eq("year_", examUserEvaluation.getYear())));
                List<ExamUserEvaluationDetailTy> examUserEvaluationDetailTyList = examUserEvaluationDetailTyDao.selectList(new QueryWrapper<ExamUserEvaluationDetailTy>().eq("user_id_", userId).eq("year_", examUserEvaluation.getYear()));
                examUserEvaluationVo.setProfessionalCommonDetail(examUserEvaluationDetailTyList.stream()
                        .filter(e -> e.getType() == 1)
                        .collect(Collectors.toList()));
                examUserEvaluationVo.setProfessionalXXDetail(examUserEvaluationDetailTyList.stream()
                        .filter(e -> e.getType() == 2)
                        .collect(Collectors.toList()));
                examUserEvaluationVo.setXXCommonDetail(examUserEvaluationDetailTyList.stream()
                        .filter(e -> e.getType() == 3)
                        .collect(Collectors.toList()));
                examUserEvaluationVo.setXXSportsDetail(examUserEvaluationDetailTyList.stream()
                        .filter(e -> e.getType() == 4)
                        .collect(Collectors.toList()));
                LambdaQueryWrapper<BizSubjectScoreCount> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(BizSubjectScoreCount::getUserArchiveId, bizUserBasic.getId());
                wrapper.eq(BizSubjectScoreCount::getYear, Integer.parseInt(year));
                wrapper.orderByAsc(BizSubjectScoreCount::getSn);
                examUserEvaluationVo.setSubjectScoreCounts(subjectScoreCountManager.list(wrapper));
                // 获取XXX资质及成果表（按年明细记录表）
                List<BizUserAchieveDetail> bizUserAchieveDetailList = bizUserAchieveDetailDao
                        .selectList(new QueryWrapper<BizUserAchieveDetail>().eq("user_archive_id_", bizUserBasic.getId()).eq("td_year_", Integer.parseInt(examUserEvaluation.getYear())));
                examUserEvaluationVo.setBizUserAchieveDetailList(bizUserAchieveDetailList);
                // 获取xxx成绩与奖惩表（按年成绩明细记录表）
                List<BizUserGrade> bizUserGradeList = bizUserGradeDao.selectList(new QueryWrapper<BizUserGrade>().eq("user_archive_id_", bizUserBasic.getId()).eq("td_year_", Integer.parseInt(examUserEvaluation.getYear())));
                examUserEvaluationVo.setBizUserGradeList(bizUserGradeList);
                // 获取xxx经历表（按年明细记录表）
                List<BizUserThroughDetail> bizUserThroughDetailList = bizUserThroughDetailDao.selectList(new QueryWrapper<BizUserThroughDetail>().eq("user_archive_id_", bizUserBasic.getId()).eq("td_year_", Integer.parseInt(examUserEvaluation.getYear())));
                examUserEvaluationVo.setBizUserThroughDetailList(bizUserThroughDetailList);
                examUserEvaluationVoList.add(examUserEvaluationVo);
            }
            personalProfileVo.setExamUserEvaluationVoList(examUserEvaluationVoList);

        }
        return personalProfileVo;
    }

    /**
     * 编辑个人档案
     *
     * @param editPersonalProfileDto 个人档案
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void editPersonalProfile(EditPersonalProfileDto editPersonalProfileDto) {
        //先删除之前的
        String userId = editPersonalProfileDto.getUserId();
        Integer year = editPersonalProfileDto.getPersonalProfileDto().getYear();
        BizUserBasic oldBasic = bizUserBasicDao.selectOne(new QueryWrapper<BizUserBasic>().eq("user_id_", userId));
        if (oldBasic != null) {
            bizUserBasicDao.delete(new QueryWrapper<BizUserBasic>().eq("user_id_", userId));
            bizUserAchieveDetailDao.delete(new QueryWrapper<BizUserAchieveDetail>().eq("user_archive_id_", oldBasic.getId()).eq("td_year_", year));
            bizUserGradeDao.delete(new QueryWrapper<BizUserGrade>().eq("user_archive_id_", oldBasic.getId()).eq("td_year_", year));
            bizUserThroughDetailDao.delete(new QueryWrapper<BizUserThroughDetail>().eq("user_archive_id_", oldBasic.getId()).eq("td_year_", year));
            bizUserWorkDetailDao.delete(new QueryWrapper<BizUserWorkDetail>().eq("user_archive_id_", oldBasic.getId()));
            examUserEvaluationDetailDao.delete(new QueryWrapper<ExamUserEvaluationDetail>().eq("user_id_", userId).eq("year_", year.toString()).eq("category_", "3").eq("category_", "4"));
            examUserEvaluationDetailTyDao.delete(new QueryWrapper<ExamUserEvaluationDetailTy>().eq("user_id_", userId).eq("year_", year.toString()));
            // 删除年度考生综合评定
            examUserEvaluationDao.delete(
                    new QueryWrapper<ExamUserEvaluation>()
                            .eq("user_id_", userId)
                            .eq("year_", year.toString()));
            // 删除成绩统计
            subjectScoreCountManager.remove(
                    new LambdaQueryWrapper<BizSubjectScoreCount>()
                            .eq(BizSubjectScoreCount::getUserArchiveId, oldBasic.getId())
                            .eq(BizSubjectScoreCount::getYear, year)
            );
        }

        //保存基本信息
        BizUserBasic basic = new BizUserBasic();
        if (oldBasic != null) {
            basic.setId(oldBasic.getId());
        }
        basic.setUserId(editPersonalProfileDto.getUserId());
        IUser userById = userServiceImpl.getUserById(editPersonalProfileDto.getUserId());
        CommonResult<JsonNode> objectNode = ucFeignService.getUserById(userId);
        if (BeanUtils.isNotEmpty(objectNode)) {
            String idCard = objectNode.getValue().get("idCard").asText();
            basic.setIdentCard(idCard);
        }
        basic.setLoginName(userById.getAccount());
        basic.setUserArchive(userById.getFullname() + " + " + editPersonalProfileDto.getIdentCard());
        basic.setUserName(userById.getFullname());
        basic.setArchiveUnitName(editPersonalProfileDto.getArchiveUnitName());
        basic.setArchiveYear(editPersonalProfileDto.getArchiveYear());
        basic.setSex(editPersonalProfileDto.getSex());
        basic.setIdentCard(editPersonalProfileDto.getIdentCard());
        basic.setPhoneNum(editPersonalProfileDto.getPhoneNum());
        basic.setBirthDate(editPersonalProfileDto.getBirthDate());
        basic.setRwDate(editPersonalProfileDto.getRwDate());
        basic.setXjxDate(editPersonalProfileDto.getXjxDate());
        basic.setJobDescription(editPersonalProfileDto.getJobDescription());
        basic.setRdDate(editPersonalProfileDto.getRdDate());
        basic.setNation(editPersonalProfileDto.getNation());
        basic.setNativePlace(editPersonalProfileDto.getNativePlace());
        basic.setPoliticalOutlook(editPersonalProfileDto.getPoliticalOutlook());
        basic.setBloodType(editPersonalProfileDto.getBloodType());
        basic.setRwAddress(editPersonalProfileDto.getRwAddress());
        basic.setRegisteredResidence(editPersonalProfileDto.getRegisteredResidence());
        basic.setHighEducation(editPersonalProfileDto.getHighEducation());
        basic.setUserClass(editPersonalProfileDto.getUserClass());
        basic.setUserPhotoUrl(editPersonalProfileDto.getUserPhotoUrl());
        bizUserBasicDao.insert(basic);

        PersonalProfileDto personalProfileDto = editPersonalProfileDto.getPersonalProfileDto();
        if (Objects.isNull(personalProfileDto)) {
            throw new RuntimeException("个人档案信息不能为空！");
        }

//        ExamUserEvaluation examUserEvaluation = examUserEvaluationDao.selectOne(new QueryWrapper<ExamUserEvaluation>().eq("user_id_", userId).eq("year_", personalProfileDto.getYear().toString()));
//        if (Objects.isNull(examUserEvaluation)) {
        ExamUserEvaluation examUserEvaluation = personalProfileDto.getExamUserEvaluation();
        examUserEvaluation.setUserId(userId);
        examUserEvaluation.setUserName(userById.getFullname());
        examUserEvaluation.setYear(year.toString());
        examUserEvaluationDao.insert(examUserEvaluation);
//        } else {
//            examUserEvaluation.setPositionId(personalProfileDto.getExamUserEvaluation().getPositionId());
//            examUserEvaluation.setVocationalEducationScore(examUserEvaluation.getVocationalEducationScore());
//
//            Integer vocationalEducationScore = examUserEvaluation.getVocationalEducationScore();
//            if (vocationalEducationScore >= 90) {
//                examUserEvaluation.setVocationalEducationEvaluation(ScoreLevelEnum.GOOD.getDesc());
//            } else if (vocationalEducationScore >= 80 && vocationalEducationScore < 90) {
//                examUserEvaluation.setVocationalEducationEvaluation(ScoreLevelEnum.LH.getDesc());
//            } else if (vocationalEducationScore >= 70 && vocationalEducationScore < 80) {
//                examUserEvaluation.setVocationalEducationEvaluation(ScoreLevelEnum.JG.getDesc());
//            } else {
//                examUserEvaluation.setVocationalEducationEvaluation(ScoreLevelEnum.BJG.getDesc());
//            }
//            examUserEvaluation.setComprehensiveAppraisalDescription(examUserEvaluation.getComprehensiveAppraisalDescription());
//            examUserEvaluation.setOverallEvaluationDescription(examUserEvaluation.getOverallEvaluationDescription());
//            examUserEvaluation.setOverallEvaluationTime(examUserEvaluation.getOverallEvaluationTime());
//            examUserEvaluationDao.updateById(examUserEvaluation);
//        }

//        List<ExamUserEvaluationDetail> examUserEvaluationDetailList = personalProfileDto.getExamUserEvaluationDetailList();
//        for (ExamUserEvaluationDetail examUserEvaluationDetail : examUserEvaluationDetailList) {
//            examUserEvaluationDetail.setId(null);
//            examUserEvaluationDetail.setYear(year.toString());
//            examUserEvaluationDetail.setPositionId(examUserEvaluation.getPositionId());
//            examUserEvaluationDetail.setUserId(userId);
//            examUserEvaluationDetail.setUserName(userById.getUsername());
//            examUserEvaluationDetail.setType("2");
//            String category = examUserEvaluationDetail.getCategory();
//            examUserEvaluationDetail.setCategory(category);
//            examUserEvaluationDetail.setSubjectName(examUserEvaluationDetail.getSubjectName());
//            examUserEvaluationDetail.setScore(examUserEvaluationDetail.getScore());
//            examUserEvaluationDetail.setLevel(examUserEvaluationDetail.getLevel());
//            examUserEvaluationDetailDao.insert(examUserEvaluationDetail);
//            if (Objects.equals(category, "4")) {
//                List<ExamUserEvaluationDetailTy> examUserEvaluationDetailTyList = personalProfileDto.getExamUserEvaluationDetailTyList();
//                for (ExamUserEvaluationDetailTy examUserEvaluationDetailTy : examUserEvaluationDetailTyList) {
//                    examUserEvaluationDetailTy.setYear(year.toString());
//                    examUserEvaluationDetailTy.setPositionId(examUserEvaluation.getPositionId());
//                    examUserEvaluationDetailTy.setUserId(userId);
//                    examUserEvaluationDetailTy.setUserName(userById.getUsername());
//                    examUserEvaluationDetailTy.setRecordId(examUserEvaluationDetail.getId());
//                    examUserEvaluationDetailTy.setTiYuKaoPingKeMuMingCheng(examUserEvaluationDetailTy.getTiYuKaoPingKeMuMingCheng());
//                    examUserEvaluationDetailTy.setTiYuKaoPingKeMuChengJi(examUserEvaluationDetailTy.getTiYuKaoPingKeMuChengJi());
//                    examUserEvaluationDetailTy.setLevel(examUserEvaluationDetailTy.getLevel());
//                }
//            }
//        }

        // 个人年度情况-各科目成绩
        List<ExamUserEvaluationDetailTy> examUserEvaluationDetailTyList = new ArrayList<>();
        // 专 业 共 同
        personalProfileDto.getProfessionalCommonDetail().forEach(professionalCommonDetail -> {
            professionalCommonDetail.setType(1);
            examUserEvaluationDetailTyList.add(professionalCommonDetail);
        });
        // 专 业 X X
        personalProfileDto.getProfessionalXXDetail().forEach(professionalCommonDetail -> {
            professionalCommonDetail.setType(2);
            examUserEvaluationDetailTyList.add(professionalCommonDetail);
        });
        // X X 共 同
        personalProfileDto.getXXCommonDetail().forEach(professionalCommonDetail -> {
            professionalCommonDetail.setType(3);
            examUserEvaluationDetailTyList.add(professionalCommonDetail);
        });
        // X X 体 育
        personalProfileDto.getXXSportsDetail().forEach(professionalCommonDetail -> {
            professionalCommonDetail.setType(4);
            examUserEvaluationDetailTyList.add(professionalCommonDetail);
        });

        for (ExamUserEvaluationDetailTy examUserEvaluationDetailTy : examUserEvaluationDetailTyList) {
            examUserEvaluationDetailTy.setYear(year.toString());
            examUserEvaluationDetailTy.setPositionId(examUserEvaluation.getPositionId());
            examUserEvaluationDetailTy.setUserId(userId);
            examUserEvaluationDetailTy.setUserName(userById.getFullname());
            // examUserEvaluationDetailTy.setRecordId(basic.getId());
            examUserEvaluationDetailTyDao.insert(examUserEvaluationDetailTy);
        }
        // 个人年度情况-课目成绩统计
        List<BizSubjectScoreCount> subjectScoreCounts = personalProfileDto.getSubjectScoreCounts();
        subjectScoreCounts.forEach(subjectScoreCount -> {
            subjectScoreCount.setUserArchiveId(basic.getId());
            subjectScoreCount.setYear(year);
        });
        subjectScoreCountManager.saveBatch(subjectScoreCounts);

        //保存xxx成绩与奖惩表（按年成绩明细记录表）
        List<BizUserGrade> bizUserGradeList = personalProfileDto.getBizUserGradeList();
        if (CollectionUtils.isNotEmpty(bizUserGradeList)) {
            for (BizUserGrade bizUserGrade : bizUserGradeList) {
                bizUserGrade.setId(null);
                bizUserGrade.setUserArchiveId(basic.getId());
                bizUserGrade.setUserName(basic.getUserName());
                bizUserGrade.setIdentiCard(basic.getIdentCard());
                bizUserGrade.setTdYear(personalProfileDto.getYear());
                bizUserGradeDao.insert(bizUserGrade);
            }

            BizUserGradeStatic bizUserGradeStatic = bizUserGradeStaticDao.selectOne(new QueryWrapper<BizUserGradeStatic>().eq("user_archive_id_", basic.getId()));
            if (Objects.isNull(bizUserGradeStatic)) {
                bizUserGradeStatic = new BizUserGradeStatic();
            }
            bizUserGradeStatic.setUserArchiveId(basic.getId());
            bizUserGradeStatic.setUserName(basic.getUserName());
            bizUserGradeStatic.setIdentiCard(basic.getIdentCard());
            bizUserGradeStatic.setYear(personalProfileDto.getYear());
            // 拼接所有成绩与奖惩内容 由于事务未提交，这里查询的时候排查掉当前修改年份的数据，并且在后续手动补充该年的数据
            List<BizUserGrade> bizUserGrades = bizUserGradeDao.selectList(new QueryWrapper<BizUserGrade>()
                    .eq("user_archive_id_", basic.getId())
                    .ne("td_year_", year)
            );
            bizUserGrades.addAll(bizUserGradeList);
            bizUserGradeStatic.setGradeContent(bizUserGrades.stream()
                    .map(BizUserGrade::getGradeContent)
                    .collect(Collectors.joining(System.lineSeparator())));
            String rewardsContent = bizUserGrades.stream()
                    .map(BizUserGrade::getRewardsContent)
                    .collect(Collectors.joining(System.lineSeparator()));
            bizUserGradeStatic.setRewardsContent(rewardsContent);
            bizUserGradeStaticManager.saveOrUpdate(bizUserGradeStatic);
        }

        //保存xxx经历表（按年明细记录表）
        List<BizUserThroughDetail> bizUserThroughDetailList = personalProfileDto.getBizUserThroughDetailList();
        if (CollectionUtils.isNotEmpty(bizUserThroughDetailList)) {
            for (BizUserThroughDetail bizUserThroughDetail : bizUserThroughDetailList) {
                bizUserThroughDetail.setId(null);
                bizUserThroughDetail.setUserArchiveId(basic.getId());
                bizUserThroughDetail.setUserName(basic.getUserName());
                bizUserThroughDetail.setIdentiCard(basic.getIdentCard());
                bizUserThroughDetail.setTdYear(personalProfileDto.getYear());
                bizUserThroughDetailDao.insert(bizUserThroughDetail);
            }
            BizUserThroughStatic bizUserThroughStatic1 = bizUserThroughStaticDao.selectOne(
                    new QueryWrapper<BizUserThroughStatic>()
                            .eq("user_archive_id_", basic.getId())
                            .eq("type_", "1")
            );
            if (Objects.isNull(bizUserThroughStatic1)) {
                bizUserThroughStatic1 = new BizUserThroughStatic();
            }
            bizUserThroughStatic1.setUserArchiveId(basic.getId());
            bizUserThroughStatic1.setUserName(basic.getUserName());
            bizUserThroughStatic1.setIdentiCard(basic.getIdentCard());
            // 由于事务未提交，这里查询的时候排查掉当前修改年份的数据，并且在后续手动补充该年的数据
            List<BizUserThroughDetail> bizUserThroughDetails = bizUserThroughDetailDao.selectList(
                    new QueryWrapper<BizUserThroughDetail>()
                            .eq("user_archive_id_", basic.getId())
                            .ne("td_year_", year)
            );
            // 手动添加改年的数据
            bizUserThroughDetails.addAll(bizUserThroughDetailList);
            //筛选出type为1的BizUserThroughDetail
            List<BizUserThroughDetail> bizUserThroughDetailList1 = bizUserThroughDetails.stream()
                    .filter(bizUserThroughDetail -> "1".equals(bizUserThroughDetail.getType()))
                    .collect(Collectors.toList());
            bizUserThroughStatic1.setType("1");
            String field1 = bizUserThroughDetailList1.stream()
                    .sorted(Comparator.comparing(BizUserThroughDetail::getTdYear))
                    .map(BizUserThroughDetail::getField1)
                    .collect(Collectors.joining(System.lineSeparator()));
            bizUserThroughStatic1.setField1(field1);
            String field2 = bizUserThroughDetailList1.stream()
                    .sorted(Comparator.comparing(BizUserThroughDetail::getTdYear))
                    .map(BizUserThroughDetail::getField2)
                    .collect(Collectors.joining(System.lineSeparator()));
            bizUserThroughStatic1.setField2(field2);
            String field3 = bizUserThroughDetailList1.stream()
                    .sorted(Comparator.comparing(BizUserThroughDetail::getTdYear))
                    .map(BizUserThroughDetail::getField3)
                    .collect(Collectors.joining(System.lineSeparator()));
            bizUserThroughStatic1.setField3(field3);
            String field4 = bizUserThroughDetailList1.stream()
                    .sorted(Comparator.comparing(BizUserThroughDetail::getTdYear))
                    .map(BizUserThroughDetail::getField4)
                    .collect(Collectors.joining(System.lineSeparator()));
            bizUserThroughStatic1.setField4(field4);
            bizUserThroughStaticManager.saveOrUpdate(bizUserThroughStatic1);

            List<BizUserThroughDetail> bizUserThroughDetailList2 = bizUserThroughDetails.stream()
                    .filter(bizUserThroughDetail -> "2".equals(bizUserThroughDetail.getType()))
                    .collect(Collectors.toList());
            BizUserThroughStatic bizUserThroughStatic2 = bizUserThroughStaticDao.selectOne(
                    new QueryWrapper<BizUserThroughStatic>()
                            .eq("user_archive_id_", basic.getId())
                            .eq("type_", "2")
            );
            if (Objects.isNull(bizUserThroughStatic2)) {
                bizUserThroughStatic2 = new BizUserThroughStatic();
            }
            bizUserThroughStatic2.setUserArchiveId(basic.getId());
            bizUserThroughStatic2.setUserName(basic.getUserName());
            bizUserThroughStatic2.setIdentiCard(basic.getIdentCard());
            bizUserThroughStatic2.setType("2");
            field1 = bizUserThroughDetailList2.stream()
                    .sorted(Comparator.comparing(BizUserThroughDetail::getTdYear))
                    .map(BizUserThroughDetail::getField1)
                    .collect(Collectors.joining(System.lineSeparator()));
            bizUserThroughStatic2.setField1(field1);
            field2 = bizUserThroughDetailList2.stream()
                    .sorted(Comparator.comparing(BizUserThroughDetail::getTdYear))
                    .map(BizUserThroughDetail::getField2)
                    .collect(Collectors.joining(System.lineSeparator()));
            bizUserThroughStatic2.setField2(field2);
            bizUserThroughStaticManager.saveOrUpdate(bizUserThroughStatic2);
        }

        //XXX资质及成果表（按年明细记录表）
        List<BizUserAchieveDetail> bizUserAchieveDetailList = personalProfileDto.getBizUserAchieveDetailList();
        if (CollectionUtils.isNotEmpty(bizUserAchieveDetailList)) {
            for (BizUserAchieveDetail bizUserAchieveDetail : bizUserAchieveDetailList) {
                bizUserAchieveDetail.setUserArchiveId(basic.getId());
                bizUserAchieveDetail.setUserName(basic.getUserName());
                bizUserAchieveDetail.setIdentiCard(basic.getIdentCard());
                bizUserAchieveDetail.setTdYear(personalProfileDto.getYear());
                bizUserAchieveDetailDao.insert(bizUserAchieveDetail);
            }
            List<BizUserAchieveDetail> bizUserAchieveDetails = bizUserAchieveDetailDao.selectList(
                    new LambdaQueryWrapper<BizUserAchieveDetail>()
                            .eq(BizUserAchieveDetail::getUserArchiveId, basic.getId())
                            .ne(BizUserAchieveDetail::getTdYear, year)
            );
            bizUserAchieveDetails.addAll(bizUserAchieveDetailList);

            LambdaQueryWrapper<BizUserAchieveStatic> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(BizUserAchieveStatic::getUserArchiveId, basic.getId());
            BizUserAchieveStatic bizUserAchieveStatic = bizUserAchieveStaticDao.selectOne(queryWrapper);
            if (Objects.isNull(bizUserAchieveStatic)) {
                bizUserAchieveStatic = new BizUserAchieveStatic();
            }
            bizUserAchieveStatic.setUserArchiveId(basic.getId());
            bizUserAchieveStatic.setUserName(basic.getUserName());
            bizUserAchieveStatic.setIdentiCard(basic.getIdentCard());
            // 查询历年的经历，并且把当年的经历拼接在上面
            bizUserAchieveStatic.setProfessionAssess(joinAssessments(bizUserAchieveDetails, BizUserAchieveDetail::getProfessionAssess));

            bizUserAchieveStatic.setTeachAssess(joinAssessments(bizUserAchieveDetails, BizUserAchieveDetail::getTeachAssess));

            bizUserAchieveStatic.setVocationAssess(joinAssessments(bizUserAchieveDetails, BizUserAchieveDetail::getVocationAssess));

            bizUserAchieveStatic.setPracticeAssess(joinAssessments(bizUserAchieveDetails, BizUserAchieveDetail::getPracticeAssess));

            bizUserAchieveStatic.setArchivement(joinAssessments(bizUserAchieveDetails, BizUserAchieveDetail::getArchivement));

            bizUserAchieveStaticManager.saveOrUpdate(bizUserAchieveStatic);
        }

        //保存xxx工作简历表
        List<BizUserWorkDetail> bizUserWorkDetailList = editPersonalProfileDto.getBizUserWorkDetailList();
        if (CollectionUtils.isNotEmpty(bizUserWorkDetailList)) {
            for (BizUserWorkDetail bizUserWorkDetail : bizUserWorkDetailList) {
                bizUserWorkDetail.setUserArchiveId(basic.getId());
                bizUserWorkDetail.setUserName(basic.getUserName());
                bizUserWorkDetail.setIdentiCard(basic.getIdentCard());
                bizUserWorkDetail.setTdYear(personalProfileDto.getYear());
                bizUserWorkDetailDao.insert(bizUserWorkDetail);
            }
        }

    }

    /**
     * 上传个人图片，返回URL
     *
     * @param file 文件
     * @return URL
     */
    @Override
    public String uploadImage(MultipartFile file) {
        String uriPhoto = "";
        if (file != null) {
            //上传图片
            //验证图片类型
            String ext;
            try {
                ext = CheckFileFormatUtil.getFileType((FileInputStream) file.getInputStream());
                ext = ext.toLowerCase();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            if (StringUtils.isEmpty(ext)) {
                throw new RuntimeException("不能识别的文件格式");
            }

            if (!"bmp,jpg,png,tif,gif,svg,jpeg".contains(ext)) {
                throw new RuntimeException("请上传图片格式文件");
            }
            String originalFilename = file.getOriginalFilename();
            assert originalFilename != null;
            String fileType = originalFilename.substring(originalFilename.lastIndexOf("."));
            try {
                uriPhoto = MinioUtil.uploadRelative(file, "", RandomStringUtils.randomAlphanumeric(100) + fileType, "user");
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

        }
        return uriPhoto;
    }

    /**
     * @param fileName
     * @param response
     */
    @Override
    public void download(String fileName, HttpServletResponse response) {
        try {
            fileName = fileName.replace("user/", "");
            InputStream minioFile = MinioUtil.getMinioFile("user", fileName, true);
            if (minioFile != null) {
                response.setContentType("application/force-download");
                response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
                IOUtils.copy(minioFile, response.getOutputStream());
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public void export(List<String> userIds, Integer year, HttpServletResponse response) {
        if (CollectionUtils.isEmpty(userIds)) {
            return;
        }
        // 创建临时文件夹及对应的临时文件输出
        Path tmpCustomPrefix;
        String zipPath = "";
        try {
            tmpCustomPrefix = Files.createTempDirectory("ftl" + UniqueIdUtil.getSuid());
            zipPath = tmpCustomPrefix.toString();
            String tmpPath = zipPath + "/";
            for (String userId : userIds) {
                PersonalProfileVo personalProfile = this.getPersonalProfile(String.valueOf(year), userId);
                if (Objects.isNull(personalProfile.getBizUserBasic())) {
                    UCFeignService service = AppUtil.getBean(UCFeignService.class);
                    ObjectNode user = (ObjectNode) service.getUserById(userId).getValue();
                    String name = user.get("fullname").asText();
                    throw new RuntimeException(name + "档案不存在，无法导出！");

                }
                if (CollectionUtils.isEmpty(personalProfile.getExamUserEvaluationVoList())) {
                    UCFeignService service = AppUtil.getBean(UCFeignService.class);
                    ObjectNode user = (ObjectNode) service.getUserById(userId).getValue();
                    String name = user.get("fullname").asText();
                    throw new RuntimeException(name + year + "年档案不完善，无法导出！");
                }
                Map<String, Object> map = new HashMap<>();
                map.put("vo", personalProfile);
                map.put("vo2", personalProfile.getExamUserEvaluationVoList().get(0));
                //文件唯一名
                String fileOnlyName = "个人档案_" + personalProfile.getBizUserBasic().getUserName() + ".doc";
                File file = new File(tmpPath + fileOnlyName);
                /** 生成word */
                WordUtil.createWord(response, map, "documentModel.ftl", file.getPath(), fileOnlyName);
            }
            //生成压缩包
            ZipUtil.zip(zipPath, true);
            FileDownloadUtil.fileDownload(response, new File(zipPath + ".zip"), "个人档案.zip");
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            // 删除导出的文件夹目录及压缩包
            FileUtil.deleteFile(zipPath + ".zip");
            File file = new File(zipPath);
            FileUtil.deleteDir(file);
        }
    }

    /**
     * 创建一个通用的拼接方法
     *
     * @param detailList     评估明细列表，用于从中提取评估值。
     * @param assessFunction 用于从每个评估明细中提取评估值的函数（例如：`BizUserAchieveDetail::getProfessionAssess`）。
     * @return 返回拼接后的评估值字符串。如果 `existingValue` 不为空且已经包含新评估值内容，
     * 则返回原始的 `existingValue`，否则返回拼接后的字符串。
     */
    private String joinAssessments(List<BizUserAchieveDetail> detailList,
                                   Function<BizUserAchieveDetail, String> assessFunction) {
        // 获取新评估值的拼接字符串
        return detailList.stream()
                .sorted(Comparator.comparing(BizUserAchieveDetail::getTdYear))
                .map(assessFunction)
                .collect(Collectors.joining(System.lineSeparator()));
    }
}
