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.pojo.PageParam;
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.QhseInfoPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.qhse.file.vo.QhseInfoRespVO;
import cn.iocoder.yudao.module.pms.controller.admin.qhse.file.vo.QhseInfoSaveReqVO;
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.dataobject.qhse.file.QhseInfoDO;
import cn.iocoder.yudao.module.pms.dal.mysql.qhse.file.QhseFileTreeMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.qhse.file.QhseInfoMapper;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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;

/**
 * QHSE文件资料 Service 实现类
 *
 * @author 超级管理员
 */
@Service
@Slf4j
@Validated
public class QhseInfoServiceImpl implements QhseInfoService {

    @Resource
    private QhseInfoMapper qhseInfoMapper;
    @Autowired
    private QhseFileTreeMapper qhseFileTreeMapper;
    @Autowired
    private QhseFileTreeService qhseFileTreeService;
    @Autowired
    private DeptApi deptApi;

    @Override
    public List<QhseInfoRespVO> getAllChildContentFile(Long classId) {
        List<QhseFileTreeDO> contents = qhseFileTreeService.getChildTreeList(ImmutableList.of(classId));
//        if (CollUtil.isNotEmpty(contents)) {
        List<Long> contentIds = contents.stream().map(QhseFileTreeDO::getId).collect(Collectors.toList());
        QhseInfoPageReqVO infoPageReqVO = new QhseInfoPageReqVO();
        infoPageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<QhseInfoDO> files = qhseInfoMapper.selectPage(infoPageReqVO, contentIds).getList();
//        }
        List<QhseInfoRespVO> infoRespVOS = dealFileVo(contents, files);
        return infoRespVOS;
    }

    @Override
    public List<QhseInfoRespVO> getChildContentFile(Long classId) {
        List<QhseFileTreeDO> contents = qhseFileTreeMapper.selectList("parent_id", classId);
        List<QhseInfoDO> files = qhseInfoMapper.selectList("class_id", classId);
        List<QhseInfoRespVO> contentVos = dealFileVo(contents, files);
        return contentVos;
    }

    @Override
    public void createQhseInfo(QhseInfoSaveReqVO createReqVO) {
        Long deptId;
        Long deviceId;
        Long classId = createReqVO.getClassId();
        String deviceCode = "";
        String deptName = "";

        deptId = createReqVO.getDeptId();
        if (Objects.nonNull(deptId)) {
            DeptRespDTO dept = deptApi.getDept(deptId);
            if (Objects.nonNull(dept)) {
                deptName = dept.getName();
            }
        }
        importFileTree(createReqVO.getFolderJson(), classId, deptId, deptName);
    }


    private final ObjectMapper objectMapper = new ObjectMapper();
    public void importFileTree(String jsonData, Long parentId, Long deptId, String deptName) {
        try {
            // 解析JSON数组
            JsonNode rootNode = objectMapper.readTree(jsonData);

            if (rootNode.isArray()) {
                for (JsonNode itemNode : rootNode) {
                    // 处理文件夹结构
                    JsonNode folderStructureNode = itemNode.get("folderStructure");
                    JsonNode files = itemNode.get("files");
                    List<String> fileNames = new ArrayList<>();
                    files.forEach(file -> {
                        if (Objects.nonNull(file)&&Objects.nonNull(file.get("name"))) {
                            String name = file.get("name").asText();
                            fileNames.add(name);
                        }
                    });
                    Long fileClassId = null;
                    if (folderStructureNode != null) {
                        fileClassId = processFolderStructure(folderStructureNode, parentId, deptId,  deptName, fileNames);
                    }

                    // todo 处理文件
                    JsonNode filesNode = itemNode.get("files");
                    if (filesNode != null && filesNode.isArray()&&Objects.nonNull(fileClassId)) {
                        processFiles(filesNode, parentId, fileClassId, deptId,  deptName);
                    }
                }
            }
        } catch (Exception e) {
            log.error("导入文件树结构失败", e);
            throw new RuntimeException("导入文件树结构失败", e);
        }
    }

    /**
     * 处理文件
     */
    private void processFiles(JsonNode filesNode, Long rootParentId,Long fileClassId, Long deptId, String deptName) {
        for (JsonNode fileNode : filesNode) {
            String path = fileNode.get("path").asText();
            String filePath = fileNode.get("filePath").asText();
            String fileName = fileNode.get("name").asText();
            String size = fileNode.get("size").asText();

            // 根据路径确定父文件夹ID
            String[] pathParts = path.split("/");
            Long parentId = rootParentId;

            // 逐级查找或创建父文件夹
            for (int i = 0; i < pathParts.length - 1; i++) {
                String folderName = pathParts[i];
                parentId = findOrCreateFolder(folderName, parentId);
            }

            // 检查文件是否已存在
            QhseInfoDO iotInfoDO = qhseInfoMapper.selectOne("filename", fileName, "class_id", fileClassId);
            if (iotInfoDO == null) {
                QhseInfoDO info = new QhseInfoDO();
                info.setDeptId(deptId);
                info.setClassId(fileClassId);
                info.setFilename(fileName);
                info.setDeleted(false);
                info.setDeptName(deptName);
                info.setFileType("file");
                if (fileName.contains("jpg")||fileName.contains("jpeg")||fileName.contains("png")||fileName.contains("gif")) {
                    info.setFileType("pic");
                }
                info.setFilePath(filePath);
                if (StringUtils.isNotBlank(size)&&!"null".equals(size)) {
                    long fileSize = Long.parseLong(size);
                    double mb = fileSize / (1024.0 * 1024.0);
                    info.setFileSize(String.format("%.2f MB", mb));
                }
                qhseInfoMapper.insert(info);
            }
        }
    }
    /**
     * 查找或创建文件夹
     */
    private Long findOrCreateFolder(String folderName, Long parentId) {
        QhseFileTreeDO folder = qhseFileTreeMapper.selectOne("name", folderName, "parent_id", parentId);

        if (folder == null) {
            folder.setParentId(parentId);
            folder.setName(folderName);
            folder.setDeleted(false);
            folder.setType("file");
            qhseFileTreeMapper.insert(folder);
        }

        return folder.getId();
    }

    private Long processFolderStructure(JsonNode folderStructureNode, Long parentId, Long deptId,  String deptName, List<String> fileNames) {
        Iterator<String> fieldNames = folderStructureNode.fieldNames();

        while (fieldNames.hasNext()) {
            String folderName = fieldNames.next();
            JsonNode folderNode = folderStructureNode.get(folderName);

            // 检查文件夹名是否包含"."，如果是则返回当前parentId
//            if (folderName.contains(".")) {
//                return parentId; // 返回当前节点的父ID
//            }
            if (fileNames.contains(folderName)) {
                return parentId;
            }
            // 查询是否已存在同名同父节点的记录
            QhseFileTreeDO iotTreeDO = qhseFileTreeMapper.selectOne("name", folderName, "parent_id", parentId);

            Long currentNodeId;
            if (iotTreeDO != null) {
                currentNodeId = iotTreeDO.getId();
            } else {
                // 创建新节点
                QhseFileTreeDO folder = new QhseFileTreeDO();
                folder.setParentId(parentId);
                folder.setName(folderName);
                folder.setDeleted(false);
                folder.setType("file");
                folder.setDeptId(Math.toIntExact(deptId));
                folder.setDeptName(deptName);
                qhseFileTreeMapper.insert(folder);
                currentNodeId = folder.getId();
            }

            // 递归处理子文件夹
            JsonNode childrenNode = folderNode.get("children");
            if (childrenNode != null && !childrenNode.isNull() && !childrenNode.isEmpty()) {
                // 递归调用，如果子节点处理中返回了parentId，则向上传递
                Long result = processFolderStructure(childrenNode, currentNodeId, deptId,  deptName, fileNames);
                if (result != null) {
                    return result; // 子节点处理中遇到了目标，返回结果
                }
            }
        }

        // 正常处理完所有节点，未遇到包含"."的文件夹
        return null;
    }


    @Override
    public void updateQhseInfo(QhseInfoSaveReqVO updateReqVO) {
        // 校验存在
        validateQhseInfoExists(updateReqVO.getId());
        // 更新
        QhseInfoDO updateObj = BeanUtils.toBean(updateReqVO, QhseInfoDO.class);
        qhseInfoMapper.updateById(updateObj);
    }

    @Override
    public void deleteQhseInfo(Long id) {
        // 校验存在
        validateQhseInfoExists(id);
        // 删除
        qhseInfoMapper.deleteById(id);
    }

    private void validateQhseInfoExists(Long id) {
        if (qhseInfoMapper.selectById(id) == null) {
            throw exception(new ErrorCode(2, "不存在"));
        }
    }

    @Override
    public QhseInfoDO getQhseInfo(Long id) {
        return qhseInfoMapper.selectById(id);
    }

    @Override
    public PageResult<QhseInfoDO> getQhseInfoPage(QhseInfoPageReqVO pageReqVO) {
        IotTreeListReqVO reqVO = new IotTreeListReqVO();
        List<QhseFileTreeDO> iotTreeList = qhseFileTreeService.getQhseTreeList(reqVO);
        if (CollUtil.isNotEmpty(iotTreeList)) {
            pageReqVO.setClassId(iotTreeList.get(0).getId());
        }

        Set<Long> sets = new HashSet<>();
        return qhseInfoMapper.selectPage(pageReqVO, sets);
    }

//    private Set<Long> getInfoCondition(Long classId) {
//        if (classId == null) {
//            return Collections.emptySet();
//        }
//        Set<Long> deptIds = convertSet(iotInfoClassifyService.getChildInfoList(classId), IotInfoClassifyDO::getId);
//        deptIds.add(classId); // 包括自身
//        return deptIds;
//    }

    private List<QhseInfoRespVO> dealFileVo(List<QhseFileTreeDO> contents, List<QhseInfoDO> files){
        List<QhseInfoRespVO> contentVos = contents.stream().map(e -> {
            QhseInfoRespVO iotInfoRespVO = new QhseInfoRespVO();
            iotInfoRespVO.setFilename(e.getName());
            iotInfoRespVO.setId(e.getId());
            iotInfoRespVO.setFileType("content");//设置为文件夹
//            if (Objects.nonNull(e.getDeptId())) {
//                DeptRespDTO dept = deptApi.getDept(e.getDeptId());
//                if (Objects.nonNull(dept)) {
//                    iotInfoRespVO.setDeptName(dept.getName());
//                }
//            }
            iotInfoRespVO.setDeptName(e.getDeptName());
            return iotInfoRespVO;
        }).collect(Collectors.toList());
        List<QhseInfoRespVO> fileVos = files.stream().map(e -> {
            QhseInfoRespVO iotInfoRespVO = new QhseInfoRespVO();
            BeanUtils.copyProperties(e, iotInfoRespVO);
//            if (Objects.nonNull(e.getDeviceId())) {
//                IotDeviceDO iotDevice = iotDeviceService.getIotDevice(e.getDeviceId());
//                if (Objects.nonNull(iotDevice)) {
//                    iotInfoRespVO.setDeviceName(iotDevice.getDeviceName());
//                }
//            }
//            if (Objects.nonNull(e.getDeptId())) {
//                DeptRespDTO dept = deptApi.getDept(e.getDeptId());
//                if (Objects.nonNull(dept)) {
//                    iotInfoRespVO.setDeptName(dept.getName());
//                }
//            }
            iotInfoRespVO.setDeviceCode(e.getDeviceCode());
            iotInfoRespVO.setDeptName(e.getDeptName());
            String docOrPdf = StringUtils.substringAfterLast(iotInfoRespVO.getFilename(), ".");
            iotInfoRespVO.setFileClassify(docOrPdf);
            iotInfoRespVO.setFileType("file");
            return iotInfoRespVO;
        }).collect(Collectors.toList());
        contentVos.addAll(fileVos);
        return contentVos;
    }
}