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

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.pms.controller.admin.vo.IotInfoPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.vo.IotInfoRespVO;
import cn.iocoder.yudao.module.pms.controller.admin.vo.IotInfoSaveReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.vo.IotTreeListReqVO;
import cn.iocoder.yudao.module.pms.dal.dataobject.IotDeviceDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.IotInfoClassifyDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.IotInfoDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.IotTreeDO;
import cn.iocoder.yudao.module.pms.dal.mysql.IotDeviceMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.IotInfoMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.IotTreeMapper;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
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.transaction.annotation.Transactional;
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;
import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.IOT_INFO_NOT_EXISTS;

/**
 * 资料 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
@Slf4j
public class IotInfoServiceImpl implements IotInfoService {

    @Resource
    private IotInfoMapper iotInfoMapper;
    @Resource
    private IotInfoClassifyService iotInfoClassifyService;
    @Autowired
    private IotDeviceService iotDeviceService;
    @Autowired
    private IotTreeService iotTreeService;
    @Resource
    private DeptApi deptApi;
    @Autowired
    private IotTreeMapper iotTreeMapper;
    @Autowired
    private IotDeviceMapper iotDeviceMapper;

    @Override
    public List<IotInfoRespVO> getChildContentFile(Long classId) {
        List<IotTreeDO> contents = iotTreeMapper.selectList("parent_id", classId);
        List<IotInfoDO> files = iotInfoMapper.selectList("class_id", classId);
        List<IotInfoRespVO> contentVos = dealFileVo(contents, files);
        return contentVos;
    }

    private List<IotInfoRespVO> dealFileVo(List<IotTreeDO> contents, List<IotInfoDO> files){
        List<IotInfoRespVO> contentVos = contents.stream().map(e -> {
            IotInfoRespVO iotInfoRespVO = new IotInfoRespVO();
            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<IotInfoRespVO> fileVos = files.stream().map(e -> {
            IotInfoRespVO iotInfoRespVO = new IotInfoRespVO();
            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;
    }


    @Override
    public List<IotInfoRespVO> getAllChildContentFile(Long classId) {
        List<IotTreeDO> contents = iotTreeService.getChildTreeList(ImmutableList.of(classId));
//        if (CollUtil.isNotEmpty(contents)) {
            List<Long> contentIds = contents.stream().map(IotTreeDO::getId).collect(Collectors.toList());
            IotInfoPageReqVO infoPageReqVO = new IotInfoPageReqVO();
            infoPageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
            List<IotInfoDO> files = iotInfoMapper.selectPage(infoPageReqVO, contentIds).getList();
//        }
        List<IotInfoRespVO> infoRespVOS = dealFileVo(contents, files);
        return infoRespVOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createIotInfo(IotInfoSaveReqVO createReqVO) {
        // 插入
//        if (CollUtil.isEmpty(createReqVO.getFileList())) {
//            throw exception(IOT_INFO_NOT_EXISTS);
//        }
        Long deptId;
        Long deviceId;
        Long classId = createReqVO.getClassId();
        String deviceCode = "";
        String deptName = "";
        if (Objects.nonNull(createReqVO.getDeviceId())) {
            IotDeviceDO iotDevice = iotDeviceService.getIotDevice(createReqVO.getDeviceId());
            deptId = iotDevice.getDeptId();
            deviceCode = iotDevice.getDeviceCode();
        } else {
            IotTreeDO iotTreeDO = iotTreeMapper.selectById(createReqVO.getClassId());
            deptId = iotTreeDO.getDeptId();
        }
        if (Objects.nonNull(deptId)) {
            DeptRespDTO dept = deptApi.getDept(deptId);
            if (Objects.nonNull(dept)) {
                deptName = dept.getName();
            }
        }
        importFileTree(createReqVO.getFolderJson(), classId, deptId, createReqVO.getDeviceId(), deviceCode, deptName);

//        List<IotInfoDO> collect = createReqVO.getFileList().stream().map(e -> {
//            IotInfoDO iotInfo = BeanUtils.toBean(createReqVO, IotInfoDO.class);
//            iotInfo.setFilename(StringUtils.substringAfterLast(e.get("url"), "/"));
//            iotInfo.setFilePath(e.get("url"));
//            iotInfo.setDeptId(iotDevice.getDeptId());
//            long size = Long.parseLong(e.get("size"));
//            double mb = size / (1024.0 * 1024.0);
//            iotInfo.setFileSize(String.format("%.2f MB", mb));
//            iotInfo.setDeleted(false);
//            if ("book".equals(createReqVO.getType())) {
//                IotInfoClassifyDO classify = iotInfoClassifyService.getIotInfoClassify(classId);
//                //如果是设备的话
//                IotTreeListReqVO reqVO = new IotTreeListReqVO();
//                if (classify.getParentId()==0) {
//                    reqVO.setType("device").setOriginId(classify.getDeviceId());
//                } else {
//                    reqVO.setType("file").setOriginId(classId);
//                }
//                List<IotTreeDO> iotTreeList = iotTreeService.getIotTreeList(reqVO);
//                if (CollUtil.isNotEmpty(iotTreeList)) {
//                    iotInfo.setClassId(iotTreeList.get(0).getId());
//                }
//            }
//            return iotInfo;
//        }).collect(Collectors.toList());

//        iotInfoMapper.insert(collect);
    }
    @Override
    public void updateIotInfo(IotInfoSaveReqVO updateReqVO) {
        // 校验存在
        validateIotInfoExists(updateReqVO.getId());
        // 更新
        IotInfoDO updateObj = BeanUtils.toBean(updateReqVO, IotInfoDO.class);
        updateObj.setFilename(StringUtils.substringAfterLast(updateObj.getFilePath(), "/"));
        updateObj.setFilePath(updateReqVO.getFilePath());
        updateObj.setFileSize(String.valueOf(FileUtils.getFileSizeMB(updateReqVO.getFilePath())));
        iotInfoMapper.updateById(updateObj);
    }

    @Override
    public void removeIotInfo(IotInfoSaveReqVO updateReqVO) {

    }

    @Override
    public void deleteIotInfo(Long id) {
        // 校验存在
        validateIotInfoExists(id);
        // 删除
        iotInfoMapper.deleteById(id);
    }

    private void validateIotInfoExists(Long id) {
        if (iotInfoMapper.selectById(id) == null) {
            throw exception(IOT_INFO_NOT_EXISTS);
        }
    }

    @Override
    public IotInfoDO getIotInfo(Long id) {
        return iotInfoMapper.selectById(id);
    }

    @Override
    public PageResult<IotInfoDO> getIotInfoPage(IotInfoPageReqVO pageReqVO) {
        IotInfoClassifyDO classify = iotInfoClassifyService.getIotInfoClassify(pageReqVO.getClassId());
        //如果是设备的话
        IotTreeListReqVO reqVO = new IotTreeListReqVO();
        if (classify.getParentId()==0) {
            reqVO.setType("device").setOriginId(classify.getDeviceId());
        } else {
            reqVO.setType("file").setOriginId(pageReqVO.getClassId());
        }
        List<IotTreeDO> iotTreeList = iotTreeService.getIotTreeList(reqVO);
        if (CollUtil.isNotEmpty(iotTreeList)) {
            pageReqVO.setClassId(iotTreeList.get(0).getId());
        }
        return iotInfoMapper.selectPage(pageReqVO, getInfoCondition(pageReqVO.getClassId()));
    }

    @Override
    public PageResult<IotInfoDO> getIotInfoFilePage(IotInfoPageReqVO pageReqVO) {
        return iotInfoMapper.selectPage(pageReqVO, getInfoFileCondition(pageReqVO.getClassId()));
    }

    private Set<Long> getInfoFileCondition(Long classId) {
        if (Objects.isNull(classId)) {
            return Collections.emptySet();
        }
        IotTreeDO iotTree = iotTreeService.getIotTree(classId);
        if (Objects.isNull(iotTree)) {
            throw exception(IOT_INFO_NOT_EXISTS);
        }
        Set<Long> fileIds = convertSet(iotTreeService.getChildTreeList(classId), IotTreeDO::getId);
        //如果是设备的话
        if ("device".equals(iotTree.getType())) {
//            IotInfoClassifyListReqVO iotInfoClassifyListReqVO = new IotInfoClassifyListReqVO();
//            IotInfoClassifyListReqVO classifyListReqVO = iotInfoClassifyListReqVO.setDeviceId(iotTree.getOriginId());
//            List<IotInfoClassifyDO> iotInfoClassifyList = iotInfoClassifyService.getIotInfoClassifyList(classifyListReqVO);
//            if (CollUtil.isNotEmpty(iotInfoClassifyList)) {
//                fileIds.add(iotInfoClassifyList.get(0).getId());
//            }
            fileIds.add(iotTree.getId());
        } else {
            fileIds.add(iotTree.getId()); // 包括自身
        }

        return fileIds;
    }

    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 final ObjectMapper objectMapper = new ObjectMapper();



    public void importFileTree(String jsonData, Long parentId, Long deptId, Long deviceId, String deviceCode, 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, deviceCode, deptName, fileNames);
                    }

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

    /**
     * 处理文件夹结构
     */
//    private void processFolderStructure(JsonNode folderStructureNode, Long parentId, Long deptId) {
//        Iterator<String> fieldNames = folderStructureNode.fieldNames();
//
//        while (fieldNames.hasNext()) {
//            String folderName = fieldNames.next();
//            JsonNode folderNode = folderStructureNode.get(folderName);
//
//            if (folderName.contains(".")) {
//                break;
//            }
//            IotTreeDO iotTreeDO = iotTreeMapper.selectOne("name", folderName, "parent_id", parentId);
//
//
//            Long currentNodeId;
//            if (iotTreeDO != null) {
//                currentNodeId = iotTreeDO.getId();
//            } else {
//                // 插入当前文件夹节点
////                IotTreeDO folder = new IotTreeDO(folderName, parentId);
////                save(folder);
//                IotTreeDO folder = new IotTreeDO();
//                folder.setParentId(parentId);
//                folder.setName(folderName);
//                folder.setDeleted(false);
//                folder.setType("file");
//                folder.setDeptId(deptId);
//                iotTreeMapper.insert(folder);
//                currentNodeId = folder.getId();
//            }
//
//            // 递归处理子文件夹
//            JsonNode childrenNode = folderNode.get("children");
//            if (childrenNode != null && !childrenNode.isNull() && !childrenNode.isEmpty()) {
//                processFolderStructure(childrenNode, currentNodeId, deptId);
//            }
//        }
//    }

    /**
     * 处理文件夹结构并递归创建节点，当遇到包含"."的文件夹名时返回其parentId
     * @param folderStructureNode 文件夹结构的JSON节点
     * @param parentId 父节点ID
     * @param deptId 部门ID
     * @return 遇到包含"."的文件夹时返回其parentId，否则返回null
     */
    private Long processFolderStructure(JsonNode folderStructureNode, Long parentId, Long deptId, String deviceCode, 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;
            }
            // 查询是否已存在同名同父节点的记录
            IotTreeDO iotTreeDO = iotTreeMapper.selectOne("name", folderName, "parent_id", parentId);

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

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

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

    /**
     * 处理文件
     */
    private void processFiles(JsonNode filesNode, Long rootParentId,Long fileClassId, Long deviceId, Long deptId, String deviceCode, 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);
            }

            // 检查文件是否已存在
            IotInfoDO iotInfoDO = iotInfoMapper.selectOne("filename", fileName, "class_id", fileClassId);
            if (iotInfoDO == null) {
                IotInfoDO info = new IotInfoDO();
                info.setDeviceId(deviceId);
                info.setDeptId(deptId);
                info.setClassId(fileClassId);
                info.setFilename(fileName);
                info.setDeleted(false);
                info.setDeviceCode(deviceCode);
                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));
                }
                iotInfoMapper.insert(info);
            }
        }
    }

    /**
     * 查找或创建文件夹
     */
    private Long findOrCreateFolder(String folderName, Long parentId) {
        IotTreeDO folder = iotTreeMapper.selectOne("name", folderName, "parent_id", parentId);

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

        return folder.getId();
    }
}
