package com.zt.plat.module.qms.resource.record.service.recordcategory;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.module.qms.resource.record.controller.admin.recordcategory.vo.RecordCategoryPageReqVO;
import com.zt.plat.module.qms.resource.record.controller.admin.recordcategory.vo.RecordCategoryRespVO;
import com.zt.plat.module.qms.resource.record.controller.admin.recordcategory.vo.RecordCategorySaveReqVO;
import com.zt.plat.module.qms.resource.record.dal.dataobject.recordcategory.RecordCategoryDO;
import com.zt.plat.module.qms.resource.record.dal.mapper.RecordCategoryMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;

import java.util.ArrayList;
import java.util.List;

import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.zt.plat.module.qms.enums.ErrorCodeConstants.RECORD_CATEGORY_NOT_EXISTS;
import static com.zt.plat.module.qms.enums.ErrorCodeConstants.RECORD_FILE_EXISTS;

/**
 * 文件记录分类 Service 实现类
 *
 * @author 后台管理
 */
@Slf4j
@Service
@Validated
public class RecordCategoryServiceImpl implements RecordCategoryService {


    @Resource
    private RecordCategoryMapper recordCategoryMapper;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public RecordCategoryRespVO createRecordCategory(RecordCategorySaveReqVO createReqVO) {
        // 插入
        RecordCategoryDO recordCategory = BeanUtils.toBean(createReqVO, RecordCategoryDO.class);
        int insert = recordCategoryMapper.insert(recordCategory);
        if (insert <= 0) throw exception(RECORD_CATEGORY_NOT_EXISTS);
        Long id = recordCategory.getId();// 获取插入后的ID
        Long parentId = recordCategory.getParentId();
        // 判断父节点是否为null或者0，如果是，则设置父节点ID为0，否则查询父节点信息并设置ID路径
        if (parentId == null || parentId == 0L) {// 没有父节点
            recordCategory.setCancelFlag("-1"); // 临时数据标识
            recordCategory.setParentId(0L);
            // 更新ID_Path
            recordCategory.setIdPath("/" + recordCategory.getParentId() + "/" + id );
        } else { // 存在父节点的新建
            RecordCategoryDO parent = recordCategoryMapper.selectById(parentId); // 存在父节点，查询父节点信息
            if (ObjectUtils.isEmpty(parent)) throw exception(RECORD_CATEGORY_NOT_EXISTS);
            else {
                String idPath = parent.getIdPath();
                recordCategory.setIdPath(idPath + "/" + id);
            }
            recordCategory.setCancelFlag("1");
        }
        int i = recordCategoryMapper.updateById(recordCategory);
        if (i <= 0) throw exception(RECORD_CATEGORY_NOT_EXISTS);
        return BeanUtils.toBean(recordCategory, RecordCategoryRespVO.class);
    }


    @Override
    public RecordCategoryDO selectCategoryAppraisalDO(Long categoryRootId) {
        return recordCategoryMapper.selectCategoryAppraisalDO(categoryRootId);
    }

    @Override
    public List<RecordCategoryDO> selectListByCategoryIdIdPath(String categoryIdPath) {
        LambdaQueryWrapper<RecordCategoryDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.like(RecordCategoryDO::getIdPath, categoryIdPath);
        return recordCategoryMapper.selectList(queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateRecordCategory(RecordCategorySaveReqVO updateReqVO) {
        // 校验存在
        RecordCategoryDO recordCategoryDO = validateRecordCategoryExists(updateReqVO.getId());

        // 子节点不能变成根节点
        Long parentId1 = recordCategoryDO.getParentId();
        if (parentId1 != null && parentId1 != 0L) {
            if (updateReqVO.getParentId() != null && updateReqVO.getParentId() == 0L)
                throw exception(RECORD_CATEGORY_NOT_EXISTS);
        }

        // 获取更新前的旧数据
        RecordCategoryDO oldObj = recordCategoryMapper.selectById(updateReqVO.getId());
        String oldIdPath = oldObj.getIdPath();

        // 更新
        RecordCategoryDO updateObj = BeanUtils.toBean(updateReqVO, RecordCategoryDO.class);
        Long parentId = updateObj.getParentId();

        // 构建新的idPath
        if (parentId == null || parentId == 0L) {
            // 父节点为null或0，则变成根节点
            updateObj.setParentId(0L);
            updateObj.setIdPath("/0/" + updateObj.getId());
        } else {
            // 查询父节点
            RecordCategoryDO parentCategory = recordCategoryMapper.selectById(parentId);
            if (ObjectUtils.isEmpty(parentCategory)) {
                // 父节点不存在，设置为根节点
                updateObj.setParentId(0L);
                updateObj.setIdPath("/0/" + updateObj.getId());
            } else {
                // 父节点存在，构建新的idPath
                updateObj.setIdPath(parentCategory.getIdPath() + "/" + updateObj.getId());
            }
        }
        updateObj.setCancelFlag("1");
        // 更新当前数据
        recordCategoryMapper.updateById(updateObj);

        // 更新当前数据的子节点
        String currentNodePattern = "/" + updateObj.getId() + "/";
        LambdaQueryWrapper<RecordCategoryDO> query = new LambdaQueryWrapper<>();
        query.like(RecordCategoryDO::getIdPath, "%" + currentNodePattern + "%");
        query.ne(RecordCategoryDO::getId, updateObj.getId()); // 排除当前节点本身
        List<RecordCategoryDO> childList = recordCategoryMapper.selectList(query);

        if (!childList.isEmpty()) {
            List<RecordCategoryDO> recordCategoryList = new ArrayList<>();
            for (RecordCategoryDO childCategory : childList) {
                String childIdPath = childCategory.getIdPath();
                // 替换旧的idPath为新的idPath
                if (childIdPath.contains(oldIdPath)) {
                    String newChildIdPath = childIdPath.replace(oldIdPath, updateObj.getIdPath());
                    childCategory.setIdPath(newChildIdPath);
                    recordCategoryList.add(childCategory);
                }
            }
            if (!recordCategoryList.isEmpty()) {
                // 批量更新所有子节点
                recordCategoryMapper.updateBatch(recordCategoryList);
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteRecordCategory(Long id) {
        // 校验存在
        validateRecordCategoryExists(id);
        // 验证是否存在字节点
        validateRecordCategoryHasChildNode(id);
        // 逻辑删除
        RecordCategoryDO recordCategoryDO = new RecordCategoryDO();
        recordCategoryDO.setId(id);
        recordCategoryDO.setDeleted(true);
        recordCategoryMapper.deleteById(id);
    }

    @Override
    public void deleteRecordCategoryListByIds(List<Long> ids) {
        // 校验存在
        validateRecordCategoryExists(ids);
        // 删除
        recordCategoryMapper.deleteByIds(ids);
    }

    // 验证删除的节点是否存在字节点，如果存在字节点，则不允许删除
    public void validateRecordCategoryHasChildNode(Long id) {
        LambdaQueryWrapper<RecordCategoryDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RecordCategoryDO::getDeleted, 0);// 没有删除的数据
        queryWrapper.like(RecordCategoryDO::getParentId, id);
        List<RecordCategoryDO> list = recordCategoryMapper.selectList(queryWrapper);
        if (CollUtil.isNotEmpty(list)) {
            throw exception(RECORD_FILE_EXISTS);
        }
    }

    private void validateRecordCategoryExists(List<Long> ids) {
        List<RecordCategoryDO> list = recordCategoryMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(RECORD_CATEGORY_NOT_EXISTS);
        }
    }

    private RecordCategoryDO validateRecordCategoryExists(Long id) {
        RecordCategoryDO recordCategoryDO = recordCategoryMapper.selectById(id);
        if (recordCategoryDO == null) {
            throw exception(RECORD_CATEGORY_NOT_EXISTS);
        }
        return recordCategoryDO;
    }

    @Override
    public RecordCategoryDO getRecordCategory(Long id) {
        return recordCategoryMapper.selectById(id);
    }

    @Override
    public PageResult<RecordCategoryDO> getRecordCategoryPage(RecordCategoryPageReqVO pageReqVO) {
        return recordCategoryMapper.selectPage(pageReqVO);
    }

    // 获取所有分类树
    @Override
    public List<RecordCategoryDO> getRecordCategoryTree(RecordCategoryPageReqVO pageReqVO) {
        pageReqVO.setPageSize(999);
        pageReqVO.setPageNo(1);
        pageReqVO.setCancelFlag("1");
        PageResult<RecordCategoryDO> recordCategoryDOPageResult = recordCategoryMapper.selectPage(pageReqVO);
        return recordCategoryDOPageResult.getList();
    }

    @Override
    public RecordCategoryDO selectById(Long categoryId) {
        return recordCategoryMapper.selectById(categoryId);
    }

}