package cn.fateverse.admin.facade;

import cn.fateverse.admin.convert.DeptConvert;
import cn.fateverse.admin.dto.DeptDto;
import cn.fateverse.admin.service.DeptService;
import cn.fateverse.admin.service.UserService;
import cn.fateverse.admin.vo.DeptVo;
import cn.fateverse.common.core.constant.BaseConstant;
import cn.fateverse.common.core.constant.UserConstants;
import cn.fateverse.common.core.entity.Dept;
import cn.fateverse.common.core.entity.OptionTree;
import cn.fateverse.common.core.utils.AssertUtil;
import cn.fateverse.common.core.utils.convert.TreeUtil;
import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class DeptFacade {

    private final DeptService deptService;

    private final UserService userService;

    /**
     * 查询树形结构信息
     *
     * @param deptName 部门名称
     * @param state    状态
     * @return {@link List }<{@link DeptVo }>
     */
    public List<DeptVo> searchTree(String deptName, Integer state) {
        List<Dept> deptList = deptService.list(deptName, state);
        return TreeUtil.build(deptList, DeptVo.class, (config) -> {
            config.setIdField("deptId");
            config.setExclude("phone");
        });
    }

    /**
     * 按id查询
     *
     * @param deptId 部门id
     * @return {@link DeptVo }
     */
    public DeptVo searchById(Long deptId) {
        Dept dept = deptService.getById(deptId);
        return DeptConvert.INSTANCE.entityToVo(dept);
    }

    /**
     * 获取部门选择的树形结构
     *
     * @return {@link List }<{@link OptionTree }> 部门树形选择对象
     */
    public List<OptionTree> searchTreeOption() {
        List<Dept> deptList = deptService.list(null, null);
        return TreeUtil.build(deptList, OptionTree.class, (config) -> {
            config.setIdField("deptId");
            config.setOption("deptId", "deptName");
        });
    }

    /**
     * 搜索排除树
     *
     * @param deptId 部门id
     * @return {@link List }<{@link OptionTree }>
     */
    public List<OptionTree> searchExcludeTree(Long deptId) {
        Dept dept = deptService.getById(deptId);
        if (BaseConstant.ZERO.equals(dept.getParentId())) {
            return List.of();
        }
        List<Dept> deptList = deptService.searchExcludeTree(deptId);
        return TreeUtil.build(deptList, OptionTree.class, (config) -> {
            config.setIdField("deptId");
            config.setOption("deptId", "deptName");
        });
    }

    /**
     * 保存
     *
     * @param deptDto 部门dto
     */
    @Transactional(rollbackFor = Exception.class)
    public void save(DeptDto deptDto) {
        Dept dept = DeptConvert.INSTANCE.dtoToEntity(deptDto);
        deptService.checkNameUnique(dept);
        deptService.save(dept);
    }

    /**
     * 编辑
     *
     * @param deptDto 部门dto
     */
    @Transactional(rollbackFor = Exception.class)
    public void edit(DeptDto deptDto) {
        Dept dept = DeptConvert.INSTANCE.dtoToEntity(deptDto);
        deptService.checkNameUnique(dept);
        AssertUtil.isTrue(!dept.getDeptId().equals(dept.getParentId()), "修改部门: {} '失败,上级部门不能为自己!", dept.getDeptName());

        Dept newParentDept = deptService.getById(dept.getParentId());
        Dept oldDept = deptService.getById(dept.getDeptId());
        if (null != newParentDept && null != oldDept) {
            String newAncestors = newParentDept.getAncestors() + "," + newParentDept.getDeptId();
            String oldAncestors = oldDept.getAncestors();
            dept.setAncestors(newAncestors);
            updateDeptChildren(dept.getDeptId(), newAncestors, oldAncestors);
        }
        if (null != newParentDept && UserConstants.DEPT_DISABLE.equals(newParentDept.getState())) {
            updateParentDept(dept);
        }
        deptService.save(dept);
    }


    /**
     * 更新字元素的ancestors
     *
     * @param deptId
     * @param newAncestors
     * @param odlAncestors
     */
    public void updateDeptChildren(Long deptId, String newAncestors, String odlAncestors) {
        List<Dept> children = deptService.selectChildrenById(deptId);
        List<Dept> newChildren = children.stream().peek(child -> {
            child.setAncestors(child.getAncestors().replace(odlAncestors, newAncestors));
        }).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(newChildren)) {
            deptService.updateBatchById(newChildren);
        }
    }


    /**
     * 更新父级部门的状态
     *
     * @param dept
     */
    public void updateParentDept(Dept dept) {
        Dept parent = deptService.getById(dept.getParentId());
        parent.setState(dept.getState());
        deptService.updateById(parent);
    }

    /**
     * 删除
     *
     * @param deptId 部门id
     */
    @Transactional(rollbackFor = Exception.class)
    public void remove(Long deptId) {
        AssertUtil.isTrue(!deptService.hasChildById(deptId), "存在下级部门,不允许删除");
        AssertUtil.isTrue(!userService.checkExistUser(deptId), "该部门下存在用户,不允许删除");
        deptService.removeById(deptId);
    }

    /**
     * 按id搜索
     *
     * @param deptIds 部门id
     * @return {@link List }<{@link DeptVo }>
     */
    public List<DeptVo> searchByIds(List<Long> deptIds) {
        List<Dept> deptList = deptService.searchByIds(deptIds);
        return DeptConvert.INSTANCE.entityToVOList(deptList);
    }
}
