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.CommonResult;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.framework.security.core.LoginUser;
import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
import com.zt.plat.module.qms.common.dic.dal.dataobject.DictionaryBusinessDO;
import com.zt.plat.module.qms.common.dic.service.DictionaryBusinessService;
import com.zt.plat.module.qms.resource.record.constant.RecordConstants;
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.mapper.RecordCategoryMapper;
import com.zt.plat.module.qms.resource.record.dal.dataobject.recordcategory.RecordCategoryDO;
import com.zt.plat.module.qms.resource.record.dal.dataobject.recordpermission.RecordPermissionDO;
import com.zt.plat.module.qms.resource.record.service.recordpermission.RecordPermissionService;
import com.zt.plat.module.system.api.dept.DeptApi;
import com.zt.plat.module.system.api.dept.dto.DeptRespDTO;
import com.zt.plat.module.system.api.permission.PermissionApi;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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 java.util.Set;

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

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


    @Resource
    private RecordCategoryMapper recordCategoryMapper;

    @Resource
    private PermissionApi permissionApi;

    @Resource
    private RecordPermissionService recordPermissionService;

    @Resource
    private DeptApi deptApi;

    @Autowired
    private DictionaryBusinessService dictionaryBusinessService; // 字典服务

    private List<DictionaryBusinessDO> dictionaryBusinessDOS = new ArrayList<>();
    private List<DictionaryBusinessDO> businessDOList = new ArrayList<>();

    @Transactional(rollbackFor = Exception.class)
    @Override
    public RecordCategoryRespVO createRecordCategory(RecordCategorySaveReqVO createReqVO) {
        // 目录名称不能重复
//        LambdaQueryWrapper<RecordCategoryDO> queryWrapper = Wrappers.lambdaQuery();
//        queryWrapper.eq(RecordCategoryDO::getName, createReqVO.getName());
//        List<RecordCategoryDO> list = recordCategoryMapper.selectList(queryWrapper);
//        if (CollUtil.isNotEmpty(list)) {
//            throw exception(RECORD_CATEGORY_NAME_EXISTS);
//        }
        // 插入
        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.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 + "/");
            }
        }
        int i = recordCategoryMapper.updateById(recordCategory);
        if (i <= 0) throw exception(RECORD_CATEGORY_NOT_EXISTS);
        return BeanUtils.toBean(recordCategory, RecordCategoryRespVO.class);
    }

    //判断当前用户是否有编辑权限
//    public boolean judgeIsEdit(RecordCategoryDO recordCategoryDO){
//        // 判断当前当户是否可编辑
//        //当前登录用户
//        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
//        Long userId = loginUser.getId();
//
//        AtomicBoolean pass = new AtomicBoolean(false);
//
//        // 通过分类ID 查询 关联权限
//        RecordPermissionDO recordPermissionDO = new RecordPermissionDO();
//        recordPermissionDO.setSourceId(recordCategoryDO.getId());
//        List<RecordPermissionDO> recordPermissionDOS = recordPermissionService.selectAllList(recordPermissionDO);
//        log.info("分类ID: {}, 关联权限列表数据：{}", recordCategoryDO.getId(), recordPermissionDOS);
//        if (ObjectUtils.isEmpty(recordPermissionDOS)) {
//            return pass.get();
//        }
//
//        // 存在，先判断是否是管理员
//        businessDOList=selectDictPermissionByKey(RecordConstants.PermissionType.PERMISSION_KEY);
//        String permissionAdmin = getDictValueByKey(businessDOList, RecordConstants.PermissionType.ADMIN);// 管理员权限
//
//        dictionaryBusinessDOS = selectDictTargetTypeByKey(RecordConstants.TargetType.TARGET_KEY);
//        // 首先判断当前账户是不是管理员，如果是管理员，则直接查询所有数据返回
//        String targetUser = getDictValueByKey(dictionaryBusinessDOS, RecordConstants.TargetType.USER);// 用户权限
//        RecordPermissionDO permission = judgeIsAdmin(targetUser, userId, permissionAdmin);
//        if (!ObjectUtils.isEmpty(permission)) {
//            pass.set(true);
//            return pass.get();
//        }
//
//
//        Long currentDeptId = loginUser.getVisitDeptId();
//
//        //通过DeptApi获取完整部门信息（包括父部门）
//        CommonResult<DeptRespDTO> deptResult = deptApi.getDept(currentDeptId);
//        DeptRespDTO currentDept = deptResult.getData();
//        Long parentDeptId = currentDept.getParentId();  // 获取父部门ID
//        List<DeptRespDTO> parentDepts = getParentDepts(parentDeptId);
//        parentDepts.add(currentDept);
//
//        // 可操作的所以权限数据列表
//        List<RecordPermissionDO> allPermissionList = getAllPermissionList(recordPermissionDOS, userId, parentDepts);
//        if (ObjectUtils.isEmpty(allPermissionList)) return pass.get();
//
//        // 判断可操作的数据权限类型
//        allPermissionList.forEach(item->{
//            if (item.getPermission().equals(RecordConstants.PermissionType.ADMIN)
//                    || item.getPermission().equals(RecordConstants.PermissionType.EDIT)) {
//                pass.set(true);
//            }
//        });
//        return pass.get();
//    }


    // 文件评审，获取满足当前账户权限的记录列表
    @Override
    public List<RecordCategoryRespVO> getReviewRecordList() {
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        if (ObjectUtils.isEmpty(loginUser)) throw exception0(1, "用户未登录");
        
        Long userId = loginUser.getId();
        Long visitDeptId = loginUser.getVisitDeptId();
        
        // 获取当前用户的所有角色
        CommonResult<Set<Long>> userRoleIdListResult = permissionApi.getUserRoleIdListByUserId(userId);
        Set<Long> userRoleIds = userRoleIdListResult.getData();
        if (ObjectUtils.isEmpty(userRoleIds)) {
            userRoleIds = new java.util.HashSet<>();
        }
        
        // 获取权限字典值
        businessDOList = selectDictPermissionByKey(RecordConstants.PermissionType.PERMISSION_KEY);
        String permissionAdmin = getDictValueByKey(businessDOList, RecordConstants.PermissionType.ADMIN);
        
        // 获取目标类型字典值
        dictionaryBusinessDOS = selectDictTargetTypeByKey(RecordConstants.TargetType.TARGET_KEY);
        String targetUser = getDictValueByKey(dictionaryBusinessDOS, RecordConstants.TargetType.USER);
        String targetDept = getDictValueByKey(dictionaryBusinessDOS, RecordConstants.TargetType.DEPT);
        String targetRole = getDictValueByKey(dictionaryBusinessDOS, RecordConstants.TargetType.ROLE);
        
        // 查询所有权限为"管理员"的权限记录
        LambdaQueryWrapper<RecordPermissionDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(RecordPermissionDO::getPermission, permissionAdmin);
        List<RecordPermissionDO> adminPermissions = recordPermissionService.selectList(queryWrapper);
        
        if (CollUtil.isEmpty(adminPermissions)) {
            return new ArrayList<>();
        }
        
        // 收集满足条件的 recordCategory ID
        Set<Long> categoryIds = new java.util.HashSet<>();
        
        for (RecordPermissionDO permission : adminPermissions) {
            // 条件1：权限必须是"管理员"（已在上面的查询中过滤）
            // 条件2、3、4：targetType 和 targetId 需要满足以下任意一个
            boolean isMatched = false;
            
            // 条件2：targetType='用户' 且 targetId=用户id
            if (targetUser.equals(permission.getTargetType()) && 
                userId.toString().equals(permission.getTargetId())) {
                isMatched = true;
            }
            
            // 条件3：targetType='部门' 且 targetId=部门id
            if (!isMatched && targetDept.equals(permission.getTargetType()) && 
                visitDeptId.toString().equals(permission.getTargetId())) {
                isMatched = true;
            }
            
            // 条件4：targetType='角色' 且 targetId 在用户角色列表中
            if (!isMatched && targetRole.equals(permission.getTargetType())) {
                try {
                    Long roleId = Long.parseLong(permission.getTargetId());
                    if (userRoleIds.contains(roleId)) {
                        isMatched = true;
                    }
                } catch (NumberFormatException e) {
                    log.warn("Invalid role ID format: {}", permission.getTargetId());
                }
            }
            
            // 如果满足条件，添加 sourceId（recordCategory ID）
            if (isMatched && permission.getSourceId() != null) {
                categoryIds.add(permission.getSourceId());
            }
        }
        
        // 根据 categoryIds 查询 recordCategory 列表
        if (CollUtil.isEmpty(categoryIds)) {
            return new ArrayList<>();
        }
        
        List<RecordCategoryDO> recordCategories = recordCategoryMapper.selectByIds(new ArrayList<>(categoryIds));
        
        // 转换为 RespVO 返回
        return BeanUtils.toBean(recordCategories, RecordCategoryRespVO.class);
    }

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

//        boolean t = judgeIsEdit(recordCategoryDO);
//        if (!t) throw exception(RECORD_PERMISSION_NOT_ALLOW); // 不允许编辑

        // 子节点不能变成根节点
        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() + "/");
            }
        }

        // 更新当前数据
        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);
        //TODO
//        recordCategoryMapper.updateById(recordCategoryDO);
        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);
    }

    // 通过字典的key 获取对应的value值
    public String getDictValueByKey(List<DictionaryBusinessDO> businessDOList, String targetKey) {
        return businessDOList.stream()
                .filter(item -> item.getKey().equals(targetKey))
                .findFirst()
                .map(DictionaryBusinessDO::getValue)
                .orElse(null);
    }

    // 查询字典列表，通过key
    public List<DictionaryBusinessDO> selectDictTargetTypeByKey(String targetKey) {
        return dictionaryBusinessDOS = dictionaryBusinessService.queryDictItemsByKey(targetKey);
    }

    public List<DictionaryBusinessDO> selectDictPermissionByKey(String targetKey) {
        return businessDOList = dictionaryBusinessService.queryDictItemsByKey(targetKey);
    }

    // 根据当前用户部门获取所有父级部门列表
    public List<DeptRespDTO> getParentDepts() {
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        Long currentDeptId = loginUser.getVisitDeptId();
        //通过DeptApi获取完整部门信息（包括父部门）
        CommonResult<DeptRespDTO> deptResult = deptApi.getDept(currentDeptId);
        DeptRespDTO currentDept = deptResult.getData();
        Long parentDeptId = currentDept.getParentId();  // 获取父部门ID
//
        List<DeptRespDTO> parentDepts = new ArrayList<>();
        // 添加当前部门到父部门列表中
        Long tempParentId = parentDeptId;
        while (tempParentId != null && tempParentId != 0) {
            CommonResult<DeptRespDTO> parentResult = deptApi.getDept(tempParentId);
            DeptRespDTO parentDept = parentResult.getData();
            parentDepts.add(parentDept);
            tempParentId = parentDept.getParentId();
        }
        parentDepts.add(currentDept);
        return parentDepts;
    }

    // 判断当前当前用户是不是第一个管理员
//    public List<RecordPermissionDO> judgeIsAdmin() {
//        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
//        Long userId = loginUser.getId();
//        RecordPermissionDO recordPermissionDO = new RecordPermissionDO();
//
//        businessDOList=selectDictPermissionByKey(RecordConstants.PermissionType.PERMISSION_KEY);
//        String permissionAdmin = getDictValueByKey(businessDOList, RecordConstants.PermissionType.ADMIN);// 管理员权限
//        dictionaryBusinessDOS = selectDictTargetTypeByKey(RecordConstants.TargetType.TARGET_KEY);
//        String targetUser = getDictValueByKey(dictionaryBusinessDOS, RecordConstants.TargetType.USER);// 用户权限
//
//        recordPermissionDO.setTargetType(targetUser);
//        recordPermissionDO.setTargetId(userId.toString());
//        recordPermissionDO.setPermission(permissionAdmin);
//        return recordPermissionService.selectRecordPermission(recordPermissionDO);
//    }

    // 获取所有分类树
    @Override
    public List<RecordCategoryDO> getRecordCategoryTree(RecordCategoryPageReqVO pageReqVO) {
        LambdaQueryWrapper<RecordCategoryDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.orderByAsc(RecordCategoryDO::getSortNo); // 升序
        String name = pageReqVO.getName();
        if (!ObjectUtils.isEmpty(name)) queryWrapper.eq(RecordCategoryDO::getName, name);
        // 需要过滤name=null和""的情况
        queryWrapper.isNotNull(RecordCategoryDO::getName);  // 排除 name 为 NULL 的数据
        queryWrapper.ne(RecordCategoryDO::getName, "");      // 排除 name 为空字符串的数据
        return recordCategoryMapper.selectList(queryWrapper);
    }

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

}