package com.tofly.base.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tofly.base.config.Constant;
import com.tofly.base.entity.Company;
import com.tofly.base.entity.Department;

import com.tofly.base.exception.BusinessException;
import com.tofly.base.service.CompanyService;
import com.tofly.base.service.DepartmentService;
import com.tofly.base.service.UnitManagementService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service("unitManagementService")
public class UnitManagementServiceImpl implements UnitManagementService {

    @Autowired
    private CompanyService companyService;

    @Autowired
    private DepartmentService departmentService;

    @Override
    public List<Company> getTreeList(String companyName, String deptName) {
        //获取公司
        List<Company> comDeptVosList = companyService.list(new QueryWrapper<Company>().lambda()
                // 排除已删除数据
                .eq(Company::getParentId,0L)
                .eq(Company::getStatusFlag,"1"));
        List<Company> companyDept = findCompanyDept(comDeptVosList, companyName,deptName);
        return companyDept;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveCompanyDept(String type, Company company, Department department) {
        // 判断是新增单位/部门
        if("1".equals(type)){
            if(StringUtils.isNotBlank(company.getCompanyName())){
                List<Company> list = companyService.list(new QueryWrapper<Company>().lambda().eq(Company::getCompanyName, company.getCompanyName())
                        .eq(Company::getParentId, company.getParentId())
                        .eq(Company::getStatusFlag,"1"));
                if(null!=list && list.size()>0){
                    throw new BusinessException(Constant.CURRENT_UNIT_ALREADY_EXISTS_CODE,Constant.CURRENT_UNIT_ALREADY_EXISTS);
                }
                Company a = companyService.getOne(Wrappers.<Company>lambdaQuery()
                        .eq(Company::getCompanyName,company.getCompanyName())
                        .eq(Company::getParentId, company.getParentId())
                        .eq(Company::getStatusFlag,"0"));
                if (null != a){
                    companyService.removeById(a.getId());
                }
                return companyService.save(company);
            }else {
                throw new BusinessException(Constant.COMPANY_NAME_IS_EMPTY_CODE,Constant.COMPANY_NAME_IS_EMPTY);
            }

        }else {
            if(StringUtils.isNotBlank(department.getName())&& null!=department.getCompanyId()){
                List<Department> list = departmentService.list(new QueryWrapper<Department>().lambda().eq(Department::getName, department.getName())
                        .eq(Department::getCompanyId, department.getCompanyId()));
                if(null!=list && list.size()>0){
                    throw new BusinessException(Constant.CURRENT_DEPARTMENT_ALREADY_EXISTS_CODE,Constant.CURRENT_DEPARTMENT_ALREADY_EXISTS);
                }
                Department a = departmentService.getOne(Wrappers.<Department>lambdaQuery()
                        .eq(Department::getName,department.getName())
                        .eq(Department::getParentId, department.getParentId())
                        .eq(Department::getStatusFlag,"0"));
                if (null != a){
                    departmentService.removeById(a.getId());
                }
                return departmentService.save(department);
            }else {
                throw new BusinessException(Constant.DEPARTMENT_NAME_COMPANY_IS_EMPTY_CODE,Constant.DEPARTMENT_NAME_COMPANY_IS_EMPTY);
            }

        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateCompanyDept(String type, Company company, Department department) {
        // 判断是新增单位/部门
        if("1".equals(type)){
            if(StringUtils.isNotBlank(company.getCompanyName())){
//                List<Company> list = companyService.list(new QueryWrapper<Company>().lambda().eq(Company::getCompanyName, company.getCompanyName())
//                        .eq(Company::getParentId, company.getParentId()).eq(Company::getStatusFlag,"1"));
//                if(null!=list && list.size()>0){
//                    throw new BusinessException(Constant.CURRENT_UNIT_ALREADY_EXISTS_CODE,Constant.CURRENT_UNIT_ALREADY_EXISTS);
//                }
                // 判断修改对象是否为总公司,若为总公司,不允许修改上下级关系/不能禁用
                Company byId = companyService.getById(company.getId());
                if(!company.getParentId().equals(byId.getParentId()) ){
                    throw new BusinessException(Constant.PARENT_RELATIONSHIP_CANNOT_MODIFIED_CODE,Constant.PARENT_RELATIONSHIP_CANNOT_MODIFIED);
                }
                if(StringUtils.isNotBlank(company.getStatusFlag())&&!company.getStatusFlag().equals("1")){
                    throw new BusinessException(Constant.PARENT_RELATIONSHIP_CANNOT_DISABLE_CODE,Constant.PARENT_RELATIONSHIP_CANNOT_DISABLE);
                }

                return companyService.updateById(company);
            }else {
                throw new BusinessException(Constant.COMPANY_NAME_IS_EMPTY_CODE,Constant.COMPANY_NAME_IS_EMPTY);
            }

        }else {
            if(StringUtils.isNotBlank(department.getName())&& null!=department.getCompanyId()){
//                List<Department> list = departmentService.list(new QueryWrapper<Department>().lambda().eq(Department::getName, department.getName())
//                        .eq(Department::getCompanyId, department.getCompanyId()).eq(Department::getStatusFlag,"1"));
//                if(null!=list && list.size()>0){
//                    throw new BusinessException(Constant.CURRENT_DEPARTMENT_ALREADY_EXISTS_CODE,Constant.CURRENT_DEPARTMENT_ALREADY_EXISTS);
//                }
                return departmentService.updateById(department);
            }else {
                throw new BusinessException(Constant.DEPARTMENT_NAME_COMPANY_IS_EMPTY_CODE,Constant.DEPARTMENT_NAME_COMPANY_IS_EMPTY);
            }

        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteCompanyDept(String type, String ids) {
        List<Long> deleteIds = Arrays.stream(ids.split(com.tofly.base.em.Constant.CSV)).map(s -> Long.parseLong(s.trim()))
                .collect(Collectors.toList());
        if("1".equals(type)){
            // 判断当前删除列表中是否存在子集
            List<Company> list = companyService.list(new QueryWrapper<Company>().lambda().in(Company::getParentId, deleteIds).eq(Company::getStatusFlag, "1"));
            if(null!=list && list.size()>0){
                Map<String, List<Company>> collect = list.stream().collect(Collectors.groupingBy(Company::getCompanyName));
                throw new BusinessException(Constant.COMPANY_EXISTING_CHILD_CODE,Constant.COMPANY_EXISTING_CHILD+": "+collect.keySet());
            }
            return companyService.update(new UpdateWrapper<Company>().lambda().in(Company::getId,deleteIds).set(Company::getStatusFlag,"0"));
        }else {
            // 判断当前删除列表中是否存在子集
            List<Department> list = departmentService.list(new QueryWrapper<Department>().lambda().in(Department::getParentId, deleteIds).eq(Department::getStatusFlag, "1"));
            if(null!=list && list.size()>0){
                Map<String, List<Department>> collect = list.stream().collect(Collectors.groupingBy(Department::getName));
                throw new BusinessException(Constant.DEPARTMENT_EXISTING_CHILD_CODE,Constant.DEPARTMENT_EXISTING_CHILD+": "+collect.keySet());
            }
            return departmentService.update(new UpdateWrapper<Department>().lambda().in(Department::getId,deleteIds).set(Department::getStatusFlag,"0"));
        }
    }

    /**
     * @param comDeptVosList
     * @return
     * @descript:递归公司，在公司里面递归部门
     */
    public List<Company> findCompanyDept(List<Company> comDeptVosList, String companyName, String deptName) {
        List<Company> list = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(comDeptVosList)) {
            for (Company comDeptVo : comDeptVosList) {
                Long id = comDeptVo.getId();
                List<Company> companies = companyService.list(new QueryWrapper<Company>().lambda()
                        .eq(Company::getParentId,id)
                        .eq(Company::getStatusFlag, "1")
                        .like(StringUtils.isNotBlank(companyName),Company::getCompanyName,companyName));
                List<Department> departments = departmentService.list(new QueryWrapper<Department>().lambda()
                        .eq(Department::getCompanyId,id)
                        .eq(Department::getParentId,"0")
                        .eq(Department::getStatusFlag, "1")
                        .like(StringUtils.isNotBlank(deptName),Department::getName,deptName));
                //通过父级公司递归公司
                comDeptVo.setSubCompany(findCompanyDept(companies,companyName,deptName));

                //通过父级部门递归部门
                comDeptVo.setDeptVos(getDeptList(departments));
                list.add(comDeptVo);
            }
        }
        return list;
    }

    /**
     * @param deptVos
     * @return
     * @descript:递归部门
     */
    public List<Department> getDeptList(List<Department> deptVos) {
        List<Department> deptVosList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(deptVos)) {
            for (Department deptVo : deptVos) {
                Long deptVoId = deptVo.getId();
                List<Department> departments = departmentService.list(new QueryWrapper<Department>().lambda()
                        .eq(Department::getCompanyId,deptVo.getCompanyId())
                        .eq(Department::getStatusFlag, "1")
                        .eq(Department::getParentId,deptVoId));
                deptVo.setDeptVos(getDeptList(departments));
                deptVosList.add(deptVo);
            }
        }
        return deptVosList;
    }


}
