package com.ruoyi.manage.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.model.MqttMessage;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.manage.domain.EquipmentManage;
import com.ruoyi.manage.domain.WarnManage;
import com.ruoyi.manage.mapper.EquipmentManageMapper;
import com.ruoyi.manage.mapper.WarnManageMapper;
import com.ruoyi.manage.service.IWarnManageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.ruoyi.common.constant.Constants.*;

/**
 * 告警管理Service业务层处理
 *
 * @author boman
 * @date 2025-06-19
 */
@Slf4j
@Service
public class WarnManageServiceImpl implements IWarnManageService {
    @Autowired
    private WarnManageMapper warnManageMapper;
    @Autowired
    private EquipmentManageMapper equipmentManageMapper;
    @Autowired
    private RedisCache redisCache;

    /**
     * 查询告警管理
     *
     * @param warnId 告警管理主键
     * @return 告警管理
     */
    @Override
    public WarnManage selectWarnManageByWarnId(Long warnId) {
        return warnManageMapper.selectWarnManageByWarnId(warnId);
    }

    /**
     * 查询告警管理列表
     *
     * @param warnManage 告警管理
     * @return 告警管理
     */
    @Override
    public List<WarnManage> selectWarnManageList(WarnManage warnManage) {
        return warnManageMapper.selectWarnManageList(warnManage);
    }

    /**
     * 新增告警管理
     *
     * @param warnManage 告警管理
     * @return 结果
     */
    @Override
    public int insertWarnManage(WarnManage warnManage) {
        warnManage.setCreateTime(DateUtils.getNowDate());
        return warnManageMapper.insertWarnManage(warnManage);
    }

    /**
     * 修改告警管理
     *
     * @param warnManage 告警管理
     * @return 结果
     */
    @Override
    public int updateWarnManage(WarnManage warnManage) {
        warnManage.setUpdateTime(DateUtils.getNowDate());
        return warnManageMapper.updateWarnManage(warnManage);
    }

    /**
     * 批量删除告警管理
     *
     * @param warnIds 需要删除的告警管理主键
     * @return 结果
     */
    @Override
    public int deleteWarnManageByWarnIds(Long[] warnIds) {
        return warnManageMapper.deleteWarnManageByWarnIds(warnIds);
    }

    /**
     * 删除告警管理信息
     *
     * @param warnId 告警管理主键
     * @return 结果
     */
    @Override
    public int deleteWarnManageByWarnId(Long warnId) {
        return warnManageMapper.deleteWarnManageByWarnId(warnId);
    }

    /**
     * 告警内容+部门统计
     *
     * @return
     */
    @Override
    public AjaxResult getWarnManageIndex() {
        //定义返回值
        Map<String, Object> map = new HashMap<>(9);
        WarnManage warnManage = new WarnManage();
        warnManage.setWarnTime(DateUtils.getNowDate());
        //当月告警数据
        List<WarnManage> warnManages = warnManageMapper.selectWarnManageDeptListByTime(warnManage);
        int warnMonthAll = 0;
        int warnMonthLeave = 0;
        int warnMonthPlay = 0;
        int warnMonthLastAll = 0;
        int warnMonthLastLeave = 0;
        int warnMonthLastPlay = 0;
        //本月部门数据
        List<Map<String, Object>> deptNameMapList = new ArrayList<>();
        //上月部门数据
        List<Map<String, Object>> deptNameLastMapList = new ArrayList<>();
        //计算告警数据
        if (warnManages != null && !warnManages.isEmpty()) {
            warnMonthAll = warnManages.size();
            Map<String, List<WarnManage>> collect = warnManages.stream().collect(Collectors.groupingBy(WarnManage::getAlgorithmType));
            if (!collect.isEmpty()) {
                //离岗
                if (collect.get(ZERO) != null && !collect.get(ZERO).isEmpty()) {
                    warnMonthLeave = collect.get(ZERO).size();
                }
                //玩手机
                if (collect.get(ONE) != null && !collect.get(ONE).isEmpty()) {
                    warnMonthPlay = collect.get(ONE).size();
                }
            }
            //插入当月部门数据
            Map<Long, List<WarnManage>> deptNameCollect = warnManages.stream().filter( e ->e.getDeptId() != null).collect(Collectors.groupingBy(WarnManage::getDeptId));
            List<Map<String, Object>> finalDeptNameMapList = new ArrayList<>();
            deptNameCollect.forEach((deptId, v) -> {
                Map<String, Object> deptMap = new HashMap<>(3);
                deptMap.put("deptName", v.get(0).getDeptName());
                deptMap.put("warnNum", String.valueOf(v.size()));
                deptMap.put("deptId", deptId);
                finalDeptNameMapList.add(deptMap);
            });
            deptNameMapList = finalDeptNameMapList;
        }

        //上月告警数据
        Map<String, Object> warnLastMonth = redisCache.getCacheMap(WARN_LAST_MONTH + DateUtils.getMonth());
        if (warnLastMonth.isEmpty()) {
            Map<String, Object> lastMap = new HashMap<>();
            //从数据库查询
            warnManage.setWarnTime(DateUtils.getLastMonth());
            List<WarnManage> warnManagesLast = warnManageMapper.selectWarnManageDeptListByTime(warnManage);
            if (warnManagesLast != null && !warnManagesLast.isEmpty()) {
                warnMonthLastAll = warnManagesLast.size();
                Map<String, List<WarnManage>> collect = warnManagesLast.stream().collect(Collectors.groupingBy(WarnManage::getAlgorithmType));
                if (!collect.isEmpty()) {
                    //离岗
                    if (collect.get(ZERO) != null && !collect.get(ZERO).isEmpty()) {
                        warnMonthLastLeave = collect.get(ZERO).size();
                    }
                    //玩手机
                    if (collect.get(ONE) != null && !collect.get(ONE).isEmpty()) {
                        warnMonthLastPlay = collect.get(ONE).size();
                    }
                }
                //插入上月部门数据
                Map<Long, List<WarnManage>> deptNameCollect = warnManagesLast.stream().filter( e ->e.getDeptId() != null).collect(Collectors.groupingBy(WarnManage::getDeptId));
                List<Map<String, Object>> finalDeptNameLastMapList = new ArrayList<>();
                deptNameCollect.forEach((deptId, v) -> {
                    Map<String, Object> deptMap = new HashMap<>(3);
                    deptMap.put("deptName", v.get(0).getDeptName());
                    deptMap.put("warnNum", String.valueOf(v.size()));
                    deptMap.put("deptId", deptId);
                    finalDeptNameLastMapList.add(deptMap);
                });
                deptNameLastMapList = finalDeptNameLastMapList;
            }
            lastMap.put("deptNameCollect", deptNameLastMapList);
            lastMap.put("warnMonthLastAll", warnMonthLastAll);
            lastMap.put("warnMonthLastLeave", warnMonthLastLeave);
            lastMap.put("warnMonthLastPlay", warnMonthLastPlay);
            redisCache.setCacheMap(WARN_LAST_MONTH + DateUtils.getMonth(), lastMap);
        } else {
            warnMonthLastAll = Integer.parseInt(warnLastMonth.get("warnMonthLastAll").toString());
            warnMonthLastLeave = Integer.parseInt(warnLastMonth.get("warnMonthLastLeave").toString());
            warnMonthLastPlay = Integer.parseInt(warnLastMonth.get("warnMonthLastPlay").toString());
            deptNameLastMapList = convertObjectToList(warnLastMonth.get("deptNameCollect"));
        }

        //进行本月部门数据和上月部门数据对比，已本月部门数据为主
        if (!deptNameMapList.isEmpty()) {
            List<Map<String, Object>> finalDeptNameMapList = deptNameLastMapList;
            deptNameMapList.forEach(deptNameMap -> {
                String deptId = deptNameMap.get("deptId").toString();
                String warnNum = deptNameMap.get("warnNum").toString();
                String warnNumLast = "0";
                if (!finalDeptNameMapList.isEmpty()) {
                    for (Map<String, Object> lastMonthDeptMap : finalDeptNameMapList) {
                        String deptIdLast = lastMonthDeptMap.get(deptId).toString();
                        if (StringUtils.isNotEmpty(deptIdLast)) {
                            warnNumLast = lastMonthDeptMap.get("warnNum").toString();
                        }
                    }
                }
                //计算百分比
                Map<String, String> numPt = getNumPt(Double.parseDouble(warnNum), Double.parseDouble(warnNumLast));
                String warnDeptPt = numPt.get("pt");
                String warnDeptPtStatus = numPt.get("ptStatus");
                deptNameMap.put("warnDeptPt", warnDeptPt);
                deptNameMap.put("warnDeptPtStatus", warnDeptPtStatus);
            });
        }
        map.put("warnMonthAll", warnMonthAll);
        Map<String, String> numPt = getNumPt(warnMonthAll, warnMonthLastAll);
        map.put("warnMonthPt", numPt.get("pt"));
        map.put("warnMonthPtStatus", numPt.get("ptStatus"));
        map.put("warnMonthLeave", warnMonthLeave);
        Map<String, String> numPt1 = getNumPt(warnMonthLeave, warnMonthLastLeave);
        map.put("warnMonthLeavePt", numPt1.get("pt"));
        map.put("warnMonthLeavePtStatus", numPt1.get("ptStatus"));
        map.put("warnMonthPlay", warnMonthPlay);
        Map<String, String> numPt2 = getNumPt(warnMonthPlay, warnMonthLastPlay);
        map.put("warnMonthPlayPt", numPt2.get("pt"));
        map.put("warnMonthPlayPtStatus", numPt2.get("ptStatus"));
        map.put("deptNameMapList", deptNameMapList);
        return AjaxResult.success(map);
    }

    /**
     * 年度告警统计
     * 接收年份查询
     */
    @Override
    public AjaxResult warnManageIndexYear(String year) {
        Map<String, Object> map = new HashMap<>();
        //当前年份数据从数据库查询
        if (StringUtils.isNotEmpty(year) && DateUtils.getYear().equals(year)) {
            return warnManageIndexYearData(year);
        } else {
            map = redisCache.getCacheMap(WARN_MANAGE_LAST_YEAR + year);
            if (map == null) {
                return warnManageIndexYearData(year);
            }
        }
        return AjaxResult.success(map);

    }


    /**
     * 从数据库查询
     *
     * @param year
     * @return
     */
    public AjaxResult warnManageIndexYearData(String year) {
        //定义返回值
        Map<String, Object> map = new HashMap<>(3);
        List<String> x = new ArrayList<>(Arrays.asList("01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"));
        List<Integer> y1 = new ArrayList<>();
        List<Integer> y2 = new ArrayList<>();
        WarnManage warnManage = new WarnManage();
        Map<String, Object> params = new HashMap<>();
        params.put("year", year);
        warnManage.setParams(params);
        //按年份检索的数据
        List<WarnManage> warnManages = warnManageMapper.selectWarnManageList(warnManage);
        if (warnManages != null && !warnManages.isEmpty()) {
            // 使用Collectors.groupingBy按月份分组
            Map<String, List<WarnManage>> WarnManageCollectMonth = warnManages.stream().collect(Collectors.groupingBy(item ->
                    new SimpleDateFormat("MM").format(item.getWarnTime())));
            for (String month : x) {
                List<WarnManage> warnManagesMonthList = WarnManageCollectMonth.get(month);
                //如果当月没有告警
                if (warnManagesMonthList != null && !warnManagesMonthList.isEmpty()) {
                    Map<String, List<WarnManage>> algorithmTypeCollect = warnManagesMonthList.stream().collect(Collectors.groupingBy(WarnManage::getAlgorithmType));
                    if (algorithmTypeCollect != null && !algorithmTypeCollect.isEmpty()) {
                        //离岗
                        if (algorithmTypeCollect.get(ZERO) != null && !algorithmTypeCollect.get(ZERO).isEmpty()) {
                            y1.add(algorithmTypeCollect.get(ZERO).size());
                        } else {
                            y1.add(0);
                        }
                        //玩手机
                        if (algorithmTypeCollect.get(ONE) != null && !algorithmTypeCollect.get(ONE).isEmpty()) {
                            y2.add(algorithmTypeCollect.get(ONE).size());
                        } else {
                            y2.add(0);
                        }
                    }
                } else {
                    y1.add(0);
                    y2.add(0);
                }
            }
        }
        map.put("x", x);
        map.put("y1", y1);
        map.put("y2", y2);
        //把非当前年份的数据存储到redis
        if (StringUtils.isNotEmpty(year) && !DateUtils.getYear().equals(year)) {
            redisCache.setCacheMap(WARN_MANAGE_LAST_YEAR + year, map);
        }
        return AjaxResult.success(map);
    }

    public static List<Map<String, Object>> convertObjectToList(Object obj) {
        // 1. 检查是否为 List 类型
        if (!(obj instanceof List<?>)) {
            throw new IllegalArgumentException("Object is not a List");
        }

        List<?> rawList = (List<?>) obj;

        // 2. 遍历检查内部元素是否为 Map 类型
        for (Object item : rawList) {
            if (!(item instanceof Map<?, ?>)) {
                throw new IllegalArgumentException("List contains non-Map elements");
            }

            Map<?, ?> map = (Map<?, ?>) item;
            // 3. 检查 Map 的键值类型（可选但推荐）
            for (Map.Entry<?, ?> entry : map.entrySet()) {
                if (!(entry.getKey() instanceof String) || !(entry.getValue() instanceof String)) {
                    throw new IllegalArgumentException(
                            "Map contains non-String key/value: " + entry.getKey() + "=" + entry.getValue()
                    );
                }
            }
        }

        // 4. 安全强制转换（已验证类型）
        return (List<Map<String, Object>>) obj;
    }


    //计算两个数的百分比和是上升还是下降
    public static Map<String, String> getNumPt(double a, double b) {
        DecimalFormat df = new DecimalFormat("##.##%");
        Map<String, String> map = new HashMap<>(2);
        if (a > 0 && b < 1) {
            map.put("ptStatus", ONE);
            map.put("pt", "100.00%");
            return map;
        } else if (a < 1 && b > 0) {
            map.put("ptStatus", TWO);
            map.put("pt", "100.00%");
            return map;
        } else if (a < 1 && b < 1) {
            map.put("ptStatus", ONE);
            map.put("pt", "0.00%");
            return map;
        } else if (a > 0 && b > 0) {
            if (a > b) {
                map.put("ptStatus", ONE);
                String format = df.format((a - b) / b);
                map.put("pt", format);
            }
            if (b > a) {
                map.put("ptStatus", TWO);
                String format = df.format((b - a) / b);
                map.put("pt", format);
            }
        }
        return map;
    }

    /**
     * 算法回调新增告警信息
     *
     * @param message
     */
    public void addWarnManage(MqttMessage message, String algorithmType) {
        try {
            String payload = message.getPayload();
            JSONObject jsonObject = JSONObject.parseObject(payload);
            String equipmentIp = jsonObject.getString("equipmentIp");
            EquipmentManage equipmentManage = new EquipmentManage();
            equipmentManage.setEquipmentIp(equipmentIp);
            EquipmentManage equipmentManageOld = equipmentManageMapper.selectEquipmentManageByEquipmentIp(equipmentManage);
            Long channelId = jsonObject.getLong("channelId");
            String parameterSet = jsonObject.getString("parameterSet");
            String algorithmResult = jsonObject.getString("algorithmResult");
            String photoUrl = jsonObject.getString("photoUrl");
            String videoUrl = jsonObject.getString("videoUrl");
            String rangName = jsonObject.getString("name");
            WarnManage warnManage = new WarnManage();
            warnManage.setEquipmentIp(equipmentIp);
            warnManage.setEquipmentName(equipmentManageOld.getEquipmentName());
            warnManage.setEquipmentId(equipmentManageOld.getEquipmentId());
            warnManage.setChannelId(channelId);
            warnManage.setParameterSet(parameterSet);
            warnManage.setAlgorithmType(algorithmType);
            warnManage.setReportStatus(algorithmResult);
            warnManage.setVideoAddress(videoUrl);
            warnManage.setWarnImage(photoUrl);
            warnManage.setCreateTime(DateUtils.getNowDate());
            warnManage.setWarnTime(DateUtils.getNowDate());
            warnManage.setRangName(rangName);
            warnManageMapper.insertWarnManage(warnManage);
        } catch (Exception e) {
            log.info("新增告警信息异常：{}", e.getMessage());
        }
    }
}
