package com.ruoyi.ems.service.impl;

import com.huashe.common.utils.DateUtils;
import com.ruoyi.ems.domain.EmsObjFlowRel;
import com.ruoyi.ems.mapper.EmsObjFlowRelMapper;
import com.ruoyi.ems.service.IEmsObjFlowRelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 能源设施能流关系Service业务层处理
 *
 * @author ruoyi
 * @date 2024-07-10
 */
@Service
public class EmsObjFlowRelServiceImpl implements IEmsObjFlowRelService {
    @Autowired
    private EmsObjFlowRelMapper flowRelMapper;

    /**
     * 查询能源设施能流关系
     *
     * @param id 能源设施能流关系主键
     * @return 能源设施能流关系
     */
    @Override
    public EmsObjFlowRel selectFlowRelById(Long id) {
        return flowRelMapper.selectFlowRelById(id);
    }

    /**
     * 查询能源设施能流关系列表
     *
     * @param flowRel 能源设施能流关系
     * @return 能源设施能流关系
     */
    @Override
    public List<EmsObjFlowRel> selectFlowRelList(EmsObjFlowRel flowRel) {
        return flowRelMapper.selectFlowRelList(flowRel);
    }

    /**
     * 新增能源设施能流关系
     *
     * @param flowRel 能源设施能流关系
     * @return 结果
     */
    @Override
    public int insertFlowRel(EmsObjFlowRel flowRel) {
        // 检查是否已存在
        if (checkFlowRelExists(flowRel)) {
            throw new RuntimeException("该能流关系已存在");
        }

        flowRel.setCreateTime(DateUtils.getNowDate());
        return flowRelMapper.insertFlowRel(flowRel);
    }

    /**
     * 修改能源设施能流关系
     *
     * @param flowRel 能源设施能流关系
     * @return 结果
     */
    @Override
    public int updateFlowRel(EmsObjFlowRel flowRel) {
        // 检查是否已存在（排除自身）
        if (checkFlowRelExists(flowRel)) {
            throw new RuntimeException("该能流关系已存在");
        }

        flowRel.setUpdateTime(DateUtils.getNowDate());
        return flowRelMapper.updateFlowRel(flowRel);
    }

    /**
     * 批量删除能源设施能流关系
     *
     * @param ids 需要删除的能源设施能流关系主键
     * @return 结果
     */
    @Override
    public int deleteFlowRelByIds(Long[] ids) {
        return flowRelMapper.deleteFlowRelByIds(ids);
    }

    /**
     * 删除能源设施能流关系信息
     *
     * @param id 能源设施能流关系主键
     * @return 结果
     */
    @Override
    public int deleteFlowRelById(Long id) {
        return flowRelMapper.deleteFlowRelById(id);
    }

    /**
     * 获取能流拓扑数据
     *
     * @param areaCode 区域代码
     * @param emsClsCode 能源分类代码
     * @return 拓扑数据（包含nodes和edges）
     */
    @Override
    public Map<String, Object> getFlowTopology(String areaCode, String emsClsCode) {
        Map<String, Object> result = new HashMap<>();

        // 构建查询条件
        EmsObjFlowRel queryParam = new EmsObjFlowRel();
        if (StringUtils.hasText(areaCode)) {
            queryParam.setAreaCode(areaCode);
        }
        if (StringUtils.hasText(emsClsCode)) {
            queryParam.setEmsCls(emsClsCode);
        }
        queryParam.setEnableStatus(1); // 只查询启用的关系

        // 查询能流关系列表
        List<EmsObjFlowRel> flowRelList = flowRelMapper.selectFlowRelList(queryParam);

        // 构建节点集合（使用Set去重，但需要保证equals和hashCode正确实现）
        Map<String, Map<String, Object>> nodeMap = new LinkedHashMap<>();
        List<Map<String, Object>> edges = new ArrayList<>();

        for (EmsObjFlowRel flowRel : flowRelList) {
            // 空值检查
            if (flowRel.getExportObj() == null || flowRel.getInputObj() == null) {
                continue;
            }

            // 添加输出节点
            String exportNodeId = flowRel.getExportObjType() + "_" + flowRel.getExportObj();
            if (!nodeMap.containsKey(exportNodeId)) {
                Map<String, Object> exportNode = new HashMap<>();
                exportNode.put("id", exportNodeId);
                exportNode.put("label", flowRel.getExportObjName() != null ? flowRel.getExportObjName() : flowRel.getExportObj());
                exportNode.put("type", flowRel.getExportObjType());
                exportNode.put("code", flowRel.getExportObj());
                nodeMap.put(exportNodeId, exportNode);
            }

            // 添加输入节点
            String inputNodeId = flowRel.getInputObjType() + "_" + flowRel.getInputObj();
            if (!nodeMap.containsKey(inputNodeId)) {
                Map<String, Object> inputNode = new HashMap<>();
                inputNode.put("id", inputNodeId);
                inputNode.put("label", flowRel.getInputObjName() != null ? flowRel.getInputObjName() : flowRel.getInputObj());
                inputNode.put("type", flowRel.getInputObjType());
                inputNode.put("code", flowRel.getInputObj());
                nodeMap.put(inputNodeId, inputNode);
            }

            // 添加边（能流关系）
            Map<String, Object> edge = new HashMap<>();
            edge.put("id", String.valueOf(flowRel.getId()));
            edge.put("from", exportNodeId);
            edge.put("to", inputNodeId);
            edge.put("label", flowRel.getEmsClsName() != null ? flowRel.getEmsClsName() : "未知能源");

            // 添加容量信息
            if (flowRel.getFlowCapacity() != null) {
                String capacity = flowRel.getFlowCapacity() +
                    (flowRel.getFlowUnit() != null ? flowRel.getFlowUnit() : "kW");
                edge.put("capacity", capacity);
            }

            edges.add(edge);
        }

        // 转换为List
        List<Map<String, Object>> nodes = new ArrayList<>(nodeMap.values());

        result.put("nodes", nodes);
        result.put("edges", edges);

        return result;
    }

    /**
     * 检查能流关系是否存在
     *
     * @param flowRel 能流关系
     * @return 是否存在
     */
    @Override
    public boolean checkFlowRelExists(EmsObjFlowRel flowRel) {
        EmsObjFlowRel queryParam = new EmsObjFlowRel();
        queryParam.setExportObj(flowRel.getExportObj());
        queryParam.setExportObjType(flowRel.getExportObjType());
        queryParam.setInputObj(flowRel.getInputObj());
        queryParam.setInputObjType(flowRel.getInputObjType());
        queryParam.setEmsCls(flowRel.getEmsCls());

        List<EmsObjFlowRel> list = flowRelMapper.selectFlowRelList(queryParam);

        // 如果是编辑，排除自身
        if (flowRel.getId() != null) {
            list = list.stream()
                .filter(item -> !item.getId().equals(flowRel.getId()))
                .collect(Collectors.toList());
        }

        return !list.isEmpty();
    }

    /**
     * 获取上游能流（输入到该对象的能流）
     *
     * @param objCode 对象代码
     * @param objType 对象类型
     * @return 能流关系列表
     */
    @Override
    public List<EmsObjFlowRel> getUpstreamFlow(String objCode, Integer objType) {
        EmsObjFlowRel queryParam = new EmsObjFlowRel();
        queryParam.setInputObj(objCode);
        queryParam.setInputObjType(objType);
        queryParam.setEnableStatus(1);
        return flowRelMapper.selectFlowRelList(queryParam);
    }

    /**
     * 获取下游能流（从该对象输出的能流）
     *
     * @param objCode 对象代码
     * @param objType 对象类型
     * @return 能流关系列表
     */
    @Override
    public List<EmsObjFlowRel> getDownstreamFlow(String objCode, Integer objType) {
        EmsObjFlowRel queryParam = new EmsObjFlowRel();
        queryParam.setExportObj(objCode);
        queryParam.setExportObjType(objType);
        queryParam.setEnableStatus(1);
        return flowRelMapper.selectFlowRelList(queryParam);
    }

    /**
     * 根据能源类型获取能流关系
     *
     * @param emsClsCode 能源分类代码
     * @param areaCode 区域代码
     * @return 能流关系列表
     */
    @Override
    public List<EmsObjFlowRel> getFlowRelByEnergyType(String emsClsCode, String areaCode) {
        EmsObjFlowRel queryParam = new EmsObjFlowRel();
        if (StringUtils.hasText(emsClsCode)) {
            queryParam.setEmsCls(emsClsCode);
        }
        if (StringUtils.hasText(areaCode)) {
            queryParam.setAreaCode(areaCode);
        }
        queryParam.setEnableStatus(1);
        return flowRelMapper.selectFlowRelList(queryParam);
    }
}