package com.yiboshi.science.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yiboshi.arch.exception.BusinessException;
import com.yiboshi.science.base.BaseServiceImpl;
import com.yiboshi.science.base.Pagination;
import com.yiboshi.science.dao.ComTalentApplyDAO;
import com.yiboshi.science.dao.ComTalentGroupDAO;
import com.yiboshi.science.entity.*;
import com.yiboshi.science.enumeration.CommonEnum;
import com.yiboshi.science.param.dto.*;
import com.yiboshi.science.param.query.ComTalentGroupQueryVO;
import com.yiboshi.science.service.*;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 人才分组表 Service 实现类
 *
 * @author xujun
 * @version 2025-07-23
 */

@Service
@AllArgsConstructor
public class ComTalentGroupServiceImpl extends BaseServiceImpl<ComTalentGroupDAO, ComTalentGroupQueryVO, ComTalentGroupDTO, ComTalentGroup> implements ComTalentGroupService {

    @Autowired
    private ComTalentGroupDAO comTalentGroupDAO;

    @Autowired
    private ComTalentApplyDAO comTalentApplyDAO;

    @Autowired
    private ComTalentGroupAssignService comTalentGroupAssignService;

    @Autowired
    private ComTalentGroupDetailService comTalentGroupDetailService;

    @Autowired
    private ComTalentAssignService comTalentAssignService;

    @Autowired
    private ComBatchService comBatchService;

    @Override
    protected void setCriteriaForQuery(ComTalentGroupQueryVO vo, QueryWrapper<ComTalentGroupQueryVO> criteria) {

        if (Objects.nonNull(vo.getGroupYear())) {
            criteria.eq("group_year", vo.getGroupYear());
        }
        if (Objects.nonNull(vo.getGroupName())) {
            criteria.like("group_name", vo.getGroupName());
        }
        if (Objects.nonNull(vo.getAssignState())) {
            criteria.eq("assign_state", vo.getAssignState());
        }
    }

    public Pagination<ComTalentGroupDTO> getTalentGroupListByPage(ComTalentGroupQueryVO vo) {
        QueryWrapper criteria = new QueryWrapper();
        setCriteriaForQuery(vo, criteria);
        Page<ComTalentGroupQueryVO> page = new Page<>(vo.getPageIndex(), vo.getPageSize());
        List<ComTalentGroupDTO> dtoList = comTalentGroupDAO.getListByPage(page, criteria).getRecords();
        if (null != dtoList && dtoList.size() != 0) {
            dtoList.forEach((e) -> {
                e.setExpertList(comTalentGroupAssignService.getAssignExpertList(e.getId()));
                e.setTalentList(comTalentGroupDetailService.getTalentDetailList(e.getId()));
            });
        }
        return new Pagination<>(dtoList, page.getTotal(), vo.getPageSize());
    }

    private String InsertTalentGroup(int ReportYear, int TalentCount, String TalentGroupName, String Remark) {
        ComTalentGroup entity = new ComTalentGroup();
        entity.setGroupYear(ReportYear);
        entity.setGroupName(TalentGroupName);
        entity.setTalentCount(TalentCount);
        entity.setExpertCount(0);
        entity.setRemark(Remark);
        entity.setAssignState(0);
        return this.insert(entity);
    }

    private void JoinTalentGroup(String groupId, String talentId) {
        ComTalentGroupDetailDTO dto = comTalentGroupDetailService.getTalentGroupDetailByGP(groupId, talentId);
        if (null == dto) {
            ComTalentGroupDetail detailEntity = new ComTalentGroupDetail();
            detailEntity.setGroupId(groupId);
            detailEntity.setTalentId(talentId);
            comTalentGroupDetailService.insert(detailEntity);
        }
    }

    public void CalculateGroupTalentCount(String groupId) {
        List<ComTalentGroupDetailDTO> list = comTalentGroupDetailService.getTalentDetailList(groupId);
        ComTalentGroup model = new ComTalentGroup();
        model.setId(groupId);
        if (null == list || list.size() == 0)
            model.setTalentCount(0);
        else
            model.setTalentCount(list.size());
        this.update(model);
    }

    public void CalculateGroupExpertCount(String groupId) {
        List<ComTalentGroupAssignDTO> list = comTalentGroupAssignService.getAssignExpertList(groupId);
        ComTalentGroup model = new ComTalentGroup();
        model.setId(groupId);
        if (null == list || list.size() == 0) {
            model.setExpertCount(0);
            model.setAssignState(0);
        } else {
            model.setExpertCount(list.size());
            model.setAssignState(1);
        }
        this.update(model);
    }

    @Transactional
    public boolean InsertTalentGroup(List<String> IdList, String groupId) {
        ComTalentGroupDTO dto = this.getGroupById(groupId);
        if (null == dto)
            return false;
        IdList.forEach(e -> {
            ComTalentGroupDetail model = new ComTalentGroupDetail();
            model.setTalentId(e);
            model.setGroupId(groupId);
            comTalentGroupDetailService.insert(model);
        });
        processGroupTalentExpert(groupId);
        CalculateGroupTalentCount(groupId);
        return true;
    }

    @Transactional
    public boolean updataTalentGroupAdjust(List<String> IdList, String groupId) {
        ComTalentGroupDetail entity = comTalentGroupDetailService.entityById(IdList.get(0));
        String oldGroupId = entity.getGroupId();
        ComTalentGroupDTO dto = this.getGroupById(oldGroupId);
        if (null != dto.getExpertCount() && dto.getExpertCount() > 0)
            return false;
        dto = this.getGroupById(groupId);
        if (null != dto.getExpertCount() && dto.getExpertCount() > 0)
            return false;

        IdList.forEach(e -> {
            ComTalentGroupDetail model = new ComTalentGroupDetail();
            model.setId(e);
            model.setGroupId(groupId);
            comTalentGroupDetailService.update(model);
        });
        CalculateGroupTalentCount(oldGroupId);
        CalculateGroupTalentCount(groupId);
        CalculateGroupExpertCount(oldGroupId);
        CalculateGroupExpertCount(groupId);
        return true;
    }

    public ComTalentGroupDTO getGroupById(String id) {
        ComTalentGroup model = this.entityById(id);
        ComTalentGroupDTO dto = convert2DTO(model);
        dto.setExpertList(comTalentGroupAssignService.getAssignExpertList(dto.getId()));
        return dto;
    }

    @Transactional
    public String save(ComTalentGroupDTO group) {
        if (null == group.getId()) {
            return insertGroup(group);
        } else {
            return updateGroup(group);
        }
    }

    public String insertGroup(ComTalentGroupDTO group) {
        ComTalentGroup model = this.convert2Entity(group);
        return this.insert(model);
    }

    public String updateGroup(ComTalentGroupDTO group) {
        ComTalentGroup model = this.convert2Entity(group);
        return this.update(model);
    }

    public String deleteByGroupId(String id) {
        this.deleteById(id);
        return id;
    }

    /**
     * 项目专家分配
     *
     * @param groupId
     * @return
     */
    @Transactional
    public void processGroupTalentExpert(String groupId) {
        ComTalentGroupDTO dto = getGroupById(groupId);
        if (null == dto)
            return;

        List<ComTalentGroupDetailDTO> talentDetailList = comTalentGroupDetailService.getTalentDetailList(groupId);
        List<ComTalentGroupAssignDTO> expertDetailList = comTalentGroupAssignService.getAssignExpertList(groupId);

        if (null == talentDetailList || talentDetailList.size() == 0)
            return;

        if (null == expertDetailList || expertDetailList.size() == 0)
            return;

        talentDetailList.forEach(e -> {
            expertDetailList.forEach(p -> {
                ComTalentAssign entity = new ComTalentAssign();
                entity.setTalentId(e.getTalentId());
                entity.setExpertId(p.getExpertId());
                List<ComTalentAssign> list = comTalentAssignService.entityList(entity);
                if (null == list || list.size() == 0) {
                    ComTalentAssign assign = new ComTalentAssign();
                    assign.setTalentId(e.getTalentId());
                    assign.setExpertId(p.getExpertId());
                    assign.setAssignYear(dto.getGroupYear());
                    comTalentAssignService.insert(assign);
                    comTalentAssignService.updateAssignState(e.getTalentId());
                }
            });
        });
    }

    @Transactional
    public String assignTalentGroup(int systemType, List<String> GroupList, List<String> ExpertList) {
        GroupList.forEach(g -> {
            ExpertList.forEach(e -> {
                ComTalentGroupAssign entity = new ComTalentGroupAssign();
                entity.setGroupId(g);
                entity.setExpertId(e);
                if (null == comTalentGroupAssignService.getEntity(entity)) {
                    entity = new ComTalentGroupAssign();
                    entity.setGroupId(g);
                    entity.setExpertId(e);
                    comTalentGroupAssignService.insert(entity);
                }
            });
        });

        List<ComTalentGroupDetailDTO> TalentInfoList = comTalentGroupDetailService.getTalentListByGroupIds(GroupList);
        Integer reportYear = comBatchService.getReportYear(systemType, CommonEnum.timeType.talentApply.getCode());
        List<String> TalentList = new ArrayList<>();
        TalentInfoList.forEach(p -> {
            TalentList.add(p.getTalentId());
        });

        String strContent = comTalentAssignService.assignTalent(reportYear, TalentList, ExpertList);

        GroupList.forEach(g -> {
            this.CalculateGroupExpertCount(g);
        });

        return strContent;
    }

    @Transactional
    public String deleteAssignGroupExpert(String id) {
        ComTalentGroupAssign comTalentGroupAssign = comTalentGroupAssignService.getById(id);
        if (null == comTalentGroupAssign)
            throw new BusinessException("分配记录已删除！");

        List<ComTalentGroupDetailDTO> talentDetailList = comTalentGroupDetailService.getTalentDetailList(comTalentGroupAssign.getGroupId());
        talentDetailList.forEach(e -> {
            ComTalentAssign entity = new ComTalentAssign();
            entity.setTalentId(e.getTalentId());
            entity.setExpertId(comTalentGroupAssign.getExpertId());
            comTalentAssignService.delete(entity);
            comTalentAssignService.updateAssignState(e.getTalentId());
        });

        List<ComTalentGroupDTO> list = comTalentAssignService.getTalentGroupAssignById(comTalentGroupAssign.getGroupId(), comTalentGroupAssign.getExpertId());
        if (null != list && list.size() > 0) {
            list.forEach(e -> {
                this.deleteById(e.getAssignId());
            });
        }
        comTalentGroupAssignService.deleteById(id);
        this.CalculateGroupExpertCount(comTalentGroupAssign.getGroupId());

        return id;
    }

    @Transactional
    public boolean deleteGroupTalentExpert(String groupId, String talentId) {
        ComTalentGroupDTO dto = getGroupById(groupId);
        if (null == dto)
            return false;

        List<ComTalentGroupDetailDTO> talentDetailList = comTalentGroupDetailService.getTalentDetailList(groupId);
        List<ComTalentGroupAssignDTO> expertDetailList = comTalentGroupAssignService.getAssignExpertList(groupId);

        if (null == talentDetailList || talentDetailList.size() == 0)
            return false;

        //判断是否分配了专家(分配了专家的项目不能移除)
        if (null != expertDetailList && expertDetailList.size() > 0)
            return false;

        talentDetailList.forEach(e -> {
            if (e.getGroupId().equals(groupId) && e.getTalentId().equals(talentId)) {
                comTalentGroupDetailService.deleteById(e.getId());
                comTalentAssignService.updateAssignState(talentId);
            }
        });

        expertDetailList.forEach(e -> {
            ComTalentAssign entity = new ComTalentAssign();
            entity.setExpertId(e.getExpertId());
            entity.setTalentId(talentId);
            comTalentAssignService.delete(entity);
        });

        this.CalculateGroupTalentCount(groupId);
        this.CalculateGroupExpertCount(groupId);
        return true;
    }

    /**
     * 项目二级学科统计
     *
     * @param groupId
     * @return
     */
    public List<ComTalentKnowledgeStatisticDTO> getTalentKnowledgeStatisticByGroupId(String groupId) {
        List<ComTalentKnowledgeStatisticDTO> list = comTalentGroupDAO.getTalentKnowledgeStatisticByGroupId(groupId);
        return list;
    }

    @Transactional
    public Map<String, Object> getGroupTalentInfo(List<String> groupIds) {
        List<ComTalentGroupDetailDTO> talent = comTalentGroupDetailService.getTalentListByGroupIds(groupIds);
        List<String> expanded = new ArrayList<>();
        List<String> specs = new ArrayList<>();
//        talent.forEach(e -> {
//            if (!expanded.contains(e.getPpkey()))
//                expanded.add(e.getPpkey());
//            if (!expanded.contains(e.getPkey()))
//                expanded.add(e.getPkey());
//            if (!specs.contains(e.getKnowledgeId()))
//                specs.add(e.getKnowledgeId());
//        });
        Map<String, Object> talentInfo = new HashMap<String, Object>(4) {
            {
                put("expanded", expanded);
                put("spec", specs);
            }
        };
        return talentInfo;
    }
}
