package com.lz.modules.app.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.lz.common.utils.PageUtils;
import com.lz.common.utils.Query;
import com.lz.common.utils.StringUtil;
import com.lz.modules.app.dao.DepartmentsDao;
import com.lz.modules.app.dao.DepartmentsStaffRelateDao;
import com.lz.modules.app.dto.DepartmentInfos;
import com.lz.modules.app.dto.DepartmentsDto;
import com.lz.modules.app.dto.StaffDepartmentDto;
import com.lz.modules.app.dto.StaffDto;
import com.lz.modules.app.entity.DepartmentsEntity;
import com.lz.modules.app.entity.DepartmentsStaffRelateEntity;
import com.lz.modules.app.service.DepartmentsService;
import com.lz.modules.app.service.StaffService;
import com.lz.modules.job.model.responseBo.DepartmentInfosBo;
import com.lz.modules.performance.dto.SimpleDepartmentDto;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;


@Service("departmentsService")
public class DepartmentsServiceImpl extends ServiceImpl<DepartmentsDao, DepartmentsEntity> implements DepartmentsService {

    protected final static org.slf4j.Logger logger = LoggerFactory.getLogger(DepartmentsServiceImpl.class);

    @Resource
    DepartmentsDao departmentsDao;
    @Resource
    DepartmentsStaffRelateDao departmentsStaffRelateDao;

    @Autowired
    StaffService staffService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<DepartmentsEntity> page = this.page(
                new Query<DepartmentsEntity>().getPage(params),
                new QueryWrapper<DepartmentsEntity>()
        );
        return new PageUtils(page);
    }


    @Override
    public void updateDepartmentInfos(List<DepartmentInfosBo> departmentInfosBos) {
        try {
            departmentsDao.updateDepartmentStatus();
            List<DepartmentsEntity> departmentsBos = filterUpdateDepartmentInfos(departmentInfosBos);
            if (departmentsBos.size() > 0) {
                //departmentsDao.addDepartmentBatch(departmentsBos);
                saveBatch(departmentsBos);
            }
        } catch (Exception e) {
            logger.info("updateDepartmentInfos error : " + e);
        }
    }

    @Override
    public List<DepartmentsDto> getDepartmentTree(int type) {
        List<DepartmentsDto> departmentsParentsList = departmentsDao.getDepartmentsByparentId("1");
        if(type == 1){
            for (DepartmentsDto dto: departmentsParentsList
            ) {
                List<StaffDto> staffDtos = staffService.getDepatAllStaffInfos(dto.getDepartmentId());
                dto.setStaffDtos(staffDtos);
            }
        }

        getDepartmentTreeList(departmentsParentsList, type);
        return departmentsParentsList;
    }

    @Override
    public List<DepartmentsDto> selectByParentDepartmentId(String deparentId) {
        return departmentsDao.getDepartmentsByparentId(deparentId+"");
    }

    @Override
    public List<DepartmentsEntity> selectEntityByParentDepartmentId(String parentId) {
        return departmentsDao.selectEntityByParentDepartmentId(parentId);
    }

    @Override
    public DepartmentsEntity selectByDepartmentId(String departmentId) {
        return departmentsDao.selectByDepartmentId(departmentId);
    }

    @Override
    public StaffDepartmentDto selectStaffAllDepartments(String departmentId) {
        StaffDepartmentDto staffDepartmentDto =  departmentsDao.selectStaffAllDepartments(departmentId);
        if (StringUtil.isEmpty(staffDepartmentDto.getDepartment2())){
            staffDepartmentDto.setDepartment1(staffDepartmentDto.getDepartment3());
            staffDepartmentDto.setDepartment2(staffDepartmentDto.getDepartment4());
            staffDepartmentDto.setDepartment3(null);
        }else if(StringUtil.isEmpty(staffDepartmentDto.getDepartment1())){
            staffDepartmentDto.setDepartment1(staffDepartmentDto.getDepartment2());
            staffDepartmentDto.setDepartment2(staffDepartmentDto.getDepartment3());
            staffDepartmentDto.setDepartment3(staffDepartmentDto.getDepartment4());
        }
        return staffDepartmentDto;
    }

    private List<DepartmentsDto> getDepartmentTreeList(List<DepartmentsDto> departmentList, int type) {
        List<DepartmentsDto> DepartmentsList = Lists.newArrayList();
        for (DepartmentsDto departmentsDto : departmentList) {
            List<DepartmentsDto> departmentsChirdList = departmentsDao.getDepartmentsByparentId(departmentsDto.getDepartmentId());
            if (departmentsChirdList.size() > 0) {
                departmentsDto.setList(getDepartmentTreeList(departmentsChirdList, type));
            }
            if(type == 1){
                List<StaffDto> staffDtos = staffService.getDepatAllStaffInfos(departmentsDto.getDepartmentId());
                departmentsDto.setStaffDtos(staffDtos);

            }
            DepartmentsList.add(departmentsDto);
        }
        return DepartmentsList;
    }

    // @Override
    public List<DepartmentsEntity> filterUpdateDepartmentInfos(List<DepartmentInfosBo> departmentInfosBos) {
        List<DepartmentsEntity> departmentsBos = Lists.newArrayList();
        for (DepartmentInfosBo departmentInfosBo : departmentInfosBos) {
            DepartmentsEntity departmentsEntity = convertDepartmentEntity(departmentInfosBo);
            DepartmentsEntity departmentBo = departmentsDao.getDepartmentByDepartmentId(departmentInfosBo.getId());
            if (departmentBo != null) {
                departmentsDao.updateDepartment(departmentsEntity);
            } else {
                departmentsBos.add(departmentsEntity);
            }
        }
        return departmentsBos;
    }

    public DepartmentsEntity convertDepartmentEntity(DepartmentInfosBo departmentInfosBo) {
        DepartmentsEntity departmentsEntity = new DepartmentsEntity();
        departmentsEntity.setDepartmentId(departmentInfosBo.getId());
        departmentsEntity.setDepartmentParentId(departmentInfosBo.getParentId());
        departmentsEntity.setMemberCount(departmentInfosBo.getMemberCount());
        departmentsEntity.setDepartmentName(departmentInfosBo.getName());
        departmentsEntity.setChatId(departmentInfosBo.getChatId());
        departmentsEntity.setLeaderEmployeeId(departmentInfosBo.getLeaderEmployeeId());
        departmentsEntity.setLeaderOpenId(departmentInfosBo.getLeaderOpenId());
        departmentsEntity.setStatus(departmentInfosBo.getStatus()); //部门状态【0 无效，1 有效】
        return departmentsEntity;
    }
    @Override
    public void updateDepartmentInfo(DepartmentInfosBo departmentInfosBo) {
        try {
            departmentsDao.updateDepartmentStatus();
            DepartmentsEntity departmentsEntity = convertDepartmentEntity(departmentInfosBo);
            DepartmentsEntity departmentBo = departmentsDao.getDepartmentByDepartmentId(departmentInfosBo.getId());
            if (departmentBo != null) {
                departmentsEntity.setId(departmentBo.getId());
                departmentsDao.updateDepartment(departmentsEntity);
            }else{
                departmentsDao.addDepartment(departmentsEntity);
            }
        } catch (Exception e) {
            logger.info("updateDepartmentInfos error : " + e);
        }
    }

    @Override
    public Map<String, String> selectUserAllDepartmentIds(String departmentId) {
        DepartmentInfos departmentInfos = departmentsDao.selectUserAllDepartmentIds(departmentId);
        Map<String, String> map = new HashMap<>();
        if (StringUtil.isNotBlank(departmentInfos.getDd1())) {
            map.put(departmentInfos.getDd1(), departmentInfos.getDn1());
        }
        if (StringUtil.isNotBlank(departmentInfos.getDd2())) {
            map.put(departmentInfos.getDd2(), departmentInfos.getDn2());
        }
        if (StringUtil.isNotBlank(departmentInfos.getDd3())) {
            map.put(departmentInfos.getDd3(), departmentInfos.getDn3());
        }
        if (StringUtil.isNotBlank(departmentInfos.getDd4())) {
            map.put(departmentInfos.getDd4(), departmentInfos.getDn4());
        }
        if (StringUtil.isNotBlank(departmentInfos.getDd5())) {
            map.put(departmentInfos.getDd5(), departmentInfos.getDn5());
        }
        return map;
    }



    @Override
    public List<String> selectAllChildDepartmentIds(String depart) {
        Set<String> set  = new LinkedHashSet<>();
        List<DepartmentInfos> departmentInfosList = departmentsDao.selectAllChildDepartmentIds(depart);
        if(CollectionUtils.isNotEmpty(departmentInfosList)){
            for(DepartmentInfos departmentInfos : departmentInfosList){
                addDD(set,departmentInfos.getDd1());
                addDD(set,departmentInfos.getDd2());
                addDD(set,departmentInfos.getDd3());
                addDD(set,departmentInfos.getDd4());
                addDD(set,departmentInfos.getDd5());
            }
        }
        return new ArrayList<>(set);
    }

    public void addDD(Set<String> set , String dd){
        if(StringUtil.isNotBlank(dd)){
            set.add(dd);
        }
    }

    @Override
    public Map<String, String> selectUserAllDepartmentInFo(String departmentId) {
        DepartmentInfos departmentInfos = departmentsDao.selectUserAllDepartmentIds(departmentId);
        Map<String, String> map = new HashMap<>();
        if (StringUtil.isNotBlank(departmentInfos.getDd1())) {
            map.put("dd1", departmentInfos.getDd1());
            map.put("dn1", departmentInfos.getDn1());
        }
        if (StringUtil.isNotBlank(departmentInfos.getDd2())) {
            map.put("dd2", departmentInfos.getDd2());
            map.put("dn2", departmentInfos.getDn2());
        }
        if (StringUtil.isNotBlank(departmentInfos.getDd3())) {
            map.put("dd3", departmentInfos.getDd3());
            map.put("dn3", departmentInfos.getDn3());
        }
        if (StringUtil.isNotBlank(departmentInfos.getDd4())) {
            map.put("dd4", departmentInfos.getDd4());
            map.put("dn4", departmentInfos.getDn4());
        }
        if (StringUtil.isNotBlank(departmentInfos.getDd5())) {
            map.put("dd5", departmentInfos.getDd5());
            map.put("dn5", departmentInfos.getDn5());
        }
        return map;
    }


    @Override
    public List<DepartmentsDto> getDepartmentTreeByStaffId(String staffId,boolean containSelf) {
        DepartmentsStaffRelateEntity departmentsStaffRelateEntity = departmentsStaffRelateDao.selectByStaffId(Long.valueOf(staffId));
        List<DepartmentsDto> departmentsParentsList = departmentsDao.getDepartmentsByparentId(departmentsStaffRelateEntity.getDepartmentId());
        getDepartmentTreeList(departmentsParentsList, 0);
        if(containSelf){
            List<DepartmentsDto> result = new ArrayList<>();
            DepartmentsDto departmentsDto = new DepartmentsDto();
            departmentsDto.setDepartmentId(departmentsStaffRelateEntity.getDepartmentId());
            DepartmentsEntity departmentsEntity = departmentsDao.selectByDepartmentId(departmentsStaffRelateEntity.getDepartmentId());
            departmentsDto.setDepartmentName(departmentsEntity.getDepartmentName());
            departmentsDto.setMemberCount(departmentsEntity.getMemberCount());
            departmentsDto.setList(departmentsParentsList);
            result.add(departmentsDto);
            return result;
        }
        return departmentsParentsList;
    }

    @Override
    public List<DepartmentsEntity> selectAllDepartmentIds(List<String> dIds){
        List<DepartmentsEntity> departmentsEntities = departmentsDao.selectEntityByDepartmentIds(dIds);

        List<DepartmentsEntity> childs = selectAllChildDepartmentIds(departmentsEntities);
        if(childs != null){
            departmentsEntities.addAll(childs);
        }

        return departmentsEntities;
    }

    public List<DepartmentsEntity> selectAllChildDepartmentIds(List<DepartmentsEntity> departmentsEntities){

        List<DepartmentsEntity> departments = departmentsDao.selectEntityByParentDepartmentIds(departmentsEntities);
        if(departments.size() > 0){
            List<DepartmentsEntity> childs = selectAllChildDepartmentIds(departments);
            if(childs != null){
                departments.addAll(childs);
            }
            return departments;
        }
        return null;
    }

    @Override
    public DepartmentsEntity selectParentDepartmentByDepartmentId(String departmentId){
        return departmentsDao.selectParentDepartmentByDepartmentId(departmentId);
    }

    @Override
    public List<DepartmentsEntity> selectAll(){
        return departmentsDao.selectAll();
    }

    @Override
    public int delDepartments(List<DepartmentsEntity> departmentsEntities){
        return departmentsDao.delDepartments(departmentsEntities);
    }

    @Override
    public Map<Long, List<String>> selectDepartmentTreeByDepIds(List<String> depIds) {
        Map<Long, List<String>> data = Maps.newHashMap();
        if(CollectionUtils.isEmpty(depIds)){
            return data;
        }

        List<SimpleDepartmentDto> simpleDepartmentDtos = departmentsDao.selectSimpleDepartmentByDepartmentIds(depIds);
        List<String> depNames = Lists.newArrayList();
        //将数据分类
        Map<Long,SimpleDepartmentDto> dtos  = Maps.newHashMap();
        for (SimpleDepartmentDto simpleDepartmentDto:simpleDepartmentDtos){
            dtos.put(Long.valueOf(simpleDepartmentDto.getDepartmentId()),simpleDepartmentDto);
        }

        for (SimpleDepartmentDto simpleDepartmentDto:simpleDepartmentDtos) {
            List<String> names = recursiveToBuild(depNames, simpleDepartmentDto, dtos,simpleDepartmentDto.getLevel());
            data.put(Long.valueOf(simpleDepartmentDto.getDepartmentId()),names);
        }
        return data;

    }


    /**
     *
     * @param data 响应数据
     * @param departmentDto 当前部门信息
     * @param dtos 缓存，存在就不查数据库
     * @return
     */
    private List<String> recursiveToBuild(List<String> data, SimpleDepartmentDto departmentDto,Map<Long,SimpleDepartmentDto> dtos, int level){
        if(departmentDto == null){
            logger.info("部门信息为空，截至当前数据data: " + JSON.toJSONString(data));
            return data;
        }
        data.add(departmentDto.getDepartmentName());
        if(level == 0){
            logger.info("部门级别为0,departmentId: " + departmentDto.getDepartmentId());
            return data;
        }
        if(level == data.size()){
            logger.info("数据填充结束,departmentId: " + departmentDto.getDepartmentId() + " ,level: " + level);
            return data;
        }
        SimpleDepartmentDto existSimpleDepartment = dtos.get(departmentDto.getDepartmentParentId());

        if(existSimpleDepartment!=null){
            return recursiveToBuild(data,existSimpleDepartment,dtos,level);
        }
        else {
            SimpleDepartmentDto simpleDepartmentDto = departmentsDao.selectSimpleDepartmentByDepartmentId(departmentDto.getDepartmentParentId());
            if(simpleDepartmentDto!=null){
                dtos.put(Long.valueOf(departmentDto.getDepartmentParentId()),simpleDepartmentDto);
            }
            return recursiveToBuild(data,simpleDepartmentDto,dtos,level);
        }


    }
}
