package com.yfd.platform.modules.specialDocument.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.modules.specialDocument.domain.Files;
import com.yfd.platform.modules.specialDocument.domain.Nodes;
import com.yfd.platform.modules.specialDocument.domain.Project;
import com.yfd.platform.modules.specialDocument.mapper.ProjectMapper;
import com.yfd.platform.modules.specialDocument.service.INodesService;
import com.yfd.platform.modules.specialDocument.service.IProjectService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.platform.modules.storage.context.StorageSourceContext;
import com.yfd.platform.modules.storage.model.enums.FileTypeEnum;
import com.yfd.platform.modules.storage.model.request.BatchDeleteRequest;
import com.yfd.platform.modules.storage.model.request.NewFolderRequest;
import com.yfd.platform.modules.storage.service.base.AbstractBaseFileService;
import com.yfd.platform.system.mapper.SysDictionaryItemsMapper;
import com.yfd.platform.utils.StringUtils;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 专项项目表 服务实现类
 * </p>
 *
 * @author LiMengNan
 * @since 2025-01-20
 */
@Service
public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> implements IProjectService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ChannelInboundHandlerAdapter.class);


    private static final String INITIAL_CODE = "00001";
    private static final int MAX_CODE_VALUE = 99999;


    //专项项目表Mapper
    @Resource
    private ProjectMapper projectMapper;


    //专项文档节点服务类
    @Resource
    private INodesService nodesService;

    //字典表Mapper
    @Resource
    private SysDictionaryItemsMapper sysDictionaryItemsMapper;

    @Resource
    private StorageSourceContext storageSourceContext;

    /**********************************
     * 用途说明: 分页查询专项文档管理-项目管理
     * 参数说明
     * description   项目描述
     * projectType   项目类型
     *projectName    项目名称
     * pageNum 当前页
     * 返回值说明: com.yfd.platform.config.ResponseResult 返回分页查询结果
     ***********************************/
    @Override
    public Page<Project> getSdProjectPage(String description, String projectType, String projectName, Page<Project> page) {

        LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>();
        //如果项目描述 description 不为空
        if (StringUtils.isNotEmpty(description)) {
            queryWrapper.like(Project::getDescription, description);
        }
        //如果项目类型 projectType 不为空
        if (StringUtils.isNotEmpty(projectType)) {
            queryWrapper.like(Project::getProjectType, projectType);
//            //查询字典表获取项目类型对应数据字典
//            QueryWrapper<SysDictionaryItems> queryWrapperSysDictionary = new QueryWrapper<>();
//            queryWrapperSysDictionary.eq("parentcode", "zxxmlx");
//            queryWrapperSysDictionary.eq("itemcode", projectType);
//            queryWrapperSysDictionary.orderByAsc("orderno");
//            SysDictionaryItems sysDictionaryItems = sysDictionaryItemsMapper.selectOne(queryWrapperSysDictionary);
//            if(sysDictionaryItems != null){
//                queryWrapper.like(Project::getProjectType, sysDictionaryItems.getDictName());
//            }else {
//              queryWrapper.like(Project::getProjectType, projectType);
//            }
        }
        //如果项目名称 projectName 不为空
        if (StringUtils.isNotEmpty(projectName)) {
            queryWrapper.like(Project::getProjectName, projectName);
        }
        //根据创建时间排序
        queryWrapper.orderByDesc(Project::getProjectTime);
        //分页查询
        Page<Project> sdProjectPage = projectMapper.selectPage(page, queryWrapper);
        return sdProjectPage;
    }

    /***********************************
     * 用途说明：新增专项文档管理-项目管理
     * 参数说明
     * Project     项目管理
     * 返回值说明:  com.yfd.platform.config.ResponseResult 返回新增成功或者失败
     ***********************************/
    @Override
    public Boolean addSdproject(Project project) {
        //创建项目的时候要创建一个本地的文件夹 路径的话去找专项的存储路径
        //生成项目编号
        String projectCode = generateNextProjectCode();
        project.setProjectCode(projectCode);

        // 设置当前时间
        LocalDateTime now = LocalDateTime.now();
        // 转换为 Timestamp
        Timestamp currentTime = Timestamp.valueOf(now);
        project.setCreateTime(currentTime);
        int valueAdded = projectMapper.insert(project);
        if (valueAdded == 1) {

            // 根节点路径
            String path = "/";
            //新增节点的时候 创建文件夹
            NewFolderRequest newFolderRequest = new NewFolderRequest();
            newFolderRequest.setName(project.getProjectName());//新建的文件夹名称,示例值(/a/b/c)
            newFolderRequest.setPassword("");//文件夹密码, 如果文件夹需要密码才能访问，则支持请求密码,示例值(123456)
            newFolderRequest.setPath(path);//请求路径,示例值(/)
            newFolderRequest.setStorageKey("sdlocal");//存储源 key,示例值(local minio)
            AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(newFolderRequest.getStorageKey());
            boolean flag = fileService.newFolder(newFolderRequest.getPath(), newFolderRequest.getName());
            if (flag) {
                return true;
            } else {
                LOGGER.error("节点新增成功，但是本地专项文件夹创建失败");
                return false;
            }

        } else {
            return false;
        }


//        //查询字典表获取项目类型对应数据字典
//        QueryWrapper<SysDictionaryItems> queryWrapperSysDictionary = new QueryWrapper<>();
//        queryWrapperSysDictionary.eq("parentcode", "compressType");
//        queryWrapperSysDictionary.orderByAsc("orderno");
//        SysDictionaryItems sysDictionaryItems = sysDictionaryItemsMapper.selectOne(queryWrapperSysDictionary);
//        if(sysDictionaryItems != null){
//            project.setProjectType(sysDictionaryItems.getDictName());
//        }


        //TODO 01.21沟通以后说是先不用管重复校验问题
//        //通过项目名称 项目编号查询 查看是否存在
//        QueryWrapper<Project> queryWrapper = new QueryWrapper<>();
//        if(project.getProjectCode() != null){
//            queryWrapper.eq("project_code",project.getProjectCode());
//        }
//        if(project.getProjectName() != null){
//            queryWrapper.eq("project_name",project.getProjectName());
//        }
//        List<Project> projects = projectMapper.selectList(queryWrapper);
//        if(){
//
//        }

    }

    // 编号生成工具方法
    @Transactional(rollbackFor = Exception.class)
    public synchronized String generateNextProjectCode() {
        // 1. 使用悲观锁查询最大编号
        Project maxProject = this.getOne(
                new QueryWrapper<Project>()
                        .select("MAX(project_code) AS projectCode")
                        .last("FOR UPDATE")
        );

        // 2. 处理空表情况
        String currentMax = (maxProject != null && maxProject.getProjectCode() != null)
                ? maxProject.getProjectCode()
                : INITIAL_CODE;

        // 3. 验证并生成新编号
        try {
            int numericCode = Integer.parseInt(currentMax);
            if (numericCode < 0 || numericCode > MAX_CODE_VALUE) {
                throw new IllegalStateException("当前项目编号超出有效范围: " + currentMax);
            }
            if (numericCode == MAX_CODE_VALUE) {
                throw new IllegalStateException("项目编号已达最大值" + MAX_CODE_VALUE);
            }
            return String.format("%05d", numericCode + 1);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("无效的项目编号格式: " + currentMax);
        }

    }

    /**********************************
     * 用途说明: 修改专项文档管理-项目管理
     * 参数说明
     * Project     项目管理
     * 返回值说明: com.yfd.platform.config.ResponseResult 返回修改成功或者失败
     ***********************************/
    @Override
    public boolean updateSdproject(Project project) {
        //查询字典表获取项目类型对应数据字典
//        QueryWrapper<SysDictionaryItems> queryWrapperSysDictionary = new QueryWrapper<>();
//        queryWrapperSysDictionary.eq("parentcode", "zxxmlx");
//        queryWrapperSysDictionary.eq("itemcode", project.getProjectType());
//        queryWrapperSysDictionary.orderByAsc("orderno");
//        SysDictionaryItems sysDictionaryItems = sysDictionaryItemsMapper.selectOne(queryWrapperSysDictionary);
//        if(sysDictionaryItems != null){
//            project.setProjectType(sysDictionaryItems.getDictName());
//        }
        if (project.getProjectTime() == null || project.getProjectTime().equals("")) {
            project.setProjectTime(null);
        }

        int valueUpdate = projectMapper.updateById(project);
        if (valueUpdate == 1) {
            return true;
        } else {
            return false;
        }
    }

    /**********************************
     * 用途说明: 批量删除专项文档管理-项目管理
     * 参数说明  ids 项目管理id数组
     * 返回值说明: com.yfd.platform.config.ResponseResult 返回批量删除成功或失败
     ***********************************/
    @Override
    public boolean deleteProjectByIds(List<String> dataset) {
        Boolean value = false;

        //循环所有的ID
        for (String id : dataset) {
            Project project = projectMapper.selectById(id);
            String path = "/" + project.getProjectName() + "/";
            QueryWrapper<Nodes> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("project_id", id);
            queryWrapper.eq("parent_id", "00");
            List<Nodes> nodesList = nodesService.list(queryWrapper);
            //如果为空 跳过当前项目 接着下一个项目
            if (nodesList != null || !nodesList.isEmpty()) {
                for (Nodes nodes : nodesList) {
                    //调用删除节点 根据任务ID
                    Boolean deleteTsnodes = nodesService.deleteNodesById(nodes.getId(), path);
                    //如果删除成功 接着删除节点表数据
                    if (deleteTsnodes) {
                        LOGGER.info("nodes表结删除改成功");
                        value = true;
                    } else {
                        LOGGER.error("nodes表结构删除失败");
                        value = false;
                    }
                }
            }

            // 删除 sdlocal 中的文件夹  项目文件夹
            List<BatchDeleteRequest.DeleteItem> deleteItemList = new ArrayList<>();
            BatchDeleteRequest.DeleteItem deleteItemData = new BatchDeleteRequest.DeleteItem();
            deleteItemData.setName(project.getProjectName());
            deleteItemData.setPassword("");
            deleteItemData.setPath("/");
            deleteItemData.setType(FileTypeEnum.FOLDER);
            deleteItemList.add(deleteItemData);

            BatchDeleteRequest batchDeleteRequest = new BatchDeleteRequest();
            batchDeleteRequest.setDeleteItems(deleteItemList);
            batchDeleteRequest.setStorageKey("sdlocal");
            AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(batchDeleteRequest.getStorageKey());
            int deleteSuccessCount = 0, deleteFailCount = 0, totalCount = CollUtil.size(deleteItemList);

            for (BatchDeleteRequest.DeleteItem deleteItem : deleteItemList) {
                boolean flag = false;
                try {
                    if (deleteItem.getType() == FileTypeEnum.FILE) {
                        flag = fileService.deleteFile(deleteItem.getPath(), deleteItem.getName());
                    } else if (deleteItem.getType() == FileTypeEnum.FOLDER) {
                        flag = fileService.deleteFolder(deleteItem.getPath(), deleteItem.getName());
                    }

                    if (flag) {
                        deleteSuccessCount++;
                    } else {
                        deleteFailCount++;
                    }
                } catch (Exception e) {
                    LOGGER.error("删除文件/文件夹失败, 文件路径: {}, 文件名称: {}", deleteItem.getPath(), deleteItem.getName(), e);
                    deleteFailCount++;
                }
            }

            if (deleteSuccessCount >= 1) {
                // 删除当前项目
                int deleteCount = projectMapper.deleteById(id);
                if (deleteCount == 1) {
                    LOGGER.info("project表结删除改成功，本地文件夹删除成功");
                    value = true;
                } else {
                    LOGGER.error("project表结构删除失败,本地文件夹删除失败");
                    value = false;
                }
            } else {
                value = false;
            }


        }
        return value;
    }
}
