package com.kiisoo.ic.department.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kiisoo.ic.department.entity.DepartmentDO;
import com.kiisoo.ic.department.mapper.PrivilageDepartmentDOMapper;
import com.kiisoo.ic.employee.entity.PrivilageCpUserDO;
import com.kiisoo.ic.wx.service.QWMailListManageService;
import lombok.Synchronized;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.bean.WxCpDepart;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.kiisoo.ic.department.constant.Constants.*;

/**
 * @Description: 部门管理service
 * @Auther: yechenhao
 * @Date: 2020/4/7 0002 10:06
 * @Version: v1
 */
@Service
public class DepartmentService {

    @Autowired
    private QWMailListManageService qwMailListManageService;

    @Autowired
    private PrivilageDepartmentDOMapper departmentDOMapper;

    /**
     * 查询部门
     * @param departmentDO 部门实体类
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    @Synchronized
    public List<DepartmentDO> listDepartment() throws Exception {
        QueryWrapper<DepartmentDO> params = new QueryWrapper<>();
        List<DepartmentDO> departmentDOS = departmentDOMapper.selectList(params);
        //转换为微信部门以使用递归分组
        List<WxCpDepart> wxCpDeparts = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(departmentDOS)){
            departmentDOS.forEach(department -> {
                WxCpDepart wxCpDepart = new WxCpDepart();
                BeanUtils.copyProperties(department,wxCpDepart);
                wxCpDepart.setOrder(department.getOrderNum());
                wxCpDeparts.add(wxCpDepart);
            });
        }

        List<DepartmentDO> results = new ArrayList<>();
        groupByDepartments(wxCpDeparts,results);

        return results;
    }
    /**
     * 增加部门
     * @param departmentDO 部门实体类
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    @Synchronized
    public Boolean addDepartment(DepartmentDO departmentDO) throws Exception {
        //数据库创建部门（需要返回部门id）
        DepartmentDO parentDep = departmentDOMapper.selectById(departmentDO.getParentId());
        Long maxId = departmentDOMapper.selectMaxDepartmentId();
        departmentDO.setLevel(parentDep.getLevel()+1);
        departmentDO.setId(maxId+1);
        int insert = departmentDOMapper.insert(departmentDO);
        if (insert == 0){
            throw new Exception("创建部门service失败");
        }
        //成功则添加用户到企业微信
        qwMailListManageService.addDepartment(departmentDO);
        return true;
    }

    /**
     * 修改部门
     * @param departmentDO 部门实体类
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateDepartment(DepartmentDO departmentDO) throws Exception {
        //数据库创建部门（需要返回部门id）
        DepartmentDO parentDep = departmentDOMapper.selectById(departmentDO.getParentId());
        departmentDO.setLevel(parentDep.getLevel()+1);
        int update = departmentDOMapper.updateById(departmentDO);
        if (update == 0){
            throw new Exception("修改部门service失败");
        }
        //成功则添加用户到企业微信
        qwMailListManageService.updateDepartment(departmentDO);
        return true;
    }

    /**
     * 删除部门
     * @param departmentId 部门实体id
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteDepartment(Long departmentId) throws Exception {
        //数据库创建部门（需要返回部门id）
        int delete = departmentDOMapper.deleteById(departmentId);
        if (delete == 0){
            throw new Exception("删除部门service失败");
        }
        //todo 删除部门后操作员工
        //成功则添加用户到企业微信
        qwMailListManageService.deleteDepartment(departmentId);
        return true;
    }

    //-----------------------------同步部门------------------------start-----------------------------

    @Transactional(rollbackFor = Exception.class)
    public Boolean syncDepartment() throws WxErrorException {
        //获取企业微信部门架构
        List<WxCpDepart> wxCpDeparts = qwMailListManageService.syncDepartment();
        //分组
        List<DepartmentDO> departmentDOS = new ArrayList<>();
        groupByDepartments(wxCpDeparts,departmentDOS);

        recursionInsertDepartment(departmentDOS);
        return true;
    }

    /**
     * 递归分组
     * @param wxCpDeparts 企业微信部门架构
     * @param departmentDOS 分组部门架构
     * @return
     */
    private void groupByDepartments(List<WxCpDepart> wxCpDeparts,List<DepartmentDO> departmentDOS){
        List<WxCpDepart> recursionList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(wxCpDeparts)){
            wxCpDeparts.forEach(wxDept -> {
                Long departmentId = wxDept.getId();
                Long parentId = wxDept.getParentId();
                //如果部门id为1为首（根）部门直接加入数组
                if (MAIN_DEPARTMENT_ID.equals(departmentId)){
                    DepartmentDO departmentDO = new DepartmentDO();
                    BeanUtils.copyProperties(wxDept,departmentDO);
                    departmentDO.setOrderNum(wxDept.getOrder());
                    departmentDO.setLevel(LEVEL_ONE);
                    departmentDOS.add(departmentDO);
                }else{
                    //部门id不为1，则寻找部门数组中是否有其夫部门
                    Boolean hasParents = false;
                    if (CollectionUtils.isNotEmpty(departmentDOS)){
                        for(DepartmentDO departmentDO:departmentDOS) {
                            Long oneId = departmentDO.getId();
                            //判断该部门是否为夫部门
                            if (parentId.equals(oneId)){
                                List<DepartmentDO> departments = departmentDO.getDepartments();
                                if (CollectionUtils.isEmpty(departments)){
                                    departments = new ArrayList<>();
                                }
                                DepartmentDO de = new DepartmentDO();
                                BeanUtils.copyProperties(wxDept,de);
                                de.setOrderNum(wxDept.getOrder());
                                de.setLevel(LEVEL_TWO);
                                departments.add(de);
                                departmentDO.setDepartments(departments);
                                hasParents = true;
                                break;
                            }else{
                                //不是副部门则递归判断该部门的子部门时候为父部门
                                hasParents = recursionLevel(LEVEL_TWO,hasParents,departmentDO,wxDept);
                            }
                        }
                        if(!hasParents){
                            recursionList.add(wxDept);
                        }
                    }else {
                        recursionList.add(wxDept);
                    }
                }

            });
            groupByDepartments(recursionList,departmentDOS);
        }
    }

    /**
     * 递归寻找父部门
     * @param level 层级
     * @param hasParents 是否找到父部门
     * @param departmentDO 部门分组
     * @param wxDept 需要寻找部门的类
     */
    private Boolean recursionLevel(int level,Boolean hasParents,DepartmentDO departmentDO,WxCpDepart wxDept){
        int nowLevel = ++level;
        Long parentId = wxDept.getParentId();
        List<DepartmentDO> departments = departmentDO.getDepartments();
        //寻找部门数组中是否有其夫部门
        if (CollectionUtils.isNotEmpty(departments)){
            for(DepartmentDO dep:departments) {
                Long oneId = dep.getId();
                //判断该部门是否为夫部门
                if (parentId.equals(oneId)){
                    List<DepartmentDO> deps = dep.getDepartments();
                    if (CollectionUtils.isEmpty(deps)){
                        deps = new ArrayList<>();
                    }
                    DepartmentDO de = new DepartmentDO();
                    BeanUtils.copyProperties(wxDept,de);
                    de.setOrderNum(wxDept.getOrder());
                    de.setLevel(nowLevel);
                    deps.add(de);
                    dep.setDepartments(deps);
                    hasParents = true;
                }else{
                    //不是副部门则递归判断该部门的子部门时候为父部门
                    hasParents =  recursionLevel(nowLevel,hasParents,dep,wxDept);
                }
            }
        }
        return hasParents;
    }

    /**
     * 递归插入
     * @param departmentDO 需要插入的部门
     */
    private void recursionInsertDepartment(List<DepartmentDO> departmentDO){
        if (CollectionUtils.isNotEmpty(departmentDO)){
            departmentDO.forEach(department -> {
                DepartmentDO dep = departmentDOMapper.selectById(department.getId());
                if (dep == null){
                    departmentDOMapper.insert(department);
                }else{
                    departmentDOMapper.updateById(department);
                }
                List<DepartmentDO> departments = department.getDepartments();
                if (CollectionUtils.isNotEmpty(departments)){
                    recursionInsertDepartment(departments);
                }
            });
        }
    }

    //-----------------------------同步部门------------------------end-----------------------------

}
