package com.artfess.examine.manager.impl;

import com.alibaba.fastjson.JSONObject;
import com.artfess.base.enums.TrainLevelEnum;
import com.artfess.base.enums.TrainTypeEnum;
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.BeanUtils;
import com.artfess.base.util.StringUtil;
import com.artfess.examine.dao.ExamEquipmentSysDao;
import com.artfess.examine.dao.ExamPosSysDao;
import com.artfess.examine.dao.ExamSubjectInfoDao;
import com.artfess.examine.dao.ExamSubjectPosDao;
import com.artfess.examine.dao.ExamSubjectSysDao;
import com.artfess.examine.manager.ExamSubjectInfoManager;
import com.artfess.examine.model.ExamEquipmentSys;
import com.artfess.examine.model.ExamSubjectInfo;
import com.artfess.examine.model.ExamSubjectPos;
import com.artfess.examine.model.ExamSubjectSys;
import com.artfess.examine.model.ExamSubjectType;
import com.artfess.examine.vo.PositionVo;
import com.artfess.examine.vo.SubjectReqVo;
import com.artfess.examine.vo.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.api.client.util.Sets;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;

/**
 * 训练考试课目 服务实现类
 *
 * @author min.wu
 * @company 阿特菲斯信息技术有限公司
 * @since 2022-10-19
 */
@Slf4j
@Service
public class ExamSubjectInfoManagerImpl extends BaseManagerImpl<ExamSubjectInfoDao, ExamSubjectInfo> implements ExamSubjectInfoManager {

    @Resource
    private ExamSubjectPosDao subjectPosDao;

    @Resource
    private ExamSubjectSysDao subjectSysDao;

    @Resource
    private ExamEquipmentSysDao equipmentSysDao;

    @Resource
    private ExamPosSysDao posSysDao;

    @Override
    public List<ExamSubjectType> getTree(ExamSubjectInfo entity) {


        List<ExamSubjectType> treeList = Lists.newArrayList();
        List<ExamSubjectType> orgs = this.baseMapper.getOrgList();
        treeList.addAll(orgs);
//        List<ExamSubjectType> list = this.baseMapper.getExamSysInfo();
//        treeList.addAll(list);
//todo暂时不改
//        Map<String, Object> trainTypeMap = Maps.newHashMap();
//        trainTypeMap.put("1", "专业岗位");
//        trainTypeMap.put("2", "专业岗位");
//        trainTypeMap.put("3", "专业岗位");
//        List<ExamSubjectType> posts = this.baseMapper.getPositions();
//        posts.forEach(post -> {
//            if (StringUtil.isNotEmpty(post.getSysId())) {
//                post.setParentId(post.getSysId());
//            } else {
//                post.setParentId(post.getOrgId());
//            }
//
//            post.setType("2");
//        });
//        treeList.addAll(posts);

        List<ExamSubjectType> posts = this.baseMapper.getPositions();
        posts.forEach(post -> {
            if(StringUtil.isNotEmpty(post.getSysId())){
                post.setParentId(post.getSysId());
            }else{
                post.setParentId(post.getOrgId());
            }

            post.setType("2");
        });
        treeList.addAll(posts);

        List<JSONObject> subjectList = baseMapper.getSubjectList(entity);
        subjectList.forEach(subject -> {
            ExamSubjectType examSubjectType = new ExamSubjectType();
            examSubjectType.setType("3");
            examSubjectType.setName(subject.getString("name"));
            examSubjectType.setId(subject.getString("id"));
            String parentId = "0";
            if (!StringUtils.isEmpty(subject.getString("positionid"))) {
                parentId = subject.getString("positionid");
            } else if (StringUtils.isEmpty(subject.getString("positionid"))) {
                parentId = subject.getString("orgid");
            }
            examSubjectType.setParentId(parentId);
            treeList.add(examSubjectType);
        });
        List<ExamSubjectType> subjectInfoList = treeList.stream().collect(
                Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(ExamSubjectType::getId))), ArrayList::new));
        List<ExamSubjectType> tree = BeanUtils.listToTree(subjectInfoList);
        return tree;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void subjectBindPosition(ExamSubjectInfo entity) {
        QueryWrapper<ExamSubjectPos> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("subject_id_", entity.getId());
        subjectPosDao.delete(queryWrapper);
        if (CollectionUtils.isEmpty(entity.getPositonVos())) {
            return;
        }
        entity.getPositonVos().forEach(positionVo -> {
            ExamSubjectPos subjectPos = new ExamSubjectPos();
            subjectPos.setPositionId(positionVo.getPositionId());
            subjectPos.setSubjectId(entity.getId());
            subjectPosDao.insert(subjectPos);
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateInfo(ExamSubjectInfo t) {
        int count = this.vaildSubject(t.getName(), t.getPositonVos(), t.getId());
        if (count > 0) {
            throw new BaseException(t.getName() + "已重复");
        }
        int insert = this.baseMapper.updateById(t);
        if (insert > 0) {
            processPositionInfo(t);
            return true;
        }
        return false;
    }

    @Override
    public List<ExamSubjectPos> findByBindPos(String id) {
        QueryWrapper<ExamSubjectPos> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("subject_id_", id);
        return subjectPosDao.selectList(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createInfo(ExamSubjectInfo t) {
        int count = this.vaildSubject(t.getName(), t.getPositonVos(), null);
        if (count > 0) {
            throw new BaseException(t.getName() + "已重复");
        }
        int insert = this.baseMapper.insert(t);
        if (insert > 0) {
            processPositionInfo(t);
            return true;
        }
        return false;
    }

    private int vaildSubject(String name, List<PositionVo> positonVos, String id) {
        Set<String> majorIds = Sets.newHashSet();
        List<String> positionIds = Lists.newArrayList();
        positonVos.forEach(positionVo -> {
            if (!StringUtils.isEmpty(positionVo.getPositionId())) {
                positionIds.add(positionVo.getPositionId());
            }

            return;

        });
        ArrayList<String> strings = new ArrayList<>(majorIds);
        return this.baseMapper.getSubjectCount(name, positionIds, strings, id);
    }

    @Override
    public List<ExamSubjectPos> findBySubjectIds(SubjectReqVo t) {

        QueryWrapper<ExamSubjectPos> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("subject_id_", t.getSubjectIds());
        List<ExamSubjectPos> subjectPosList = subjectPosDao.selectList(queryWrapper);
        return subjectPosList;
    }

    @Override
    public List<ExamSubjectInfo> findByMajorIds(SubjectReqVo t) {
        return this.baseMapper.findByMajorIds(t);
    }

    @Override
    public ExamSubjectInfo findById(String id) {
        ExamSubjectInfo examSubjectInfo = this.baseMapper.selectById(id);
        List<PositionVo> list = this.baseMapper.getPositionInfo(id);
        examSubjectInfo.setPositonVos(list);
        return examSubjectInfo;
    }

    @Override
    public PageList<ExamSubjectInfo> findByPage(QueryFilter<ExamSubjectInfo> queryFilter) {
        PageBean pageBean = queryFilter.getPageBean();
        IPage<ExamSubjectInfo> result = baseMapper.queryPage(convert2IPage(pageBean), convert2Wrapper(queryFilter, currentModelClass()));
        List<String> subjectIds = result.getRecords().stream().map(ExamSubjectInfo::getId).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(subjectIds)) {
            List<ExamEquipmentSys> list = baseMapper.findBySubjectIds(subjectIds);
            Map<String, String> map = Maps.newHashMap();
            list.forEach(examEquipmentSys -> {
                if (map.containsKey(examEquipmentSys.getSubjectId())) {
                    map.put(examEquipmentSys.getSubjectId(), map.get(examEquipmentSys.getSubjectId()) + "," + examEquipmentSys.getName());
                } else {
                    map.put(examEquipmentSys.getSubjectId(), examEquipmentSys.getName());
                }
            });
            result.getRecords().forEach(subject -> {
                if (map.containsKey(subject.getId())) {
                    subject.setMajorName(map.get(subject.getId()));
                }
            });
        }


        return new PageList<ExamSubjectInfo>(result);
    }

    @Override
    public List<ExamSubjectInfo> getSubjectList(SubjectReqVo t) {
        QueryWrapper<ExamSubjectInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id_", t.getSubjectIds());
        return this.baseMapper.selectList(queryWrapper);
    }

    @Override
    public List<UserInfoVo> getSubjectUserList(SubjectReqVo t) {

        List<UserInfoVo> subjectUserList = this.baseMapper.getSubjectUserList(t);
        Map<String, UserInfoVo> userInfoVoMap = Maps.newHashMap();
        subjectUserList.forEach(userInfoVo -> {
            userInfoVoMap.put(userInfoVo.getUserId(), userInfoVo);
        });
        List<UserInfoVo> list = Lists.newArrayList();
        userInfoVoMap.forEach((key, value) -> {
            list.add(value);
        });
        return list;
    }

    @Override
    public PageList<ExamSubjectInfo> notSubjectPage(QueryFilter<ExamSubjectInfo> queryFilter) {
        PageBean pageBean = queryFilter.getPageBean();
        IPage<ExamSubjectInfo> result = baseMapper.notSubjectPage(convert2IPage(pageBean), convert2Wrapper(queryFilter, currentModelClass()), queryFilter.getParams());
        return new PageList<ExamSubjectInfo>(result);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean importExcel(List<ExamSubjectInfo> list) {
        list.forEach(subject -> {

            subject.setTrainLevel(TrainLevelEnum.getType(subject.getTrainLevel()));
            subject.setTrainType(TrainTypeEnum.getType(subject.getTrainType()));
            if (!StringUtils.isEmpty(subject.getUserTypeId())) {
                subject.setUserTypeId(this.baseMapper.getuserTypeId(subject.getUserTypeId()));
            }
            this.baseMapper.insert(subject);
            String orgId = posSysDao.findByOrgName(subject.getOrgName());
            String positionId = null;
            if (!StringUtils.isEmpty(subject.getPositonNames())) {
                positionId = this.baseMapper.getPositionId(orgId, subject.getPositonNames());
            }

            ExamSubjectPos subjectPos = new ExamSubjectPos();
            subjectPos.setPositionId(positionId);
            subjectPos.setSubjectId(subject.getId());
            subjectPos.setOrgId(orgId);
            subjectPos.setFullId(orgId + "/" + positionId + "/" + subject.getId());
            subjectPosDao.insert(subjectPos);

        });
        return true;
    }

    @Override
    public PageList<UserInfoVo> coachSubjectList(QueryFilter<ExamSubjectInfo> queryFilter) {
        PageBean pageBean = queryFilter.getPageBean();
        IPage<UserInfoVo> result = baseMapper.coachSubjectList(convert2IPage(pageBean), convert2Wrapper(queryFilter, currentModelClass()));
        return new PageList<UserInfoVo>(result);
    }


    private void processPositionInfo(ExamSubjectInfo t) {
        if (CollectionUtils.isEmpty(t.getPositonVos())) {
            return;
        }
        QueryWrapper<ExamSubjectPos> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("subject_id_", t.getId());
        subjectPosDao.delete(queryWrapper);

        QueryWrapper<ExamSubjectSys> query = new QueryWrapper<>();
        query.eq("subject_id_", t.getId());
        subjectSysDao.delete(query);
        Set<String> majorIds = Sets.newHashSet();
        t.getPositonVos().forEach(positionVo -> {
            if (!StringUtils.isEmpty(positionVo.getPositionId())) {
                ExamSubjectPos subjectPos = new ExamSubjectPos();
                subjectPos.setPositionId(positionVo.getPositionId());
                subjectPos.setSubjectId(t.getId());
                subjectPos.setOrgId(positionVo.getOrgId());
                subjectPos.setFullId(positionVo.getOrgId() + "/" + positionVo.getPositionId() + "/" + t.getId());
                subjectPosDao.insert(subjectPos);
            }

            return;

        });

        if (CollectionUtils.isEmpty(majorIds)) {
            return;
        }
        ArrayList<String> strings = new ArrayList<>(majorIds);
        strings.forEach(majorId -> {
            ExamSubjectSys subjectPos = new ExamSubjectSys();
            subjectPos.setSubjectId(t.getId());
            subjectPos.setMajorId(majorId);
            subjectSysDao.insert(subjectPos);
        });

    }
}
