package com.artfess.examine.manager.impl;

import com.artfess.base.exception.BaseException;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.base.query.PageBean;
import com.artfess.base.query.PageList;
import com.artfess.base.query.QueryFilter;
import com.artfess.examine.dao.ExamSubjectInfoDao;
import com.artfess.examine.dao.ExamYearAssessmentSubDao;
import com.artfess.examine.manager.ExamUserEvaluationDetailManager;
import com.artfess.examine.manager.ExamUserEvaluationManager;
import com.artfess.examine.manager.ExamYearAssessmentSubManager;
import com.artfess.examine.model.ExamSubjectInfo;
import com.artfess.examine.model.ExamUserEvaluation;
import com.artfess.examine.model.ExamUserEvaluationDetail;
import com.artfess.examine.model.ExamYearAssessmentSub;
import com.artfess.examine.vo.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

/**
 * 年度考核课目 服务实现类
 *
 * @author min.wu
 * @company 阿特菲斯信息技术有限公司
 * @since 2022-11-25
 */
@Service
public class ExamYearAssessmentSubManagerImpl extends BaseManagerImpl<ExamYearAssessmentSubDao, ExamYearAssessmentSub> implements ExamYearAssessmentSubManager {

    @Resource
    private ExamSubjectInfoDao subjectInfoDao;

    @Autowired
    private ExamUserEvaluationManager userEvaluationManager;

    @Autowired
    private ExamUserEvaluationDetailManager userEvaluationDetailManager;

    @Resource(name = "bmpExecutorService")
    private ExecutorService executorService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createInfo(ExamYearAssessmentSub t) {
        Assert.notEmpty(t.getSubjectInfoList(), "请选择要考核的课目");
        String subjectIds = t.getSubjectInfoList().stream()
                .map(ExamSubjectInfo::getId)
                .collect(Collectors.joining(",", "", ""));
        QueryWrapper<ExamYearAssessmentSub> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("year_", t.getYear());
        queryWrapper.eq("position_id_", t.getPositionId());
        queryWrapper.in("subject_ids_", subjectIds);
        List<ExamYearAssessmentSub> examYearAssessmentSubs = this.baseMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(examYearAssessmentSubs)) {
            throw new BaseException("该岗位今年已配置考核课目，请检查配置信息");
        }
        List<ExamYearAssessmentSub> list =Lists.newArrayList();
        t.getSubjectInfoList().forEach(subjectInfo ->{
            ExamYearAssessmentSub sub = new ExamYearAssessmentSub();
            sub.setPositionId(t.getPositionId());
            sub.setSubjectIds(subjectInfo.getId());
            sub.setSubjectName(subjectInfo.getName());
            sub.setYear(t.getYear());
            list.add(sub);
        });
        boolean b = this.saveBatch(list);
        if (b) {
            executorService.execute(() -> {
                try {
                    List<UserInfoVo> userInfoList = this.baseMapper.getUserInfoList(t.getPositionId());
                    list.forEach(sub -> {
                        processUserEvaluation(userInfoList, sub);
                    });
                } catch (Exception e) {
                    log.error("创建年度考核记录失败:{}", e);
                }
            });
        }
        return b;
    }

    private void processUserEvaluation(List<UserInfoVo> userInfoList, ExamYearAssessmentSub t) {
        QueryWrapper<ExamUserEvaluation> query = new QueryWrapper<>();
        query.eq("position_id_", t.getPositionId());
        query.eq("year_", t.getYear());
        List<ExamUserEvaluation> examUserEvaluations = userEvaluationManager.getBaseMapper().selectList(query);
        Map<String, ExamUserEvaluation> userEvaluationMap = Maps.newHashMap();
        if (!CollectionUtils.isEmpty(examUserEvaluations)) {
            userEvaluationMap = examUserEvaluations.stream().collect(Collectors.toMap(item -> item.getUserId(), item -> item));
        }
        List<ExamUserEvaluation> list = Lists.newArrayList();
        List<ExamUserEvaluationDetail> detailList = Lists.newArrayList();
        for (UserInfoVo userInfoVo : userInfoList) {
            ExamUserEvaluation examUserEvaluation = null;
            if (!CollectionUtils.isEmpty(userEvaluationMap) && userEvaluationMap.containsKey(userInfoVo.getUserId())) {
                examUserEvaluation = userEvaluationMap.get(userInfoVo.getUserId());
                examUserEvaluation.setNotCount(examUserEvaluation.getNotCount() + 1);
                examUserEvaluation.setTotalCount(examUserEvaluation.getTotalCount() + 1);
                examUserEvaluation.setSubjectId(examUserEvaluation.getSubjectId() + "," + t.getSubjectIds());
                examUserEvaluation.setSubjectName(examUserEvaluation.getSubjectName() + "," + t.getSubjectName());
            } else {
                examUserEvaluation = new ExamUserEvaluation();
                examUserEvaluation.setYear(t.getYear());
                examUserEvaluation.setPositionId(t.getPositionId());
                examUserEvaluation.setUserId(userInfoVo.getUserId());
                examUserEvaluation.setUserName(userInfoVo.getUserName());
                examUserEvaluation.setInCount(0);
                examUserEvaluation.setNotCount(1);
                examUserEvaluation.setTotalCount(1);
                examUserEvaluation.setSubjectName(t.getSubjectName());
                examUserEvaluation.setSubjectId(t.getSubjectIds());
            }
            list.add(examUserEvaluation);
            ExamUserEvaluationDetail examUserEvaluationDetail = new ExamUserEvaluationDetail();
            examUserEvaluationDetail.setPositionId(examUserEvaluation.getPositionId());
            examUserEvaluationDetail.setSubjectId(t.getSubjectIds());
            examUserEvaluationDetail.setSubjectName(t.getSubjectName());
            examUserEvaluationDetail.setType("1");
            examUserEvaluationDetail.setUserId(examUserEvaluation.getUserId());
            examUserEvaluationDetail.setUserName(examUserEvaluation.getUserName());
            examUserEvaluationDetail.setYear(examUserEvaluation.getYear());
            detailList.add(examUserEvaluationDetail);
        }
        userEvaluationManager.saveOrUpdateBatch(list);
        userEvaluationDetailManager.saveBatch(detailList);

    }

    //todo 废弃
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateInfo(ExamYearAssessmentSub t) {
        Assert.notEmpty(t.getSubjectInfoList(), "请选择要考核的课目");
        ExamYearAssessmentSub sub = this.baseMapper.selectById(t.getId());
        QueryWrapper<ExamUserEvaluation> query = new QueryWrapper<>();
        query.eq("position_id_", sub.getPositionId());
        query.eq("year_", sub.getYear());
        query.like("subject_id_", sub.getSubjectIds());
        query.gt("in_count_", 0);
        List<ExamUserEvaluation> examUserEvaluations = userEvaluationManager.getBaseMapper().selectList(query);
        if(!CollectionUtils.isEmpty(examUserEvaluations)) {
            throw new BaseException("当前要修改的科目加入年度考核中，不能进行修改");
        }

        QueryWrapper<ExamYearAssessmentSub> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("year_", t.getYear());
        queryWrapper.eq("position_id_", t.getPositionId());
        queryWrapper.ne("id_", t.getId());
        List<ExamYearAssessmentSub> examYearAssessmentSubs = this.baseMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(examYearAssessmentSubs)) {
            throw new BaseException("该岗位今年已配置考核课目，请检查配置信息");
        }
        String subjectNames = t.getSubjectInfoList().stream()
                .map(ExamSubjectInfo::getName)
                .collect(Collectors.joining(",", "", ""));
        String subjectIds = t.getSubjectInfoList().stream()
                .map(ExamSubjectInfo::getId)
                .collect(Collectors.joining(",", "", ""));
        t.setSubjectIds(subjectIds);
        t.setSubjectName(subjectNames);
        boolean b = this.updateById(t);
        if(b) {
            executorService.execute(() -> {
                try {
                    if(!sub.getSubjectIds().equals(t.getSubjectIds())) {
                        List<UserInfoVo> userInfoList = this.baseMapper.getUserInfoList(t.getPositionId());
                        updateUserEvaluation(userInfoList, t, sub);
                    }
                } catch (Exception e) {
                    log.error("创建年度考核记录失败:{}", e);
                }
            });


        }
        return b;
    }

    private void updateUserEvaluation(List<UserInfoVo> userInfoList, ExamYearAssessmentSub t, ExamYearAssessmentSub sub) {
        QueryWrapper<ExamUserEvaluation> query = new QueryWrapper<>();
        query.eq("position_id_", t.getPositionId());
        query.eq("year_", t.getYear());
        List<ExamUserEvaluation> examUserEvaluations = userEvaluationManager.getBaseMapper().selectList(query);
        Map<String, ExamUserEvaluation> userEvaluationMap = Maps.newHashMap();
        if (!CollectionUtils.isEmpty(examUserEvaluations)) {
            userEvaluationMap = examUserEvaluations.stream().collect(Collectors.toMap(item -> item.getUserId(), item -> item));
        }
        List<ExamUserEvaluation> list = Lists.newArrayList();
        List<ExamUserEvaluationDetail> detailList = Lists.newArrayList();
        for (UserInfoVo userInfoVo : userInfoList) {
            ExamUserEvaluation examUserEvaluation = null;
            if (!CollectionUtils.isEmpty(userEvaluationMap) && userEvaluationMap.containsKey(userInfoVo.getUserId())) {
                examUserEvaluation = userEvaluationMap.get(userInfoVo.getUserId());
                examUserEvaluation.setSubjectId(examUserEvaluation.getSubjectId().replace(sub.getSubjectIds(), t.getSubjectIds()));
                examUserEvaluation.setSubjectName(examUserEvaluation.getSubjectName().replace(sub.getSubjectName(), t.getSubjectName()));
            } else {
                examUserEvaluation = new ExamUserEvaluation();
                examUserEvaluation.setYear(t.getYear());
                examUserEvaluation.setPositionId(t.getPositionId());
                examUserEvaluation.setUserId(userInfoVo.getUserId());
                examUserEvaluation.setUserName(userInfoVo.getUserName());
                examUserEvaluation.setInCount(0);
                examUserEvaluation.setNotCount(1);
                examUserEvaluation.setTotalCount(1);
                examUserEvaluation.setSubjectName(t.getSubjectName());
                examUserEvaluation.setSubjectId(t.getSubjectIds());
            }
            list.add(examUserEvaluation);

        }
        userEvaluationManager.saveOrUpdateBatch(list);
        userEvaluationDetailManager.saveBatch(detailList);
    }


    @Override
    public ExamYearAssessmentSub findById(String id) {
        ExamYearAssessmentSub sub = this.baseMapper.selectById(id);
        QueryWrapper<ExamSubjectInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id_", Arrays.asList(sub.getSubjectIds().split(",")));
        List<ExamSubjectInfo> examSubjectInfos = subjectInfoDao.selectList(queryWrapper);
        sub.setSubjectInfoList(examSubjectInfos);
        return sub;
    }

    @Override
    public List<ExamSubjectInfo> findByPositionId(String positionId) {
        QueryWrapper<ExamYearAssessmentSub> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("year_", String.valueOf(LocalDateTime.now().getYear()));
        queryWrapper.eq("position_id_", positionId);
        ExamYearAssessmentSub sub = this.baseMapper.selectOne(queryWrapper);
        List<String> strings = Arrays.asList(sub.getSubjectIds().split(","));
        QueryWrapper<ExamSubjectInfo> query = new QueryWrapper<>();
        query.in("id_", strings);
        List<ExamSubjectInfo> examSubjectInfos = subjectInfoDao.selectList(query);
        return examSubjectInfos;
    }

    @Override
    public PageList<ExamSubjectInfo> findByPage(QueryFilter<ExamSubjectInfo> queryFilter) {

        PageBean pageBean = queryFilter.getPageBean();
        IPage<ExamSubjectInfo> result = baseMapper.findByPage(convert2IPage(pageBean), convert2Wrapper(queryFilter, currentModelClass()), queryFilter.getParams());
        return new PageList<ExamSubjectInfo>(result);
    }
}
