package com.app.service.platform;

import com.app.dto.PageResult;
import com.app.dto.platform.ResponseDeptDto;
import com.app.dto.platform.ResponseNodeDto;
import com.app.dto.platform.SearchDeptDto;
import com.app.entity.BaseEntity;
import com.app.entity.platform.system.Dept;
import com.app.mapper.platform.DeptMapper;
import com.app.util.NodeUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * 部门管理
 */
@Slf4j
@Service
public class DeptService {

    @Resource
    private DeptMapper deptMapper;

    /**
     * 查询【部门】分页
     * 未传部门名称搜索时，只查询出顶级部门
     */
    public PageResult<ResponseDeptDto> page(SearchDeptDto dto) {
        LambdaQueryWrapper<Dept> wrapper = new QueryWrapper<Dept>().lambda();
        if (!StringUtils.isEmpty(dto.getName())) { // 有传入部门名称时，按部门名称查询
            wrapper.like(Dept::getName, dto.getName());
        } else { // 默认查询顶级部门
            wrapper.isNull(Dept::getParentId);
        }
        wrapper.eq(Dept::getIsDel, dto.getIsDel());
        wrapper.orderByDesc(Dept::getSort);
        Page<Dept> p = deptMapper.selectPage(new Page<>(dto.getPage(), dto.getSize()), wrapper);
        Page<ResponseDeptDto> page = new Page<>(dto.getPage(), dto.getSize());
        page.setTotal(p.getTotal());
        List<ResponseDeptDto> list = new ArrayList<>();
        for (Dept d : p.getRecords()) { // 判断节点是否有子节点
            ResponseDeptDto respDto = new ResponseDeptDto();
            BeanUtils.copyProperties(d, respDto);
            wrapper = new QueryWrapper<Dept>().lambda();
            wrapper.eq(Dept::getParentId, d.getId()).eq(BaseEntity::getIsDel, Boolean.FALSE);
            Integer count = deptMapper.selectCount(wrapper);
            if (count > 0) {
                respDto.setHasChildren(true);
            } else {
                respDto.setHasChildren(false);
            }
            list.add(respDto);
        }
        page.setRecords(list);
        return new PageResult<>(dto.getPage(), dto.getSize(), page.getTotal(), page.getRecords());
    }


    /**
     * 获取节点树（用于前端选择上级部门）
     * @return 节点树
     */
    public List<ResponseNodeDto> getAllNodes() {
        LambdaQueryWrapper<Dept> wrapper = new QueryWrapper<Dept>().lambda().eq(BaseEntity::getIsDel, Boolean.FALSE);
        List<Dept> deptList = deptMapper.selectList(wrapper);
        List<ResponseNodeDto> list=new ArrayList<>();
        for (Dept dept : deptList) {
            ResponseNodeDto nodeDto = new ResponseNodeDto();
            BeanUtils.copyProperties(dept,nodeDto);
            nodeDto.setLabel(dept.getName());
            nodeDto.setValue(dept.getId());
            list.add(nodeDto);
        }
        return NodeUtils.buildTree(list);
    }


    /**
     * 查询【部门】
     */
    public List<ResponseDeptDto> list(SearchDeptDto dto) {
        LambdaQueryWrapper<Dept> wrapper = new QueryWrapper<Dept>().lambda();
        if (!StringUtils.isEmpty(dto.getParentId())) {
            wrapper.eq(Dept::getParentId, dto.getParentId());
        }
        wrapper.eq(Dept::getIsDel, Boolean.FALSE);
        wrapper.orderByDesc(Dept::getSort);
        List<Dept> deptList = deptMapper.selectList(wrapper);
        if (deptList.isEmpty()) {
            return null;
        }
        List<ResponseDeptDto> list = new ArrayList<>();
        for (Dept dept : deptList) {
            ResponseDeptDto respDto = new ResponseDeptDto();
            BeanUtils.copyProperties(dept, respDto);
            wrapper = new QueryWrapper<Dept>().lambda();
            wrapper.eq(Dept::getParentId, dept.getId()).eq(BaseEntity::getIsDel, Boolean.FALSE);
            Integer count = deptMapper.selectCount(wrapper);
            if (count > 0) {
                respDto.setHasChildren(true);
            } else {
                respDto.setHasChildren(false);
            }
            list.add(respDto);
        }
        return list;
    }

    /**
     * 保存或更新【部门】
     */
    public Dept saveOrUpdate(Dept dto) {
        Dept _dept = null;
        if (StringUtils.isEmpty(dto.getId())) {
            _dept = new Dept();
            if(StringUtils.isEmpty(dto.getParentId())){
                _dept.setParentId(null);
            }else {
                _dept.setParentId(dto.getParentId());
            }
            _dept.setEmail(dto.getEmail());
            _dept.setLeader(dto.getLeader());
            _dept.setName(dto.getName());
            _dept.setPhone(dto.getPhone());
            _dept.setSort(dto.getSort());
            deptMapper.insert(_dept);
        } else {
            Optional<Dept> newsOptional = Optional.ofNullable(deptMapper.selectById(dto.getId()));
            if (newsOptional.isPresent()) {
                _dept = newsOptional.get();
                LambdaUpdateWrapper<Dept> wrapper = new UpdateWrapper<Dept>().lambda();
                wrapper.eq(BaseEntity::getId,_dept.getId());
                // 当parentId为空时，把该字段置为null，即节点修改为顶级节点
                if(StringUtils.isEmpty(dto.getParentId())){
                    wrapper.set(Dept::getParentId,null);
                }else {
                    wrapper.set(Dept::getParentId,dto.getParentId());
                }
                wrapper.set(Dept::getEmail,dto.getEmail());
                wrapper.set(Dept::getLeader,dto.getLeader());
                wrapper.set(Dept::getName,dto.getName());
                wrapper.set(Dept::getPhone,dto.getPhone());
                wrapper.set(Dept::getSort,dto.getSort());
                deptMapper.update(null,wrapper);
            }
        }
        return _dept;
    }

    /**
     * 替换[部门]删除状态
     */
    public void handleIsDel(String id) {
        LambdaQueryWrapper<Dept> wrapper = new QueryWrapper<Dept>().lambda();
        wrapper.eq(BaseEntity::getIsDel,Boolean.FALSE).eq(Dept::getParentId,id);
        List<Dept> list = deptMapper.selectList(wrapper);
        Optional<Dept> optional = Optional.ofNullable(deptMapper.selectById(id));
        if (optional.isPresent()) {
            Dept dept = optional.get();
            dept.setIsDel(!dept.getIsDel());
            deptMapper.updateById(dept);
        }
        // 如果该节点有子节点，继续遍历删除其子节点
        if(!list.isEmpty()){
            for (Dept dept : list) {
                handleIsDel(dept.getId());
            }
        }


    }
}
