package com.yfd.platform.modules.patroltask.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.beanit.iec61850bean.BdaBoolean;
import com.beanit.iec61850bean.BdaTimestamp;
import com.yfd.platform.component.WebSocketServer;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.modules.auxcontrol.domain.AnalogData;
import com.yfd.platform.modules.auxcontrol.mapper.DeviceSignalMapper;
import com.yfd.platform.modules.auxcontrol.service.IDeviceWorkDataService;
import com.yfd.platform.modules.basedata.domain.DeviceChannel;
import com.yfd.platform.modules.basedata.service.IDeviceChannelService;
import com.yfd.platform.modules.basedata.service.ISubstationDeviceService;
import com.yfd.platform.modules.patroltask.domain.AlarmLog;
import com.yfd.platform.modules.patroltask.domain.TaskResult;
import com.yfd.platform.modules.patroltask.mapper.TaskResultMapper;
import com.yfd.platform.modules.patroltask.service.IAlarmLogService;
import com.yfd.platform.modules.patroltask.service.ITaskTodoService;
import com.yfd.platform.utils.SecurityUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 告警日志表 前端控制器
 * </p>
 *
 *
 * @since 2023-05-03
 */
@RestController
@RequestMapping("/patroltask/task-alarm")
@Api(value = "AlarmLogController", tags = "告警日志")
public class AlarmLogController {

    @Resource
    private IAlarmLogService alarmLogService;

    @Resource
    private IDeviceChannelService deviceChannelService;

    @Resource
    private ITaskTodoService taskTodoService;

    @Resource
    private ISubstationDeviceService substationDeviceService;

    @Resource
    private IDeviceWorkDataService deviceWorkDataService;
    @Resource
    private DeviceSignalMapper deviceSignalMapper;

    @Resource
    private TaskResultMapper taskResultMapper;

    @GetMapping("/getAlarmLogList")
    @ApiOperation("查询报警信息")
    public ResponseResult getAlarmLogList(String stationId) {
        if (StrUtil.isBlank(stationId)) {
            return ResponseResult.error("未传变电站信息");
        }
        List<Map<String, Object>> maps = alarmLogService.getAlarmLogList(stationId);
        return ResponseResult.successData(maps);
    }

    @GetMapping("/getNotCheckAlarmCount")
    @ApiOperation("查询未审核告警和数量")
    public ResponseResult getNotCheckAlarmCount(String stationId) {
        if (StrUtil.isBlank(stationId)) {
            return ResponseResult.successData(null);
        }
        List<AlarmLog> list =alarmLogService.getNotCheckAlarmCount(stationId);
//        String[] split = stationId.split(",");
//        LambdaQueryWrapper<AlarmLog> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(AlarmLog::getDatastatus, "1").in(AlarmLog::getStationId, Arrays.asList(split)).eq(AlarmLog::getCheckFlag
//                , 0).orderByDesc(AlarmLog::getAlarmDate);
//        List<AlarmLog> list = alarmLogService.list(queryWrapper);
        Map<String, Object> map = new HashMap<>();
        map.put("count", list.size());
        map.put("notCheck", list);
        return ResponseResult.successData(map);
    }

    @GetMapping("/getNotCheckAlarmInfo")
    @ApiOperation("根据任务id查询未审核告警和数量")
    public ResponseResult getNotCheckAlarmInfo(String taskTodoIds) {
        List<Map<String, Object>> list = taskTodoService.getNotCheckAlarmInfo(taskTodoIds);
        Map<String, Object> map = new HashMap<>();
        map.put("count", list.size());
        map.put("notCheck", list);
        return ResponseResult.successData(map);
    }

    @GetMapping("/getExceptionEventStat")
    @ApiOperation("异常事件统计")
    public ResponseResult getExceptionEventStat(String stationId) {
        if (StrUtil.isBlank(stationId)) {
            return ResponseResult.error("未传变电站信息");
        }
        List<String> idList = Arrays.asList(stationId.split(","));
        LambdaQueryWrapper<AlarmLog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(AlarmLog::getStationId, idList).isNotNull(AlarmLog::getAlarmLevel).eq(AlarmLog::getDatastatus, "1").select(AlarmLog::getId,
                AlarmLog::getContent, AlarmLog::getAlarmLevel, AlarmLog::getAlarmDate, AlarmLog::getStationName);
        List<Map<String, Object>> maps = alarmLogService.listMaps(queryWrapper);
        Map<Object, List<Map<String, Object>>> alarmLevel = maps.stream().collect(Collectors.groupingBy(m -> m.get(
                "alarmLevel")));
        List<Map<String, Object>> maps1 = alarmLevel.get("1");
        List<Map<String, Object>> maps2 = alarmLevel.get("2");
        List<Map<String, Object>> maps3 = alarmLevel.get("3");
        List<Map<String, Object>> maps4 = alarmLevel.get("4");
        Map<String, Object> alarmMap = new HashMap<>();
        if (maps1 == null || maps1.size() == 0) {
            alarmMap.put("warnEvent", 0);
        } else {
            alarmMap.put("warnEvent", maps1.size());
        }
        if (maps2 == null || maps2.size() == 0) {
            alarmMap.put("sameEvent", 0);
        } else {
            alarmMap.put("sameEvent", maps2.size());
        }
        if (maps3 == null || maps3.size() == 0) {
            alarmMap.put("seriousEvent", 0);
        } else {
            alarmMap.put("seriousEvent", maps3.size());
        }
        if (maps4 == null || maps4.size() == 0) {
            alarmMap.put("crisisEvent", 0);
        } else {
            alarmMap.put("crisisEvent", maps4.size());
        }
        return ResponseResult.successData(alarmMap);
    }

    @GetMapping("/getAlarmListByType")
    @ApiOperation("静默监视查询")
    public ResponseResult getAlarmListByType(Page<Map<String, Object>> page, String stationId, String areaId,
                                             String patrolDeviceName, String monitorType) {
        Page<Map<String, Object>> alarmList = alarmLogService.getAlarmListByType(page, stationId, areaId,
                patrolDeviceName, monitorType);
        List<Map<String, Object>> records = alarmList.getRecords();
        records.forEach(r -> {
            String patroldeviceCode = r.get("patroldeviceCode").toString();
            LambdaQueryWrapper<DeviceChannel> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(DeviceChannel::getDeviceid, patroldeviceCode).select(DeviceChannel::getDeviceid,
                    DeviceChannel::getChannelid);
            List<Map<String, Object>> channelList = deviceChannelService.listMaps(queryWrapper1);
            if (channelList != null && channelList.size() > 0) {
                r.put("channelList", channelList);
            }
        });
        alarmList.setRecords(records);
        return ResponseResult.successData(alarmList);
    }

    @GetMapping("/getAlarmListPage")
    @ApiOperation("根据设备编号查询告警列表")
    public ResponseResult getAlarmListPage(Page<Map<String, Object>> page, String patrolDeviceCode,
                                           String monitorType, String startDate, String endDate) {
        String startFormat = "";
        if (StrUtil.isNotBlank(startDate)) {
            Date parseStart = DateUtil.parse(startDate);
            //一天的开始
            Date beginOfDay = DateUtil.beginOfDay(parseStart);
            startFormat = DateUtil.format(beginOfDay, "yyyy-MM-dd HH:mm:ss");
        }
        String endFormat = "";
        if (StrUtil.isNotBlank(startDate)) {
            Date parseEnd = DateUtil.parse(endDate);
            //一天的结束
            Date endOfDay = DateUtil.endOfDay(parseEnd);
            endFormat = DateUtil.format(endOfDay, "yyyy-MM-dd HH:mm:ss");
        }
        Page<Map<String, Object>> alarmList = alarmLogService.getAlarmListPage(page, patrolDeviceCode, monitorType,
                startFormat, endFormat);
        return ResponseResult.successData(alarmList);
    }

    @GetMapping("/getAlarmLogPage")
    @ApiOperation("告警信息确认分页")
    public ResponseResult getAlarmLogPage(Page<Map<String, Object>> page, String stationCode, String taskAlarmType,
                                          String alarmLevel, String checkFlag,String alarmSourceType, String startDate, String endDate) {
        if (StrUtil.isBlank(stationCode)) {
            return ResponseResult.error("未传变电站信息");
        }
        Page<Map<String, Object>> alarmList = alarmLogService.getAlarmLogPage(page, stationCode, taskAlarmType,
                alarmLevel, checkFlag,alarmSourceType, startDate, endDate);

        List<Map<String, Object>> records = alarmList.getRecords();
        records.forEach(r -> {

            String patroldeviceCode = r.get("patroldeviceCode").toString();
            LambdaQueryWrapper<DeviceChannel> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(DeviceChannel::getDeviceid, patroldeviceCode).select(DeviceChannel::getDeviceid,
                    DeviceChannel::getChannelid);
            List<Map<String, Object>> channelList = deviceChannelService.listMaps(queryWrapper1);
            if (channelList != null && channelList.size() > 0) {
                r.put("channelList", channelList);
            }
        });
        alarmList.setRecords(records);
        return ResponseResult.successData(alarmList);
    }

    @PostMapping("/setAlarmLogStatus")
    @ApiOperation("告警信息核查")
    public ResponseResult setAlarmLogStatus(@RequestBody AlarmLog alarmLog) {
        if (alarmLog == null) {
            return ResponseResult.error("参数为空");
        }
        boolean ok = alarmLogService.setAlarmLogStatus(alarmLog);
        if (ok) {
            return ResponseResult.success();
        } else {
            return ResponseResult.error("核查失败");
        }

    }

    @PostMapping("/setBatchAlarmLogStatus")
    @ApiOperation("告警信息批量核查")
    public ResponseResult batchSetAlarmLogStatus(String alarmJson) {
        if (StrUtil.isBlank(alarmJson)) {
            return ResponseResult.error("参数为空");
        }
        JSONObject objects = new JSONObject(alarmJson);
        Map alarm = objects.toBean(Map.class);
        String ids = Objects.isNull(alarm.get("ids")) ? "" : alarm.get("ids").toString();
        if (StrUtil.isBlank(ids)) {
            return ResponseResult.error("已经核查的信息不能再次核查");
        }
        String[] split = ids.split(",");
        String checkComment = Objects.isNull(alarm.get("checkComment")) ? "" : alarm.get("checkComment").toString();
        String checkFlag = Objects.isNull(alarm.get("checkFlag")) ? "" : alarm.get("checkFlag").toString();
        String currentUsername = SecurityUtils.getCurrentUsername();
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(timestamp);
        for (String id : split) {
            LambdaUpdateWrapper<AlarmLog> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(AlarmLog::getCheckComment, checkComment).set(AlarmLog::getCheckFlag, checkFlag).set(AlarmLog::getLastmodifier, currentUsername).set(AlarmLog::getCheckUserName, currentUsername).set(AlarmLog::getLastmodifydate, timestamp).set(AlarmLog::getCheckDate, format).eq(AlarmLog::getId, id);
            alarmLogService.update(updateWrapper);
            AlarmLog alarmLog = alarmLogService.getById(id);
            Map<String, Object> logMap = BeanUtil.beanToMap(alarmLog);
            String stationId = alarmLog.getStationId();
            LambdaQueryWrapper<AlarmLog> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(AlarmLog::getDatastatus, "1").eq(AlarmLog::getStationId, stationId).eq(AlarmLog::getCheckFlag, 0);
            int count = alarmLogService.count(queryWrapper1);
            logMap.put("alarmCount", count);
            JSONObject jsonObject = new JSONObject(logMap);
            WebSocketServer.sendInfo("check_" + alarmLog.getStationId(), jsonObject.toString());
        }
        return ResponseResult.success();
    }

    @GetMapping("/getAlarmHistory")
    @ApiOperation("根据机器人编号查询告警历史（前20条）")
    public ResponseResult getAlarmHistory(String patroldeviceCode) {
        LambdaQueryWrapper<AlarmLog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AlarmLog::getPatroldeviceCode, patroldeviceCode).select(AlarmLog::getAlarmDate,AlarmLog::getContent).orderByDesc(AlarmLog::getAlarmDate).last("LIMIT 20");
        List<Map<String, Object>> mapList = alarmLogService.listMaps(queryWrapper);
        return ResponseResult.successData(mapList);
    }

    @GetMapping("/getAlarmLogById")
    @ApiOperation("根据告警信息ID查询详情")
    public ResponseResult getAlarmLogById(String id) {
        Map<String, Object> alarmLog = alarmLogService.getAlarmLogById(id);
        return ResponseResult.successData(alarmLog);
    }


    @GetMapping("/getConfirmationRate")
    @ApiOperation("告警准确率统计")
    public ResponseResult getConfirmationRate(String stationId) {
        Map<String, Object> alarmLog = alarmLogService.getConfirmationRate(stationId);
        return ResponseResult.successData(alarmLog);
    }

    @GetMapping("/sendAlarmById")
    @ApiOperation("发送报警")
    public ResponseResult sendAlarmById(String stationId,String id) {
        AlarmLog alarmLog = alarmLogService.getById(id);
        JSONObject jsonObject = JSONUtil.parseObj(alarmLog);
        TaskResult taskResult = taskResultMapper.selectById(alarmLog.getTaskResultId());
        jsonObject.putOpt("channelId", taskResult.getPatroldeviceChannelcode());
        jsonObject.putOpt("deviceId", taskResult.getPatroldeviceCode());
        WebSocketServer.sendInfo(stationId, jsonObject.toString());
        return ResponseResult.success();
    }

    public static String getCurrentTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        return sdf.format(new Date());
    }

    @PostMapping("/sendAnalogData")
    @ApiOperation("批量发送数据")
    public ResponseResult sendAnalogData(@RequestBody List<AnalogData> analogDataList) {
        for (AnalogData analogData : analogDataList) {
            if ("yc".equals(analogData.getType())) {
                //更新信号数据值
                deviceSignalMapper.updateDeviceSignalValue_yc(analogData.getAddress(), analogData.getValue(),
                        getCurrentTime());
                //插入历史数据
                deviceWorkDataService.insertData("IEC61850", null, analogData.getAddress(), analogData.getValue(),
                        getCurrentTime());
                //执行报警处理
                alarmLogService.doAlaramRecord("IEC61850", "yc", null, analogData.getAddress(), analogData.getValue());

            }
            if ("yx".equals(analogData.getType())) {
                //更新信号状态
                deviceSignalMapper.updateDeviceSignalValue_yx(analogData.getAddress(), analogData.getValue(),
                        getCurrentTime());
                //执行报警处理：生成设备自身报警记录（status=1）
                alarmLogService.doAlaramRecord("IEC61850", "yx", null, analogData.getAddress(), analogData.getValue());
            }
        }

        return ResponseResult.success();
    }

}
