package com.ruoyi.system.service.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.dto.PrintExcelDTO;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.ReportDataService;
import com.ruoyi.system.service.SaveDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * classname: 站点信息
 * description  服务实现类
 */
@Service
@Slf4j
public class SaveDataServiceImpl implements SaveDataService {

    @Resource
    private HeartBeatMapper heartBeatMapper;

    @Resource
    private SiteInfoMapper siteInfoMapper;

    @Resource
    private TaskNoticeMapper taskNoticeMapper;

    @Resource
    private TaskResultMapper taskResultMapper;

    @Resource
    private CarPositionMapper carPositionMapper;

    @Resource
    private MeasureUploadMapper measureUploadMapper;

    @Resource
    private WaterLevelMapper waterLevelMapper;

    @Resource
    ReportDataService reportDataService;

    @Resource
    private BerthingPointConfigMapper berthingPointConfigMapper;

    @Resource
    private BerthingPointMapper berthingPointMapper;



    @Override
    public void saveDate(String data, String topics) {
        String[] topicsList = topics.split("/");
        if (topicsList.length == 3) {
            String action = topicsList[2];
            switch (action) {
                case "heartbeat" ->
                    //存入心跳
                        heartbeat(data);
                case "startMeasure" ->
                    //开始测流
                        startMeasure(data);
                case "taskFault" ->
                    //任务故障
                        taskFault(data);
                case "positionUpdate" ->
                    //小车位置
                        positionUpdate(data);
                case "measureBegin" ->
                    //停泊点开始测流
                        measureBegin(data);
                case "measureUpload" ->
                    //停泊点流速上报
                        measureUpload(data);
                case "return" ->
                    //小车开始返航
                        xiaoReturn(data);
                case "taskend" ->
                    //小车任务完成上报
                        taskend(data);
                case "waterLevelUpload" ->
                    //水位数据上报
                        waterLevelUpload(data);
                case "resultUpload" ->
                    //测流结果上报
                        resultUpload(data);
                default -> log.error("topic 命令没找到:{}", topics);
            }
        } else {
            log.error("topic is error:{}",topics);
        }
    }

    public void heartbeat(String data){
        try {
            HeartBeat heartBeat = JSONUtil.toBean(data, HeartBeat.class);
            heartBeat.setHeartId(0L);
            heartBeat.setCreateTime(new Date());
            SiteInfo siteInfo = siteInfoMapper.queryBySiteCode(heartBeat.getId());
            if (siteInfo == null){
                log.error("查询站点失败入库失败 站码:{}",heartBeat.getId());
                return;
            }
            heartBeat.setSiteId(siteInfo.getSiteId());
            heartBeatMapper.insert(heartBeat);
            log.info("insert heartbeat:{}",heartBeat);
        } catch (Exception e) {
            log.error("存入心跳 入库错误:",e);
        }

    }

    public void startMeasure(String data){
        try {
            TaskNotice taskNotice = JSONUtil.toBean(data, TaskNotice.class);
            SiteInfo siteInfo = siteInfoMapper.queryBySiteCode(taskNotice.getId());
            if (siteInfo == null) {
                log.error("开始测流 查询站点失败 Id:{}", taskNotice.getId());
                return;
            }
            taskNotice.setStartId(0L);
            if (taskNotice.getWorkmode() == 1) {
                taskNotice.setRemark("时间任务触发 开始测流任务");
            } else if (taskNotice.getWorkmode() == 2) {
                taskNotice.setRemark("变幅任务触发 开始测流任务");
            } else if (taskNotice.getWorkmode() == 3) {
                taskNotice.setRemark("手动任务触发 开始测流任务");
            }
            taskNotice.setCreateTime(new Date());
            taskNotice.setSiteId(siteInfo.getSiteId());
            taskNoticeMapper.insert(taskNotice);
            //新建结果报告 状态设置为测流中
            TaskResult taskResult = new TaskResult();
            taskResult.setTaskid(taskNotice.getTaskid());
            taskResult.setSiteId(siteInfo.getSiteId());
            //查询有无重复taskId
            if (taskResultMapper.count(taskResult) > 0){
                log.error("开始测流 新建报告taskId重复 Id:{}", taskNotice.getId());
                return;
            }
            taskResult.setType(0); // 移动测流
            taskResult.setPlanid(taskNotice.getPlanid());
            taskResult.setResultId(0L);
            taskResult.setStatus(0);
            taskResult.setCreateTime(new Date());
            taskResultMapper.insert(taskResult);
        } catch (Exception e) {
            log.error("开始测流 入库错误:",e);
        }

    }

    public void taskFault(String data) {
        try {
            TaskNotice taskNotice = JSONUtil.toBean(data, TaskNotice.class);
            SiteInfo siteInfo = siteInfoMapper.queryBySiteCode(taskNotice.getId());
            if (siteInfo == null) {
                log.error("查询站点失败入库失败 站码:{}", taskNotice.getId());
                return;
            }
            taskNotice.setStartId(0L);
            taskNotice.setRemark("任务故障");
            taskNotice.setCreateTime(new Date());
            taskNotice.setSiteId(siteInfo.getSiteId());
            taskNoticeMapper.insert(taskNotice);
        } catch (Exception e) {
            log.error("任务故障 入库错误:", e);
        }
    }
    public void positionUpdate(String data){
        try {
            CarPosition carPosition= JSONUtil.toBean(data, CarPosition.class);
            SiteInfo siteInfo = siteInfoMapper.queryBySiteCode(carPosition.getId());
            if (siteInfo == null) {
                log.error("查询站点失败入库失败 站码:{}", carPosition.getId());
                return;
            }
            carPosition.setSiteId(siteInfo.getSiteId());
            carPosition.setCarId(0L);
            carPosition.setCreateTime(new Date());
            carPositionMapper.insert(carPosition);
        } catch (Exception e) {
            log.error("小车位置 入库错误:", e);
        }
    }

    public void measureBegin(String data){
        try {
            TaskNotice taskNotice = JSONUtil.toBean(data, TaskNotice.class);
            SiteInfo siteInfo = siteInfoMapper.queryBySiteCode(taskNotice.getId());
            if (siteInfo == null) {
                log.error("查询站点失败入库失败 站码:{}", taskNotice.getId());
                return;
            }
            taskNotice.setStartId(0L);
            taskNotice.setRemark(taskNotice.getPn() + "号停泊点开始测流");
            taskNotice.setCreateTime(new Date());
            taskNotice.setSiteId(siteInfo.getSiteId());
            taskNoticeMapper.insert(taskNotice);
        } catch (Exception e) {
            log.error("停泊点开始测流 入库错误:", e);
        }
    }

    public void measureUpload(String data){
        try {
            MeasureUpload measureUpload= JSONUtil.toBean(data, MeasureUpload.class);
            SiteInfo siteInfo = siteInfoMapper.queryBySiteCode(measureUpload.getId());
            if (siteInfo == null) {
                log.error("查询站点失败入库失败 无法查询站点 站码:{}", measureUpload.getId());
                return;
            }
            WaterLevel waterLevel = reportDataService.getWaterLevel(siteInfo.getSiteId());
            if (waterLevel == null){
                log.error("查询站点失败入库失败 无法查询水位 站码:{}", measureUpload.getId());
                return;
            }
            BerthingPointConfig berthingPointConfig = berthingPointConfigMapper.queryByPlanid(siteInfo.getSiteId(), measureUpload.getPlanid());
            if (berthingPointConfig == null){
                log.error("查询站点失败入库失败 无法查询停泊点信息 站码:{}", measureUpload.getId());
                return;
            }
            List<PrintExcelDTO> positions = JSON.parseObject(berthingPointConfig.getPositions(), new TypeReference<>() {});
            PrintExcelDTO printExcelDTO = positions.get(Math.toIntExact(measureUpload.getPn()) - 1);
            measureUpload.setPointX(printExcelDTO.getX());
            measureUpload.setWaterlevel(waterLevel.getWaterlevel());
            measureUpload.setSiteId(siteInfo.getSiteId());
            measureUpload.setMeasureId(0L);
            measureUpload.setCreateTime(new Date());
            measureUploadMapper.insert(measureUpload);
        } catch (Exception e) {
            log.error("停泊点流速上报 入库错误:", e);
        }
    }

    public void taskend(String data){
        try {
            TaskNotice taskNotice = JSONUtil.toBean(data, TaskNotice.class);
            SiteInfo siteInfo = siteInfoMapper.queryBySiteCode(taskNotice.getId());
            if (siteInfo == null) {
                log.error("查询站点失败入库失败 站码:{}", taskNotice.getId());
                return;
            }
            taskNotice.setStartId(0L);
            taskNotice.setRemark("小车任务完成");
            taskNotice.setCreateTime(new Date());
            taskNotice.setSiteId(siteInfo.getSiteId());
            taskNoticeMapper.insert(taskNotice);
            //任务完成更新状态
            TaskResult taskResult = taskResultMapper.queryByTaskid(taskNotice.getTaskid());
            if (taskResult == null){
                log.error("查询站点失败入库失败 无法查询任务结果 站码:{}", taskNotice.getId());
                return;
            }
            taskResult.setStatus(2);
            taskResultMapper.update(taskResult);
        } catch (Exception e) {
            log.error("小车任务完成 入库错误:", e);
        }
    }

    public void waterLevelUpload(String data){
        try {
            WaterLevel waterLevel = JSONUtil.toBean(data, WaterLevel.class);
            SiteInfo siteInfo = siteInfoMapper.queryBySiteCode(waterLevel.getId());
            if (siteInfo == null) {
                log.error("查询站点失败入库失败 站码:{}", waterLevel.getId());
                return;
            }
            waterLevel.setCreateTime(new Date());
            waterLevel.setWaterId(0L);
            waterLevel.setSiteId(siteInfo.getSiteId());
            waterLevelMapper.insert(waterLevel);
        } catch (Exception e) {
            log.error("小车任务完成 入库错误:", e);
        }
    }

    public void xiaoReturn(String data){
        try {
            TaskNotice taskNotice = JSONUtil.toBean(data, TaskNotice.class);
            SiteInfo siteInfo = siteInfoMapper.queryBySiteCode(taskNotice.getId());
            if (siteInfo == null) {
                log.error("查询站点失败入库失败 站码:{}", taskNotice.getId());
                return;
            }
            taskNotice.setStartId(0L);
            taskNotice.setRemark("小车开始返航");
            taskNotice.setCreateTime(new Date());
            taskNotice.setSiteId(siteInfo.getSiteId());
            taskNoticeMapper.insert(taskNotice);
        } catch (Exception e) {
            log.error("小车返航 入库错误:", e);
        }
    }

    public void resultUpload(String data){
        try {
            TaskResult taskResult = JSONUtil.toBean(data, TaskResult.class);
            SiteInfo siteInfo = siteInfoMapper.queryBySiteCode(taskResult.getId());
            if (siteInfo == null) {
                log.error("测流结果上报 查询站点失败 站码:{}", taskResult.getId());
                return;
            }
            TaskResult one = taskResultMapper.queryByTaskid(taskResult.getTaskid());
            if (one == null) {
                log.error("测流结果上报 数据更新失败 taskid {}", taskResult.getTaskid());
                return;
            }
            BerthingPoint berthingPoint = berthingPointMapper.queryBySiteId(siteInfo.getSiteId());
            if (berthingPoint == null) {
                log.error("测流结果上报 查询断面信息失败 站码:{}", taskResult.getId());
                return;
            }
            BerthingPointConfig berthingPointConfig = berthingPointConfigMapper.queryByPlanid(siteInfo.getSiteId(), taskResult.getPlanid());
            if (berthingPointConfig == null) {
                log.error("测流结果上报 查询停泊点信息失败 站码:{}", taskResult.getId());
                return;
            }
            taskResult.setStopId(berthingPointConfig.getStopId());
            taskResult.setBerthingId(berthingPoint.getBerthingId());
            taskResult.setResultId(one.getResultId());
            taskResult.setStatus(2);
            taskResultMapper.update(taskResult);
        } catch (Exception e) {
            log.error("测流结果上报 入库错误:", e);
        }
    }



}
