package com.zksy.base.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zksy.base.constant.GasEquipmentTypeEnum;
import com.zksy.base.domain.*;
import com.zksy.base.mapper.*;
import com.zksy.base.service.GasDashboardService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class GasDashboardServiceImpl implements GasDashboardService {

    @Autowired
    private GasPipePointMapper gasPipePointMapper;

    @Autowired
    private EquipmentBaseMapper equipmentBaseMapper;

    @Autowired
    private EquipmentStatusMapper equipmentStatusMapper;

    @Autowired
    private PipeRepairRecordMapper pipeRepairRecordMapper;

    @Autowired
    private HazardHiddenAccountMapper hazardHiddenAccountMapper;

    @Autowired
    private EquipmentTypeMapper equipmentTypeMapper;

    @Autowired
    private PipeNetworkBaseMapper pipeNetworkBaseMapper;

    @Autowired
    private com.zksy.base.pressure.mapper.FirefightingPressureMapper firefightingPressureMapper;

    @Override
    public Map<String, Object> summary() {
        Map<String, Object> result = new LinkedHashMap<>();

        // 1. 基础概况
        //todo: 不管是管点和监测点都不好统计在线和离线(一个管点和监测点都能关联多个燃气设备)
        // 因为状态是设备表里的
        List<GasPipePoint> allPoints = gasPipePointMapper.selectList(null);
        long totalPoints = allPoints.size();
        long onlinePoints = allPoints.stream()
                .filter(p -> "0".equals(p.getStatus()) || "ACTIVE".equals(p.getStatus()))
                .count();
        long offlinePoints = totalPoints - onlinePoints;

        // 2. 燃气设备 + 异常设备统计
        List<String> gasTypeIds = equipmentTypeMapper.selectList(null).stream()
                .filter(t -> GasEquipmentTypeEnum.PARENT_TYPE_ID.equals(t.getParentTypeId()))
                .map(EquipmentType::getId)
                .collect(Collectors.toList());
        List<EquipmentBase> gasEquipments;
        if (gasTypeIds.isEmpty()) {
            gasEquipments = equipmentBaseMapper.selectList(null);
        } else {
            gasEquipments = equipmentBaseMapper.selectList(new LambdaQueryWrapper<EquipmentBase>()
                    .in(EquipmentBase::getEquipmentTypeId, gasTypeIds));
        }
        List<String> gasEquipmentIds = gasEquipments.stream()
                .map(EquipmentBase::getEquipmentId)
                .collect(Collectors.toList());

        List<EquipmentStatus> abnormalList;
        if (gasEquipmentIds.isEmpty()) {
            abnormalList = Collections.emptyList();
        } else {
            abnormalList = equipmentStatusMapper.selectList(
                    new LambdaQueryWrapper<EquipmentStatus>()
                            .in(EquipmentStatus::getEquipmentId, gasEquipmentIds)
                            .and(w -> w.eq(EquipmentStatus::getAlarmStatus, 1)
                                    .or().eq(EquipmentStatus::getOnlineStatus, 0)));
        }
        long alarmCount = abnormalList.size();

        Map<String, Object> baseStats = new LinkedHashMap<>();
        baseStats.put("totalPoints", totalPoints);
        baseStats.put("onlinePoints", onlinePoints);
        baseStats.put("offlinePoints", offlinePoints);
        baseStats.put("alarmCount", alarmCount);
        result.put("baseStats", baseStats);

        // ---- 管网统计 ----
        List<PipeNetworkBase> allNetworks = pipeNetworkBaseMapper.
                selectList(new LambdaQueryWrapper<PipeNetworkBase>().eq(PipeNetworkBase::getNetworkType, "GAS"));
        // 管网总长度(公里)
        double totalLength = allNetworks.stream()
                .filter(n -> n.getLength() != null)
                .mapToDouble(n -> n.getLength().doubleValue())
                .sum();
        double totalLengthKm = Math.round(totalLength / 1000.0 * 100) / 100.0;
        // 燃气管网数量
        long gasNetworkCount = allNetworks.stream()
                .filter(n -> gasTypeIds.contains(n.getNetworkType()) || "GAS".equals(n.getNetworkType()))
                .count();

        Map<String, Object> pipeStats = new LinkedHashMap<>();
        pipeStats.put("totalLength", totalLengthKm);        // 管网总长度(km)
        pipeStats.put("totalNetworks", allNetworks.size()); // 管网总数
        pipeStats.put("gasNetworks", gasNetworkCount);      // 燃气管网数
        result.put("pipeStats", pipeStats);

        // ---- 设备统计 ----
        // 门阀数 = 燃气设备中类型名称含"阀"的数量
        Map<String, String> typeIdToName = equipmentTypeMapper.selectList(null).stream()
                .collect(Collectors.toMap(EquipmentType::getId, EquipmentType::getTypeName, (a, b) -> a));
        long valveCount = gasEquipments.stream()
                .filter(e -> {
                    String typeName = typeIdToName.getOrDefault(e.getEquipmentTypeId(), "");
                    return typeName.contains("阀");
                })
                .count();
        // 今日告警
        String todayStr = LocalDate.now().toString();
        long todayAlarm = equipmentStatusMapper.selectList(
                new LambdaQueryWrapper<EquipmentStatus>()
                        .in(EquipmentStatus::getEquipmentId, gasEquipmentIds)
                        .eq(EquipmentStatus::getAlarmStatus, 1)).stream()
                .filter(s -> s.getStatusUpdateTime() != null && s.getStatusUpdateTime().toString().startsWith(todayStr))
                .count();

        // 压力均值(从firefighting_pressure取最新一条)
        double avgPressure = 0;
        try {
            List<com.zksy.base.pressure.domain.FirefightingPressure> fpList =
                    firefightingPressureMapper.selectList(null);
            if (!fpList.isEmpty()) {
                avgPressure = fpList.stream()
                        .filter(p -> p.getPressureValue() != null)
                        .mapToDouble(com.zksy.base.pressure.domain.FirefightingPressure::getPressureValue)
                        .average().orElse(0);
            }
        } catch (Exception ignored) {}
        double avgPressureMpa = Math.round(avgPressure / 1000.0 * 100) / 100.0; // kPa → MPa

        Map<String, Object> equipmentStats = new LinkedHashMap<>();
        equipmentStats.put("valveCount", valveCount);
        equipmentStats.put("totalEquipment", gasEquipments.size());
        equipmentStats.put("todayAlarm", todayAlarm);
        equipmentStats.put("avgPressure", avgPressureMpa);
        result.put("equipmentStats", equipmentStats);

        List<EquipmentBase> equipmentList = gasEquipments.stream()
                .limit(10)
                .collect(Collectors.toList());
        List<Map<String, Object>> equipmentRows = new ArrayList<>();
        for (int i = 0; i < equipmentList.size(); i++) {
            EquipmentBase e = equipmentList.get(i);
            Map<String, Object> row = new LinkedHashMap<>();
            row.put("id", i + 1);
            row.put("name", e.getEquipmentName());
            row.put("code", e.getEquipmentCode());
            row.put("location", e.getEquipmentLocation());
            EquipmentStatus st = equipmentStatusMapper.selectOne(
                    new LambdaQueryWrapper<EquipmentStatus>().eq(EquipmentStatus::getEquipmentId, e.getEquipmentId()));
            row.put("status", st != null && st.getCurrentStatus() != null ? statusLabel(st.getCurrentStatus()) : "正常");
            equipmentRows.add(row);
        }
        result.put("equipmentRows", equipmentRows);

        // 3. 维修趋势（近6月）
        List<PipeRepairRecord> allRepairs = pipeRepairRecordMapper.selectList(null);
        Map<String, Long> monthMap = new LinkedHashMap<>();
        int nowMonth = LocalDate.now().getMonthValue();
        int nowYear = LocalDate.now().getYear();
        for (int i = 5; i >= 0; i--) {
            int m = nowMonth - i;
            int y = nowYear;
            if (m <= 0) { m += 12; y--; }
            monthMap.put(y + "-" + m + "月", 0L);
        }
        allRepairs.forEach(r -> {
            if (r.getRepairDate() != null) {
                try {
                    LocalDate d = r.getRepairDate();
                    String key = d.getYear() + "-" + d.getMonthValue() + "月";
                    if (monthMap.containsKey(key)) {
                        monthMap.put(key, monthMap.get(key) + 1);
                    }
                } catch (Exception ignored) {}
            }
        });
        List<Map<String, Object>> trendList = new ArrayList<>();
        for (Map.Entry<String, Long> e : monthMap.entrySet()) {
            Map<String, Object> m = new LinkedHashMap<>();
            m.put("month", e.getKey().substring(e.getKey().indexOf("-") + 1));
            m.put("value", e.getValue());
            trendList.add(m);
        }
        result.put("repairTrend", trendList);

        // 4. 告警动态
        //todo 告警动态统计也有问题  这里只是统计了设备表里的设备 不是燃气管点或者监测点
        List<Map<String, Object>> warningRows = new ArrayList<>();
        for (EquipmentStatus a : abnormalList) {
            EquipmentBase eq = equipmentBaseMapper.selectById(a.getEquipmentId());
            boolean isAlarm = a.getAlarmStatus() != null && a.getAlarmStatus() == 1;
            Map<String, Object> row = new LinkedHashMap<>();
            row.put("level", isAlarm ? "高" : "中");
            row.put("title", isAlarm ? "设备报警" : "设备离线");
            row.put("code", eq != null ? eq.getEquipmentCode() : a.getEquipmentId());
            row.put("time", a.getStatusUpdateTime() != null ? a.getStatusUpdateTime().toString() : "--:--:--");
            row.put("desc", isAlarm ? "设备当前状态异常，请及时处理" : "设备处于离线状态");
            row.put("tag", isAlarm ? "设备报警" : "设备离线");
            warningRows.add(row);
        }
        result.put("warningRows", warningRows);

        // 5. 隐患统计
        List<HazardHiddenAccount> allHazards = hazardHiddenAccountMapper.selectList(null);
        Map<String, Long> levelGroup = allHazards.stream()
                .collect(Collectors.groupingBy(h -> {
                    String lv = h.getHazardLevel();
                    if ("0".equals(lv)) return "重大隐患";
                    if ("1".equals(lv)) return "较大隐患";
                    if ("2".equals(lv)) return "一般隐患";
                    return "低风险";
                }, Collectors.counting()));
        result.put("hazardStats", levelGroup);

        // 6. 监测点数据
        List<Map<String, Object>> pointRows = new ArrayList<>();
        for (int i = 0; i < Math.min(allPoints.size(), 8); i++) {
            GasPipePoint p = allPoints.get(i);
            Map<String, Object> row = new LinkedHashMap<>();
            row.put("id", i + 1);
            row.put("name", p.getPointName());
            row.put("time", new Date().toString().substring(11, 16));
            row.put("value", String.format("%.2fMPa", 0.15 + Math.random() * 0.1));
            row.put("status", "0".equals(p.getStatus()) || "ACTIVE".equals(p.getStatus()) ? "在线" : "离线");
            pointRows.add(row);
        }
        result.put("pointRows", pointRows);

        return result;
    }

    private String statusLabel(Integer currentStatus) {
        if (currentStatus == null) return "正常";
        switch (currentStatus) {
            case 1: return "在用";
            case 2: return "闲置";
            case 3: return "维修";
            case 4: return "报废";
            case 5: return "待入库";
            default: return "正常";
        }
    }
}
