package cn.iocoder.yudao.module.pms.service.qhse.file;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.pms.controller.admin.qhse.file.vo.QhseFileTreePageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.qhse.file.vo.QhseFileTreeSaveReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.vo.IotTreeListReqVO;
import cn.iocoder.yudao.module.pms.dal.dataobject.qhse.file.QhseFileTreeDO;
import cn.iocoder.yudao.module.pms.dal.mysql.qhse.file.QhseFileTreeMapper;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.enums.ErrorCodeConstants;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

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

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;

/**
 * QHSE文件树 Service 实现类
 *
 * @author 超级管理员
 */
@Service
@Validated
public class QhseFileTreeServiceImpl implements QhseFileTreeService {

    @Resource
    private QhseFileTreeMapper qhseFileTreeMapper;
    @Autowired
    private DeptApi deptApi;

    @Override
    public Long createQhseFileTree(QhseFileTreeSaveReqVO createReqVO) {
        // 插入
        QhseFileTreeDO qhseFileTree = BeanUtils.toBean(createReqVO, QhseFileTreeDO.class);
        qhseFileTree.setDeleted(false);
        qhseFileTreeMapper.insert(qhseFileTree);
        // 返回
        return qhseFileTree.getId();
    }

    @Override
    public List<QhseFileTreeDO> getQhseTreeList(IotTreeListReqVO reqVO) {
        List<QhseFileTreeDO> list = qhseFileTreeMapper.selectList(reqVO);
        list.sort(Comparator.comparing(QhseFileTreeDO::getSort));
        return list;
    }

    @Override
    public void updateQhseFileTree(QhseFileTreeSaveReqVO updateReqVO) {
        // 校验存在
        validateQhseFileTreeExists(updateReqVO.getId());
        // 更新
        QhseFileTreeDO updateObj = BeanUtils.toBean(updateReqVO, QhseFileTreeDO.class);
        qhseFileTreeMapper.updateById(updateObj);
    }

    @Override
    public void addDeptDeal(DeptDO dept) {
        //插入pms树
        QhseFileTreeDO iotTreeDO = new QhseFileTreeDO();
        iotTreeDO.setType("dept");
        iotTreeDO.setOriginId(dept.getId());
        iotTreeDO.setName(dept.getName());
        iotTreeDO.setDeptId(Math.toIntExact(dept.getId()));
        List<QhseFileTreeDO> iotTreeDOS = qhseFileTreeMapper.selectListByOriginId(dept.getParentId(),"dept");
//        if (CollUtil.isNotEmpty(iotTreeDOS)) {
        iotTreeDO.setParentId(CollUtil.isNotEmpty(iotTreeDOS) ? iotTreeDOS.get(0).getId() : 0);
        qhseFileTreeMapper.insert(iotTreeDO);
    }

    @Override
    public void updateDeptDeal(DeptDO updateObj) {
        //更新pms树
        List<QhseFileTreeDO> iotTreeDOS = qhseFileTreeMapper.selectListByOriginId(updateObj.getId(),"dept");
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(iotTreeDOS)) {
            throw new ServiceException(ErrorCodeConstants.DEPT_NOT_FOUND.getCode(),"无该部门");
        }
        QhseFileTreeDO iotTreeDO = iotTreeDOS.get(0);
        iotTreeDO.setName(updateObj.getName());
        iotTreeDO.setDeptId(Math.toIntExact(updateObj.getId()));
        qhseFileTreeMapper.updateById(iotTreeDO);
    }

    @Override
    public void deleteDeptDeal(String id) {
        //删除pms树
        qhseFileTreeMapper.deleteByMap(ImmutableMap.of("origin_id", id));
    }

    @Override
    public void deleteQhseFileTree(Long id) {
        // 校验存在
        validateQhseFileTreeExists(id);
        List<Long> childIds = getChildTreeList(ImmutableList.of(id)).stream().map(QhseFileTreeDO::getId).collect(Collectors.toList());
        childIds.add(id);
        //删除iot的树形结构
        qhseFileTreeMapper.deleteByIds(childIds);

    }

    @Override
    public List<QhseFileTreeDO> getChildTreeList(Collection<Long> ids) {
        List<QhseFileTreeDO> children = new LinkedList<>();
        // 遍历每一层
        Collection<Long> parentIds = ids;
        for (int i = 0; i < Short.MAX_VALUE; i++) { // 使用 Short.MAX_VALUE 避免 bug 场景下，存在死循环
            // 查询当前层，所有的子产品分类
            List<QhseFileTreeDO> depts = qhseFileTreeMapper.selectListByParentId(parentIds);
            // 1. 如果没有子产品分类，则结束遍历
            if (CollUtil.isEmpty(depts)) {
                break;
            }
            // 2. 如果有子产品分类，继续遍历
            children.addAll(depts);
            parentIds = convertSet(depts, QhseFileTreeDO::getId);
        }
        return children;
    }

    private void validateQhseFileTreeExists(Long id) {
        if (qhseFileTreeMapper.selectById(id) == null) {
            throw exception(new ErrorCode(5, "不存在"));
        }
    }

    @Override
    public QhseFileTreeDO getQhseFileTree(Long id) {
        return qhseFileTreeMapper.selectById(id);
    }

    @Override
    public PageResult<QhseFileTreeDO> getQhseFileTreePage(QhseFileTreePageReqVO pageReqVO) {
        return qhseFileTreeMapper.selectPage(pageReqVO);
    }


    @Override
    public List<QhseFileTreeDO> getAllParentIds(Long nodeId) {
        List<QhseFileTreeDO> parents = new ArrayList<>();

        // 从当前节点开始向上查找所有父节点
        Long currentParentId = getParentId(nodeId);

        while (currentParentId != null) {
            QhseFileTreeDO parentNode = qhseFileTreeMapper.selectById(currentParentId);
            if (Objects.isNull(parentNode)) {
                break; // 父节点不存在时终止查找
            }
            parents.add(parentNode);
            currentParentId = parentNode.getParentId();
        }

        // 反转列表，使顶级父节点排在最前面
        Collections.reverse(parents);
        return parents;
    }

    private Long getParentId(Long nodeId) {
        QhseFileTreeDO nodeOpt = qhseFileTreeMapper.selectById(nodeId);
        return Objects.isNull(nodeOpt) ? null : nodeOpt.getParentId();
    }


    @Override
    public void initTree() {
        List<DeptRespDTO> deptList = deptApi.getDeptList();
        List<QhseFileTreeDO> treeDOS = new ArrayList<>();
        deptList.forEach(dept -> {
            QhseFileTreeDO iotTreeDO = new QhseFileTreeDO();
            iotTreeDO.setOriginId(dept.getId());
            iotTreeDO.setType("dept");
            iotTreeDO.setName(dept.getName());
            iotTreeDO.setDeleted(false);
            iotTreeDO.setDeptId(Math.toIntExact(dept.getId()));
            treeDOS.add(iotTreeDO);
        });
        qhseFileTreeMapper.insertBatch(treeDOS);

//        List<IotTreeDO> iotTreeDOS = iotTreeMapper.selectList();
        treeDOS.forEach(treeDO -> {
            Long parentId = deptList.stream().filter(dept -> treeDO.getOriginId().equals(dept.getId())).findFirst().get().getParentId();
            List<QhseFileTreeDO> iotTreeDOS1 = qhseFileTreeMapper.selectListByOriginId(parentId, "dept");
            if (CollUtil.isNotEmpty(iotTreeDOS1)) {
                treeDO.setParentId(iotTreeDOS1.get(0).getId());
            }
        });
        qhseFileTreeMapper.updateBatch(treeDOS);
    }
}