package com.artfess.data.manager.impl;

import com.artfess.base.enums.DelStatusEnum;
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.base.util.DictionaryUtils;
import com.artfess.base.util.DmpBeanUtil;
import com.artfess.base.util.StringUtil;
import com.artfess.data.dao.BizExamGeneralPlanDao;
import com.artfess.data.manager.BizExamGeneralPlanManager;
import com.artfess.data.manager.BizExamPlanManager;
import com.artfess.data.manager.BizExamPlanSubjectManager;
import com.artfess.data.manager.BizExamSpaceDataManager;
import com.artfess.data.model.BizExamGeneralPlan;
import com.artfess.data.model.BizExamPlan;
import com.artfess.data.model.BizExamPlanSubject;
import com.artfess.data.model.BizExamSpaceData;
import com.artfess.examine.dao.ExamOrgEvaluationDao;
import com.artfess.examine.dao.ExamUserEvaluationDetailDao;
import com.artfess.examine.manager.ExamEquipmentSysManager;
import com.artfess.examine.manager.ExamSubjectInfoManager;
import com.artfess.examine.model.ExamEquipmentSys;
import com.artfess.examine.model.ExamSubjectInfo;
import com.artfess.examine.vo.OrgVo;
import com.artfess.examine.vo.PositionVo;
import com.artfess.uc.api.model.IUser;
import com.artfess.uc.api.service.IUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Lists;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
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.LocalDate;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 训练总计划 服务实现类
 *
 * @author min.wu
 * @company 阿特菲斯信息技术有限公司
 * @since 2024-12-04
 */
@Service
public class BizExamGeneralPlanManagerImpl extends BaseManagerImpl<BizExamGeneralPlanDao, BizExamGeneralPlan> implements BizExamGeneralPlanManager {

    @Autowired
    private BizExamPlanManager planManager;

    @Resource
    private ExamOrgEvaluationDao orgEvaluationDao;

    @Autowired
    private ExamSubjectInfoManager subjectInfoManager;

    @Autowired
    private BizExamSpaceDataManager spaceDataManager;

    @Autowired
    private ExamEquipmentSysManager equipmentSysManager;

    @Resource
    private ExamUserEvaluationDetailDao userEvaluationDetailDao;

    @Resource
    IUserService userServiceImpl;

    @Autowired
    private BizExamPlanSubjectManager planSubjectManager;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveInfo(BizExamGeneralPlan t) {
        if ("1".equals(t.getPlanType())) {
            if (StringUtil.isEmpty(t.getYear())) {
                t.setYear(String.valueOf(LocalDate.now().getYear()));
            }
        } else if ("2".equals(t.getPlanType())) {
            Assert.hasText(t.getQuarter(), "请填写阶段名称");
        } else if ("3".equals(t.getPlanType())) {
            Assert.notNull(t.getMonth(), "请填写训练月份");
        } else if ("4".equals(t.getPlanType())) {
            Assert.notNull(t.getWeek(), "请填写训练周");
        } else {
            Assert.notNull(t.getStartTime(), "请填写训练开始时间");
            Assert.notNull(t.getEndTime(), "请填写训练结束时间");
        }
        t.setPlanStatus("0");
        boolean save = this.save(t);
        if (save) {
            processPlans(t);
            return save;
        }

        return false;
    }

    private void processPlans(BizExamGeneralPlan t) {

        LambdaQueryWrapper<BizExamPlanSubject> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BizExamPlanSubject::getGeneralPlanId, t.getId());
        planSubjectManager.remove(lambdaQueryWrapper);

        LambdaQueryWrapper<BizExamPlan> bizExamPlanLambdaQueryWrapper = new LambdaQueryWrapper<>();
        bizExamPlanLambdaQueryWrapper.eq(BizExamPlan::getGeneralPlanId, t.getId());
        planManager.remove(bizExamPlanLambdaQueryWrapper);
        List<BizExamPlan> list = Lists.newArrayList();
        t.getPlanList().forEach(plan -> {
            plan.setGeneralPlanId(t.getId());
           //  Assert.hasText(plan.getSubjectId(), "请选择培训的课目");
            Assert.hasText(plan.getOrgId(), "请选择要参与培训的单位");
            String[] split = plan.getOrgId().split(",");
            for (int i = 0; i < split.length; i++) {
                BizExamPlan examPlan = new BizExamPlan();
                examPlan.setGeneralPlanId(t.getId());
                examPlan.setYear(t.getYear());
                examPlan.setQuarter(t.getQuarter());
                examPlan.setWeek(t.getWeek());
                examPlan.setPlanType(t.getPlanType());
                examPlan.setStartTime(t.getStartTime());
                examPlan.setEndTime(t.getEndTime());
                examPlan.setSubjectId(plan.getSubjectId());
                examPlan.setSubjectName(plan.getSubjectName());
                examPlan.setHour(plan.getHour());
                examPlan.setMonth(t.getMonth());
                examPlan.setMemo(t.getMemo());
                examPlan.setCoachId(plan.getCoachId());
                examPlan.setCoachName(plan.getCoachName());
                examPlan.setMajorId(plan.getMajorId());
                examPlan.setMajorName(plan.getMajorName());
                examPlan.setTrainType(plan.getTrainType());
                examPlan.setTrainLevel(plan.getTrainLevel());
                examPlan.setOrgId(split[i]);
                if(StringUtils.isNotEmpty(plan.getOrgName())){
                    examPlan.setOrgName(plan.getOrgName().split(",")[i]);
                }
                examPlan.setPlanStatus("0");
                list.add(examPlan);
            }

        });
        planManager.saveBatch(list);
        planSubjectManager.saveOrUpdateBatch(t.getPlanList());
    }

    @Override
    public BizExamGeneralPlan findById(String id) {
        BizExamGeneralPlan generalPlan = this.get(id);
        Assert.notNull(generalPlan, "训练计划不存在");

        LambdaQueryWrapper<BizExamPlanSubject> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BizExamPlanSubject::getGeneralPlanId, id);
        List<BizExamPlanSubject> planList = planSubjectManager.list(lambdaQueryWrapper);

        generalPlan.setPlanList(planList);
        return generalPlan;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateInfo(BizExamGeneralPlan t) {
        BizExamGeneralPlan generalPlan = this.get(t.getId());
        if (!"0".equals(generalPlan.getPlanStatus())) {
            throw new BaseException("已下发的计划不能进行修改");
        }
        if ("1".equals(t.getPlanType())) {
            if (StringUtil.isEmpty(t.getYear())) {
                t.setYear(String.valueOf(LocalDate.now().getYear()));
            }
        } else if ("2".equals(t.getPlanType())) {
            Assert.hasText(t.getQuarter(), "请填写阶段名称");
        } else if ("3".equals(t.getPlanType())) {
            Assert.notNull(t.getMonth(), "请填写训练月份");
        } else if ("4".equals(t.getPlanType())) {
            Assert.notNull(t.getWeek(), "请填写训练周");
        } else {
            Assert.notNull(t.getStartTime(), "请填写训练开始时间");
            Assert.notNull(t.getEndTime(), "请填写训练结束时间");
        }

        boolean save = this.updateById(t);
        if (save) {
            processPlans(t);
            return save;
        }
        return false;
    }

    @Override
    public void saveList(List<BizExamGeneralPlan> list, String planType) {
        Assert.hasText(planType, "请选择计划类型");
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        BizExamGeneralPlan bizExamGeneralPlan = list.get(0);
        boolean save = this.save(bizExamGeneralPlan);
        if (!save) {
            return;
        }

        QueryWrapper<ExamSubjectInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_dele_", DelStatusEnum.N.getType());
        List<ExamSubjectInfo> subjectInfos = subjectInfoManager.list(queryWrapper);
        Map<String, ExamSubjectInfo> subjectInfoMap = subjectInfos.stream().collect(Collectors.toMap(item -> item.getName(), item -> item));
        List<OrgVo> orgVos = orgEvaluationDao.orgList();
        Map<String, OrgVo> orgMap = orgVos.stream().collect(Collectors.toMap(item -> item.getName(), item -> item));

        QueryWrapper<ExamEquipmentSys> sysQueryWrapper = new QueryWrapper<>();
        sysQueryWrapper.eq("is_dele_", DelStatusEnum.N.getType());
        List<ExamEquipmentSys> sysList = equipmentSysManager.list(sysQueryWrapper);
        Map<String, ExamEquipmentSys> sysMap = sysList.stream().collect(Collectors.toMap(item -> item.getName(), item -> item));

        QueryWrapper<BizExamSpaceData> spaceDataQueryWrapper = new QueryWrapper<>();
        spaceDataQueryWrapper.eq("is_dele_", DelStatusEnum.N.getType());
        List<BizExamSpaceData> spaceDataList = spaceDataManager.list(spaceDataQueryWrapper);
        Map<String, BizExamSpaceData> spaceDateMap = spaceDataList.stream().collect(Collectors.toMap(item -> item.getName(), item -> item));

        List<PositionVo> positionVoList = userEvaluationDetailDao.getPositionList();
        Map<String, PositionVo> positionMap = positionVoList.stream().collect(Collectors.toMap(item -> item.getPositionName(), item -> item));

        List<IUser> userList = userServiceImpl.getUserListByGroup("role", "jly");
        Map<String, IUser> userMap = userList.stream().collect(Collectors.toMap(item -> item.getFullname(), item -> item));

        List<BizExamPlan> planList = DmpBeanUtil.copyList(list, BizExamPlan.class);
        planList.forEach(t -> {
            t.setGeneralPlanId(bizExamGeneralPlan.getId());
            t.setPlanType(planType);
            if (null != DictionaryUtils.getDictInfo("xllb", t.getTrainType())) {
                String trainType = DictionaryUtils.getDictInfo("xllb", t.getTrainType()).getValue();
                t.setTrainType(trainType);
            }

            if (null != DictionaryUtils.getDictInfo("xljb", t.getTrainLevel())) {
                String trainLevel = DictionaryUtils.getDictInfo("xljb", t.getTrainLevel()).getValue();
                t.setTrainLevel(trainLevel);
            }

            if (null != DictionaryUtils.getDictInfo("jdmc", t.getQuarter())) {
                String type = DictionaryUtils.getDictInfo("jdmc", t.getQuarter()).getValue();
                t.setQuarter(type);
            }

            if (null != DictionaryUtils.getDictInfo("xlfs", t.getWay())) {
                String way = DictionaryUtils.getDictInfo("xlfs", t.getWay()).getValue();
                t.setWay(way);
            }

            Assert.notNull(t.getStartTime(), "请填写训练开始时间");
            Assert.notNull(t.getEndTime(), "请填写训练结束时间");
            if ("1".equals(planType)) {
                Assert.hasText(t.getYear(), "请填写年份");
            } else if ("2".equals(planType)) {
                Assert.hasText(t.getQuarter(), "请填写阶段名称");
            } else if ("3".equals(planType)) {
                Assert.notNull(t.getMonth(), "请填写训练月份");
            } else if ("4".equals(planType)) {
                Assert.notNull(t.getWeek(), "请填写训练周");
            }

            if (StringUtils.isNotEmpty(t.getMajorName()) && !CollectionUtils.isEmpty(sysMap) && null != sysMap.get(t.getMajorName().split(",")[0])) {
                t.setMajorId(sysMap.get(t.getMajorName()).getId());
            }

            if (StringUtils.isNotEmpty(t.getMajorName()) && !CollectionUtils.isEmpty(subjectInfoMap) && null != subjectInfoMap.get(t.getSubjectName().split(",")[0])) {
                t.setSubjectId(subjectInfoMap.get(t.getSubjectName()).getId());
            }

            if (StringUtils.isNotEmpty(t.getOrgName()) && !CollectionUtils.isEmpty(orgMap) && null != orgMap.get(t.getOrgName().split(",")[0])) {
                t.setOrgId(orgMap.get(t.getOrgName()).getId());
            }

            if (StringUtils.isNotEmpty(t.getSpaceName()) && !CollectionUtils.isEmpty(spaceDateMap) && null != spaceDateMap.get(t.getSpaceName().split(",")[0])) {
                t.setSpaceId(spaceDateMap.get(t.getSpaceName()).getId());
            }

            if (StringUtils.isNotEmpty(t.getPost()) && !CollectionUtils.isEmpty(positionMap) && null != positionMap.get(t.getPost().split(",")[0])) {
                t.setPostId(positionMap.get(t.getPost()).getPositionId());
            }

            if (StringUtils.isNotEmpty(t.getCoachName()) && !CollectionUtils.isEmpty(userMap) && null != positionMap.get(t.getCoachName().split(",")[0])) {
                t.setCoachId(userMap.get(t.getCoachName()).getUserId());
            }
        });

        planManager.saveBatch(planList);
    }

    @Override
    public void updateStatus(String id) {
        BizExamGeneralPlan bizExamPlan = this.get(id);
        Assert.notNull(bizExamPlan, "训练计划不存在");
        if (!"0".equals(bizExamPlan.getPlanStatus())) {
            throw new BaseException("已下发的计划不能再次下发");
        }
        bizExamPlan.setPlanStatus("1");
        boolean update = this.updateById(bizExamPlan);
    }

    @Override
    public PageList<BizExamGeneralPlan> findByPage(QueryFilter<BizExamGeneralPlan> queryFilter) {
        PageBean pageBean = queryFilter.getPageBean();
        IPage<BizExamGeneralPlan> result = baseMapper.findByPage(convert2IPage(pageBean), convert2Wrapper(queryFilter, currentModelClass()));
        return new PageList<BizExamGeneralPlan>(result);
    }


    //计划超时 定时任务修改状态 每天晚上23点执行
    @Scheduled(cron = "0 0 23 * * ? ")
    public void updatePlanStatus() {
        LambdaQueryWrapper<BizExamGeneralPlan> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        String[] plans = new String[]{"0", "2"};
        lambdaQueryWrapper.notIn(BizExamGeneralPlan::getPlanStatus, Arrays.asList(plans));
        lambdaQueryWrapper.ge(BizExamGeneralPlan::getEndTime, LocalDate.now());
        lambdaQueryWrapper.eq(BizExamGeneralPlan::getIsDele, DelStatusEnum.N.getType());
        List<BizExamGeneralPlan> list = this.list(lambdaQueryWrapper);
        list.forEach(plan -> {
            plan.setPlanStatus("3");
        });
        boolean b = this.updateBatchById(list);
    }
}
