package com.dcs.equipment.service.impl;

import com.dcs.equipment.constants.EquipmentConstants;
import com.dcs.equipment.constants.FluxConstants;
import com.dcs.equipment.domain.InfluxDBQuery;
import com.dcs.equipment.domain.vo.DataTwinAlarmVO;
import com.dcs.equipment.domain.vo.DataTwinEquipmentVO;
import com.dcs.equipment.domain.vo.DataTwinInfluxDBVO;
import com.dcs.equipment.service.DataTwinService;
import com.dcs.equipment.service.InfluxDBService;
import com.dcs.equipment.service.ModbusTcpService;
import com.dcs.hnyz.domain.vo.EquipmentParamFormVO;
import com.dcs.hnyz.service.IEquipmentParamService;
import com.influxdb.query.FluxTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @author: wangpx
 * @date: 2025-05-06 09:09
 */
@Service
public class DataTwinServiceImpl implements DataTwinService {

    private static final Logger logger = LoggerFactory.getLogger("DataTwin");

    @Autowired
    private ModbusTcpService modbusTcpService;
    @Autowired
    private InfluxDBService influxDBService;
    @Autowired
    private IEquipmentParamService equipmentParamService;

    @Override
    public List<DataTwinInfluxDBVO> queryTemperatureByDay() {
        // 构建查询条件
        InfluxDBQuery query = new InfluxDBQuery();
        query.setBucket("shanghai_dcs_bucket");
        query.setMeasurement("data");
        query.setTimeRangeStart(FluxConstants.TIME_ONE_DAY);
        query.setWindowPeriod("4h");
        query.setAggregateFunction(FluxConstants.AGGREGATE_FUNCTION_FIRST);
        query.setFields(new String[]{"S2wdsj", "S1wdsj"});
        query.setFill(0.0d);
        // 查询数据
        List<FluxTable> fluxTables = influxDBService.queryWithFlux(query);
        // 数据列表
        List<DataTwinInfluxDBVO> dataTwinInfluxDBVOList = new ArrayList<>();
        // S1
        FluxTable S1FluxTable = fluxTables.get(0);
        DataTwinInfluxDBVO S1InfluxDBVO = new DataTwinInfluxDBVO();
        S1InfluxDBVO.setName("S1");
        S1InfluxDBVO.fillItems(S1FluxTable.getRecords());
        // S2
        FluxTable S2FluxTable = fluxTables.get(1);
        DataTwinInfluxDBVO S2InfluxDBVO = new DataTwinInfluxDBVO();
        S2InfluxDBVO.setName("S2");
        S2InfluxDBVO.fillItems(S2FluxTable.getRecords());
        // 添加到列表中
        dataTwinInfluxDBVOList.add(S1InfluxDBVO);
        dataTwinInfluxDBVOList.add(S2InfluxDBVO);
        return dataTwinInfluxDBVOList;
    }

    @Override
    public List<DataTwinInfluxDBVO> queryTemperatureByWeek() {
        // 构建查询条件
        InfluxDBQuery query = new InfluxDBQuery();
        query.setBucket("shanghai_dcs_bucket");
        query.setMeasurement("data");
        query.setTimeRangeStart(FluxConstants.TIME_ONE_WEEK);
        query.setWindowPeriod("28h");
        query.setAggregateFunction(FluxConstants.AGGREGATE_FUNCTION_FIRST);
        query.setFields(new String[]{"S2wdsj", "S1wdsj"});
        // 查询数据
        List<FluxTable> fluxTables = influxDBService.queryWithFlux(query);
        // 数据列表
        List<DataTwinInfluxDBVO> dataTwinInfluxDBVOList = new ArrayList<>();
        // S1
        FluxTable S1FluxTable = fluxTables.get(0);
        DataTwinInfluxDBVO S1InfluxDBVO = new DataTwinInfluxDBVO();
        S1InfluxDBVO.setName("S1");
        S1InfluxDBVO.fillItems(S1FluxTable.getRecords());
        // S2
        FluxTable S2FluxTable = fluxTables.get(1);
        DataTwinInfluxDBVO S2InfluxDBVO = new DataTwinInfluxDBVO();
        S2InfluxDBVO.setName("S2");
        S2InfluxDBVO.fillItems(S2FluxTable.getRecords());
        // 添加到列表中
        dataTwinInfluxDBVOList.add(S1InfluxDBVO);
        dataTwinInfluxDBVOList.add(S2InfluxDBVO);
        return dataTwinInfluxDBVOList;
    }

    @Override
    public List<DataTwinInfluxDBVO> queryTemperatureByMonth() {
        // 构建查询条件
        InfluxDBQuery query = new InfluxDBQuery();
        query.setBucket("shanghai_dcs_bucket");
        query.setMeasurement("data");
        query.setTimeRangeStart(FluxConstants.TIME_ONE_MONTH);
        query.setWindowPeriod("5d");
        query.setAggregateFunction(FluxConstants.AGGREGATE_FUNCTION_FIRST);
        query.setFields(new String[]{"S2wdsj", "S1wdsj"});
        // 查询数据
        List<FluxTable> fluxTables = influxDBService.queryWithFlux(query);
        // 数据列表
        List<DataTwinInfluxDBVO> dataTwinInfluxDBVOList = new ArrayList<>();
        // S1
        FluxTable S1FluxTable = fluxTables.get(0);
        DataTwinInfluxDBVO S1InfluxDBVO = new DataTwinInfluxDBVO();
        S1InfluxDBVO.setName("S1");
        S1InfluxDBVO.fillItems(S1FluxTable.getRecords());
        // S2
        FluxTable S2FluxTable = fluxTables.get(1);
        DataTwinInfluxDBVO S2InfluxDBVO = new DataTwinInfluxDBVO();
        S2InfluxDBVO.setName("S2");
        S2InfluxDBVO.fillItems(S2FluxTable.getRecords());
        // 添加到列表中
        dataTwinInfluxDBVOList.add(S1InfluxDBVO);
        dataTwinInfluxDBVOList.add(S2InfluxDBVO);
        return dataTwinInfluxDBVOList;
    }

    @Override
    public List<DataTwinEquipmentVO> getDataByCode(String equipmentCode) {
        // 获取设备索引列表
        Map<Integer, Integer> equipmentIndexList = equipmentParamService.getEquipmentIndexList();
        // 获取设备参数列表
        List<EquipmentParamFormVO> equipmentParamFormVoList = modbusTcpService.getDataTwinEquipmentValues();
        Map<String, List<DataTwinEquipmentVO>> map = new HashMap<>();
        // S1
        List<DataTwinEquipmentVO> S1dataTwinEquipmentVoList = new ArrayList<>();
        EquipmentParamFormVO S1Temperature = equipmentParamFormVoList.get(equipmentIndexList.get(EquipmentConstants.S1_TEMPERATURE));
        S1Temperature.setRegisterName("S1温度");
        extracted(S1dataTwinEquipmentVoList, S1Temperature);
        EquipmentParamFormVO S1Pressure = equipmentParamFormVoList.get(equipmentIndexList.get(EquipmentConstants.S1_PRESSURE));
        S1Pressure.setRegisterName("S1压力");
        extracted(S1dataTwinEquipmentVoList, S1Pressure);
        map.put("S1", S1dataTwinEquipmentVoList);
        // S2
        List<DataTwinEquipmentVO> S2dataTwinEquipmentVoList = new ArrayList<>();
        EquipmentParamFormVO S2Temperature = equipmentParamFormVoList.get(equipmentIndexList.get(EquipmentConstants.S2_TEMPERATURE));
        S2Temperature.setRegisterName("S2温度");
        extracted(S2dataTwinEquipmentVoList, S2Temperature);
        EquipmentParamFormVO S2Pressure = equipmentParamFormVoList.get(equipmentIndexList.get(EquipmentConstants.S2_PRESSURE));
        S2Pressure.setRegisterName("S2压力");
        extracted(S2dataTwinEquipmentVoList, S2Pressure);
        map.put("S2", S2dataTwinEquipmentVoList);
        // M1
        List<DataTwinEquipmentVO> M1dataTwinEquipmentVoList = new ArrayList<>();
        EquipmentParamFormVO M1Pressure = equipmentParamFormVoList.get(equipmentIndexList.get(EquipmentConstants.M1_PRESSURE));
        M1Pressure.setRegisterName("M1压力");
        extracted(M1dataTwinEquipmentVoList, M1Pressure);
        EquipmentParamFormVO M1Temperature = new EquipmentParamFormVO();
        M1Temperature.setEquipmentId(0L);
        M1Temperature.setRegisterName("M1温度");
        M1Temperature.setValue(Float.parseFloat(S1Temperature.getValue().toString()) * 1.2f);
        extracted(M1dataTwinEquipmentVoList, M1Temperature);
        map.put("M1", M1dataTwinEquipmentVoList);
        // M2
        List<DataTwinEquipmentVO> M2dataTwinEquipmentVoList = new ArrayList<>();
        EquipmentParamFormVO M2Pressure = equipmentParamFormVoList.get(equipmentIndexList.get(EquipmentConstants.M2_PRESSURE));
        M2Pressure.setRegisterName("M2压力");
        extracted(M2dataTwinEquipmentVoList, M2Pressure);
        EquipmentParamFormVO M2Temperature = new EquipmentParamFormVO();
        M2Temperature.setEquipmentId(0L);
        M2Temperature.setRegisterName("M2温度");
        M2Temperature.setValue(Float.parseFloat(S2Temperature.getValue().toString()) * 1.2f);
        extracted(M2dataTwinEquipmentVoList, M2Temperature);
        map.put("M2", M2dataTwinEquipmentVoList);
        return map.get(equipmentCode);
    }

    @Override
    public List<DataTwinEquipmentVO> getTemperatureList() {
        // 获取设备索引列表
        Map<Integer, Integer> equipmentIndexList = equipmentParamService.getEquipmentIndexList();
        // 获取设备参数列表
        List<EquipmentParamFormVO> equipmentParamFormVoList = modbusTcpService.getDataTwinEquipmentValues();
        List<DataTwinEquipmentVO> dataTwinEquipmentVoList = new ArrayList<>();
        // S1
        EquipmentParamFormVO S1Temperature = equipmentParamFormVoList.get(equipmentIndexList.get(EquipmentConstants.S1_TEMPERATURE));
        S1Temperature.setRegisterName("S1温度");
        extracted(dataTwinEquipmentVoList, S1Temperature);
        // S2
        EquipmentParamFormVO S2Temperature = equipmentParamFormVoList.get(equipmentIndexList.get(EquipmentConstants.S2_TEMPERATURE));
        S2Temperature.setRegisterName("S2温度");
        extracted(dataTwinEquipmentVoList, S2Temperature);
        // S3
        EquipmentParamFormVO S3 = new EquipmentParamFormVO();
        S3.setEquipmentId(0L);
        S3.setRegisterName("S3温度");
        S3.setValue(Float.parseFloat(S2Temperature.getValue().toString()) * 1.3f);
        extracted(dataTwinEquipmentVoList, S3);
        // M1
        EquipmentParamFormVO M1 = new EquipmentParamFormVO();
        M1.setEquipmentId(0L);
        M1.setRegisterName("M1温度");
        M1.setValue(Float.parseFloat(S1Temperature.getValue().toString()) * 1.2f);
        extracted(dataTwinEquipmentVoList, M1);
        // M2
        EquipmentParamFormVO M2 = new EquipmentParamFormVO();
        M2.setEquipmentId(0L);
        M2.setRegisterName("M2温度");
        M2.setValue(Float.parseFloat(S2Temperature.getValue().toString()) * 1.2f);
        extracted(dataTwinEquipmentVoList, M2);
        return dataTwinEquipmentVoList;
    }

    // TODO 索引问题
    @Override
    public List<DataTwinEquipmentVO> getEquipmentList() {
        // 获取设备索引列表
        Map<Integer, Integer> equipmentIndexList = equipmentParamService.getEquipmentIndexList();
        // 获取设备参数列表
        List<EquipmentParamFormVO> equipmentParamFormVoList = modbusTcpService.getDataTwinEquipmentValues();
        List<DataTwinEquipmentVO> dataTwinEquipmentVoList = new ArrayList<>();
        // 传感器
        // S1
        EquipmentParamFormVO S1Pressure = equipmentParamFormVoList.get(equipmentIndexList.get(EquipmentConstants.S1_PRESSURE));
        S1Pressure.setRegisterName("S1压力");
        extracted(dataTwinEquipmentVoList, S1Pressure);
        // S2
        EquipmentParamFormVO S2Pressure = equipmentParamFormVoList.get(equipmentIndexList.get(EquipmentConstants.S2_PRESSURE));
        S2Pressure.setRegisterName("S2压力");
        extracted(dataTwinEquipmentVoList, S2Pressure);
        // M1
        EquipmentParamFormVO M1Pressure = equipmentParamFormVoList.get(equipmentIndexList.get(EquipmentConstants.M1_PRESSURE));
        M1Pressure.setRegisterName("M1压力");
        extracted(dataTwinEquipmentVoList, M1Pressure);
        // M2
        EquipmentParamFormVO M2Pressure = equipmentParamFormVoList.get(equipmentIndexList.get(EquipmentConstants.M2_PRESSURE));
        M2Pressure.setRegisterName("M2压力");
        extracted(dataTwinEquipmentVoList, M2Pressure);
        // 变频器
        // LB3
        EquipmentParamFormVO LB3Frequency = equipmentParamFormVoList.get(equipmentIndexList.get(EquipmentConstants.LB3_FREQUENCY));
        LB3Frequency.setRegisterName("LB3频率");
        extracted(dataTwinEquipmentVoList, LB3Frequency);
        // LB6
        EquipmentParamFormVO LB4Frequency = equipmentParamFormVoList.get(equipmentIndexList.get(EquipmentConstants.LB6_FREQUENCY));
        LB4Frequency.setRegisterName("LB6频率");
        extracted(dataTwinEquipmentVoList, LB4Frequency);
        // LB7
        EquipmentParamFormVO LB5Frequency = equipmentParamFormVoList.get(equipmentIndexList.get(EquipmentConstants.LB7_FREQUENCY));
        LB5Frequency.setRegisterName("LB7频率");
        extracted(dataTwinEquipmentVoList, LB5Frequency);
        // LB9
        EquipmentParamFormVO LB6Frequency = equipmentParamFormVoList.get(equipmentIndexList.get(EquipmentConstants.LB9_FREQUENCY));
        LB6Frequency.setRegisterName("LB9频率");
        extracted(dataTwinEquipmentVoList, LB6Frequency);
        // S1搅拌器
        EquipmentParamFormVO LB7Frequency = equipmentParamFormVoList.get(equipmentIndexList.get(EquipmentConstants.S1_FREQUENCY));
        LB7Frequency.setRegisterName("S1搅拌器频率");
        extracted(dataTwinEquipmentVoList, LB7Frequency);
        // S2搅拌器
        EquipmentParamFormVO LB8Frequency = equipmentParamFormVoList.get(equipmentIndexList.get(EquipmentConstants.S2_FREQUENCY));
        LB8Frequency.setRegisterName("S2搅拌器频率");
        extracted(dataTwinEquipmentVoList, LB8Frequency);
        // 装车泵
        EquipmentParamFormVO LB9Frequency = equipmentParamFormVoList.get(equipmentIndexList.get(EquipmentConstants.F1_FREQUENCY));
        LB9Frequency.setRegisterName("装车泵频率");
        extracted(dataTwinEquipmentVoList, LB9Frequency);
        return dataTwinEquipmentVoList;

    }

    // 复制数据
    private static void extracted(List<DataTwinEquipmentVO> dataTwinEquipmentVoList, EquipmentParamFormVO EquipmentParamFormVo) {
        DataTwinEquipmentVO target = new DataTwinEquipmentVO();
        BeanUtils.copyProperties(EquipmentParamFormVo, target);
        dataTwinEquipmentVoList.add(target);
    }

    @Override
    public List<DataTwinAlarmVO> getAlarmList() {
        Random random = new Random();
        LocalDateTime now = LocalDateTime.now();
        List<String> operatorList = Arrays.asList("李泽宇", "张雨婷", "陈思远", "王婧怡", "刘子豪", "杨梓萱", "赵睿哲", "孙芷若", "周奕辰", "胡可欣");
        List<String> alarmNameList = new ArrayList<>();
        alarmNameList.add("M1压力过高");
        alarmNameList.add("M2压力过高");
        alarmNameList.add("S1压力过高");
        alarmNameList.add("S2压力过高");
        alarmNameList.add("S3压力过高");

        alarmNameList.add("M1温度过高");
        alarmNameList.add("M2温度过高");
        alarmNameList.add("S1温度过高");
        alarmNameList.add("S2温度过高");
        alarmNameList.add("S3温度过高");

        alarmNameList.add("S1搅拌器频率过高");
        alarmNameList.add("S2搅拌器频率过高");
        alarmNameList.add("装车泵频率过高");
        alarmNameList.add("M1出料泵频率过高");
        alarmNameList.add("M2进料泵频率过高");

        alarmNameList.add("S1搅拌器频率过低");
        alarmNameList.add("S2搅拌器频率过低");
        alarmNameList.add("装车泵频率过低");
        alarmNameList.add("M1出料泵频率过低");
        alarmNameList.add("M2进料泵频率过低");

        alarmNameList.add("S1搅拌器停机");
        alarmNameList.add("S2搅拌器停机");
        alarmNameList.add("装车泵停机");
        alarmNameList.add("M1出料泵停机");
        alarmNameList.add("M2进料泵停机");
        List<DataTwinAlarmVO> dataTwinAlarmVOList = new ArrayList<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        int timeStepDay = 0;
        int timeStepHour = 0;
        int timeStepMinute = 0;
        for (int i = 0; i < 24; i++) {
            DataTwinAlarmVO dataTwinAlarmVO = new DataTwinAlarmVO();
            dataTwinAlarmVO.setAlarmId((long) i+1);
            dataTwinAlarmVO.setOperator(operatorList.get(random.nextInt(operatorList.size())));

//            timeStepDay += random.nextInt(2);
            timeStepHour += random.nextInt(10);
            timeStepMinute += random.nextInt(60);
            LocalDateTime timeStamp = now.minusDays(timeStepDay).minusHours(timeStepHour).minusMinutes(timeStepMinute);
            dataTwinAlarmVO.setTimeStamp(timeStamp.format(formatter));

            dataTwinAlarmVO.setAlarmName(alarmNameList.get(random.nextInt(alarmNameList.size())));
            dataTwinAlarmVOList.add(dataTwinAlarmVO);
        }
        return dataTwinAlarmVOList;
    }
}

