package com.usky.backend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.usky.backend.domain.*;
import com.usky.backend.domain.request.HistoryQueryVo;
import com.usky.backend.domain.request.LastQueryVo;
import com.usky.backend.domain.response.HistoryResultVo;
import com.usky.backend.domain.response.LastResultVo;
import com.usky.backend.mapper.DataRealTimeMapper;
import com.usky.backend.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class DataQueryServiceImpl implements DataQueryService {
    @Autowired
    private DataRealTimeService dataRealTimeService;

    @Autowired
    private DataRealTimeMapper dataRealTimeMapper;

    @Override
    public HistoryResultVo historyMetric(String deviceId, String metric, String startTime, String endTime,String typeAbbrevia){

        List<MetricItemVo> items = new ArrayList<>();
        String tableName = "data_"+typeAbbrevia+"_history";

        items = dataRealTimeMapper.QueryHistoryData(deviceId, metric, startTime, endTime,tableName);

        HistoryResultVo historyResultVo = new HistoryResultVo(deviceId,metric,items);

        return historyResultVo;
    }

    @Override
    public List<HistoryResultVo> historyMetrics(HistoryQueryVo historyQueryVo){
        List<HistoryResultVo> result = new ArrayList<>();
        String deviceId = historyQueryVo.getDeviceId();
        String startTime = historyQueryVo.getStartTime();
        String endTime = historyQueryVo.getEndTime();
        String typeAbbrevia = historyQueryVo.getTypeAbbrevia();
        List<String> metrics = historyQueryVo.getMetrics();
        if(CollectionUtils.isNotEmpty(metrics)){
            for(int i=0;i<metrics.size();i++){
                List<MetricItemVo> items = new ArrayList<>();
                String tableName = "data_"+typeAbbrevia+"_history";

                items = dataRealTimeMapper.QueryHistoryData(deviceId, metrics.get(i), startTime, endTime,tableName);

                HistoryResultVo historyResultVo = new HistoryResultVo(deviceId,metrics.get(i),items);
                result.add(historyResultVo);
            }
        }

        return result;
    }

    @Override
    public List<LastResultVo> last(LastQueryVo lastQueryVo){
        List<LastResultVo> list = new ArrayList<>();

        List<String> items = lastQueryVo.getMetrics();
        for(int i=0;i<items.size();i++){
            LambdaQueryWrapper<DataRealTime> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.select(DataRealTime::getAttributeData,DataRealTime::getDataTime)
                    .eq(DataRealTime::getDeviceId,lastQueryVo.getDeviceId())
                    .eq(DataRealTime::getAttributeName,items.get(i));
            DataRealTime one = dataRealTimeService.getOne(queryWrapper);
            if(one != null){
                LastResultVo lastResultVo = new LastResultVo(items.get(i),one.getDataTime(),one.getAttributeData());
                list.add(lastResultVo);
            }
        }

        return list;
    }

    @Override
    public List<StatusVO> status(){
        List<StatusVO> list = new ArrayList<>();
        QueryWrapper<DataRealTime> query = Wrappers.query();
        query.select("product_code as productCode","device_id as deviceId","Max(data_time) as maxTime")
                .groupBy("device_id","product_code");
        List<Map<String,Object>> maps = dataRealTimeService.listMaps(query);
        if(maps.size()>0) {
            for (int i = 0; i < maps.size(); i++) {
                StatusVO statusVO = new StatusVO();
                statusVO.setDeviceId(maps.get(i).get("deviceId").toString());
                statusVO.setTime(LocalDateTime.parse(maps.get(i).get("maxTime").toString(),DateTimeFormatter.ISO_DATE_TIME));
                statusVO.setProductCode(maps.get(i).get("productCode").toString());
                list.add(statusVO);
            }
        }

        return list;
    }

    @Override
    public List<Map<String,Object>> deviceDataTotal(DataTotalRequestVO requestVO){
        List<Map<String,Object>> list = new ArrayList<>();
        //设备类型简称
        String typeAbbrevia = dataRealTimeMapper.QueryDeviceTypeAbbrevia(requestVO.getDeviceType());
        String tableName = "data_"+typeAbbrevia+"_history";

        List<DataHistoryTotalVO> list1 = new ArrayList<>();
        if(requestVO.getGroupType().equals("Each")){
            list1 = dataRealTimeMapper.QueryEachHistoryTotalData(tableName,requestVO.getStartTime(),requestVO.getEndTime(),requestVO.getProductCode(),requestVO.getDeviceIds(),requestVO.getAttributeNames());
        }else if(requestVO.getGroupType().equals("Total")){
            list1 = dataRealTimeMapper.QueryTotalHistoryTotalData(tableName,requestVO.getStartTime(),requestVO.getEndTime(),requestVO.getProductCode(),requestVO.getAttributeNames());
        }
        if(CollectionUtils.isNotEmpty(list1)){
            List<String> deviceIdList = new ArrayList<>();
            for(int i=0;i<list1.size();i++){
                if(!deviceIdList.contains(list1.get(i).getDeviceId())){
                    deviceIdList.add(list1.get(i).getDeviceId());
                }
            }
            if(CollectionUtils.isNotEmpty(deviceIdList)){
                for(int j=0;j<deviceIdList.size();j++){
                    Map<String,Object> map = new HashMap<>();

                    map.put("deviceId",deviceIdList.get(j));

                    for(int k=0;k<list1.size();k++){
                        if(deviceIdList.get(j).equals(list1.get(k).getDeviceId())){
                            map.put(list1.get(k).getAttributeName(),list1.get(k).getTotalValue());
                        }
                    }
                    list.add(map);
                }
            }
        }

        return list;
    }

    @Override
    public List<DataAverageResponseVO> deviceDataAverage(DataAverageRequestVO requestVO){
        List<DataAverageResponseVO> list = new ArrayList<>();

        //设备类型简称
        String typeAbbrevia = dataRealTimeMapper.QueryDeviceTypeAbbrevia(requestVO.getDeviceType());
        String tableName = "data_"+typeAbbrevia+"_history";

        int leftLen = 0;
        if(requestVO.getDataType().equals("Day")){
            leftLen = 10;
        }else if(requestVO.getDataType().equals("Month")){
            leftLen = 7;
        }else if(requestVO.getDataType().equals("Year")){
            leftLen = 4;
        }

        List<DataHistoryAvergerVO> list1 = new ArrayList<>();
        if(requestVO.getGroupType().equals("Each")){
            list1 = dataRealTimeMapper.QueryEachHistoryAvrgData(leftLen,tableName,requestVO.getStartTime(),requestVO.getEndTime(),requestVO.getProductCode(),requestVO.getDeviceIds(),requestVO.getAttributeNames());
        }else if(requestVO.getGroupType().equals("Total")){
            if(CollectionUtils.isNotEmpty(requestVO.getDeviceIds())){
                list1 = dataRealTimeMapper.QueryTotalOptHistoryAvrgData(leftLen,tableName,requestVO.getStartTime(),requestVO.getEndTime(),requestVO.getProductCode(),requestVO.getDeviceIds(),requestVO.getAttributeNames());
            }else{
                list1 = dataRealTimeMapper.QueryTotalHistoryAvrgData(leftLen,tableName,requestVO.getStartTime(),requestVO.getEndTime(),requestVO.getProductCode(),requestVO.getAttributeNames());
            }

        }
        if(CollectionUtils.isNotEmpty(list1)){
            List<String> dateList = new ArrayList<>();
            List<String> deviceIdList = new ArrayList<>();
            for(int i=0;i<list1.size();i++){
                if(!dateList.contains(list1.get(i).getDataDate())){
                    dateList.add(list1.get(i).getDataDate());
                }
                if(!deviceIdList.contains(list1.get(i).getDeviceId())){
                    deviceIdList.add(list1.get(i).getDeviceId());
                }
            }
            if(CollectionUtils.isNotEmpty(dateList) && CollectionUtils.isNotEmpty(deviceIdList)){
                for(int i=0;i<dateList.size();i++){
                    for(int j=0;j<deviceIdList.size();j++){
                        DataAverageResponseVO responseVO = new DataAverageResponseVO();
                        responseVO.setDataDate(dateList.get(i));
                        responseVO.setDeviceId(deviceIdList.get(j));
                        for(int k=0;k<list1.size();k++){
                            if(dateList.get(i).equals(list1.get(k).getDataDate()) && deviceIdList.get(j).equals(list1.get(k).getDeviceId())){
                                if(list1.get(k).getAttributeName().equals("wd")){
                                    responseVO.setWd(String.format("%.1f",list1.get(k).getAvrg()));
                                }
                                if(list1.get(k).getAttributeName().equals("sd")){
                                    responseVO.setSd(String.format("%.1f",list1.get(k).getAvrg()));
                                }
                                if(list1.get(k).getAttributeName().equals("pm2_5")){
                                    responseVO.setPm2_5(String.format("%.1f",list1.get(k).getAvrg()));
                                }
                                if(list1.get(k).getAttributeName().equals("co2")){
                                    responseVO.setCo2(String.format("%.1f",list1.get(k).getAvrg()));
                                }
                                if(list1.get(k).getAttributeName().equals("voc")){ //voc平均值（优就是1，良是2，差是3）
                                    String name = "";
                                    double value = list1.get(k).getAvrg();
                                    if(value>=0 && value<=1.5){
                                        name = "优";
                                    }else if(value>1.5 && value<=2.5){
                                        name = "良";
                                    }else if(value>2.5){
                                        name = "差";
                                    }
                                    responseVO.setVoc(name);
                                }
                                if(list1.get(k).getAttributeName().equals("quality")){ //空气质量平均值（1、优质 2、良好 3、轻度污染 4、中度污染 5、重度污染 6、严重污染）
                                    String name = "";
                                    double value = list1.get(k).getAvrg();
                                    if(value>=0 && value<=1.5){
                                        name = "优质";
                                    }else if(value>1.5 && value<=2.5){
                                        name = "良好";
                                    }else if(value>2.5 && value<=3.5){
                                        name = "轻度污染";
                                    }else if(value>3.5 && value<=4.5){
                                        name = "中度污染";
                                    }else if(value>4.5 && value<=5.5){
                                        name = "重度污染";
                                    }else if(value>5.5){
                                        name = "严重污染";
                                    }
                                    responseVO.setQuality(name);
                                }
                            }
                        }
                        list.add(responseVO);
                    }
                }
            }
        }

        return list;
    }

    @Override
    public List<DataAverageExportVO> DataAverageExport(DataAverageRequestVO requestVO){
        List<DataAverageExportVO> list = new ArrayList<>();
        //设备类型简称
        String typeAbbrevia = dataRealTimeMapper.QueryDeviceTypeAbbrevia(requestVO.getDeviceType());
        String tableName = "data_"+typeAbbrevia+"_history";

        int leftLen = 0;
        if(requestVO.getDataType().equals("Day")){
            leftLen = 10;
        }else if(requestVO.getDataType().equals("Month")){
            leftLen = 7;
        }else if(requestVO.getDataType().equals("Year")){
            leftLen = 4;
        }

        List<DataHistoryAvergerVO> list1 = new ArrayList<>();
        List<String> outDeviceList = new ArrayList<>();
        outDeviceList.add("weather0001");
        List<DataHistoryAvergerVO> list2 = dataRealTimeMapper.QueryEachHistoryAvrgData(leftLen,tableName,requestVO.getStartTime(),requestVO.getEndTime(),null,outDeviceList,requestVO.getAttributeNames());
        if(requestVO.getGroupType().equals("Each")){
            list1 = dataRealTimeMapper.QueryEachHistoryAvrgData(leftLen,tableName,requestVO.getStartTime(),requestVO.getEndTime(),requestVO.getProductCode(),requestVO.getDeviceIds(),requestVO.getAttributeNames());
        }else if(requestVO.getGroupType().equals("Total")){
            if(CollectionUtils.isNotEmpty(requestVO.getDeviceIds())){
                list1 = dataRealTimeMapper.QueryTotalOptHistoryAvrgData(leftLen,tableName,requestVO.getStartTime(),requestVO.getEndTime(),requestVO.getProductCode(),requestVO.getDeviceIds(),requestVO.getAttributeNames());
            }else{
                list1 = dataRealTimeMapper.QueryTotalHistoryAvrgData(leftLen,tableName,requestVO.getStartTime(),requestVO.getEndTime(),requestVO.getProductCode(),requestVO.getAttributeNames());
            }
        }
        if(CollectionUtils.isNotEmpty(list1)){
            List<String> dateList = new ArrayList<>();
            List<String> deviceIdList = new ArrayList<>();
            for(int i=0;i<list1.size();i++){
                if(!dateList.contains(list1.get(i).getDataDate())){
                    dateList.add(list1.get(i).getDataDate());
                }
                if(!deviceIdList.contains(list1.get(i).getDeviceId())){
                    deviceIdList.add(list1.get(i).getDeviceId());
                }
            }
            if(CollectionUtils.isNotEmpty(dateList) && CollectionUtils.isNotEmpty(deviceIdList)){
                for(int i=0;i<dateList.size();i++){
                    for(int j=0;j<deviceIdList.size();j++){
                        DataAverageExportVO responseVO = new DataAverageExportVO();
                        responseVO.setDataDate(dateList.get(i));
                        responseVO.setDeviceName(deviceIdList.get(j));
                        for(int k=0;k<list1.size();k++){
                            if(dateList.get(i).equals(list1.get(k).getDataDate()) && deviceIdList.get(j).equals(list1.get(k).getDeviceId())){
                                if(list1.get(k).getAttributeName().equals("wd")){
                                    responseVO.setWdIn(String.format("%.1f",list1.get(k).getAvrg()));
                                }
                                if(list1.get(k).getAttributeName().equals("sd")){
                                    responseVO.setSdIn(String.format("%.1f",list1.get(k).getAvrg()));
                                }
                                if(list1.get(k).getAttributeName().equals("pm2_5")){
                                    responseVO.setPm2_5In(String.format("%.1f",list1.get(k).getAvrg()));
                                }
                                if(list1.get(k).getAttributeName().equals("co2")){
                                    responseVO.setCo2(String.format("%.1f",list1.get(k).getAvrg()));
                                }
                                if(list1.get(k).getAttributeName().equals("voc")){ //voc平均值（优就是1，良是2，差是3）
                                    String name = "";
                                    double value = list1.get(k).getAvrg();
                                    if(value>=1 && value<=1.5){
                                        name = "优";
                                    }else if(value>1.5 && value<=2.5){
                                        name = "良";
                                    }else if(value>2.5 && value<=3){
                                        name = "差";
                                    }
                                    responseVO.setVoc(name);
                                }
                            }
                        }

                        for(int h=0;h<list2.size();h++){
                            if(dateList.get(i).equals(list2.get(h).getDataDate())){
                                if(list2.get(h).getAttributeName().equals("wd")){
                                    responseVO.setWdOut(String.format("%.1f",list2.get(h).getAvrg()));
                                }
                                if(list2.get(h).getAttributeName().equals("sd")){
                                    responseVO.setSdOut(String.format("%.1f",list2.get(h).getAvrg()));
                                }
                                if(list2.get(h).getAttributeName().equals("pm2_5")){
                                    responseVO.setPm2_5Out(String.format("%.1f",list2.get(h).getAvrg()));
                                }
                                if(list2.get(h).getAttributeName().equals("quality")){ //空气质量平均值（1、优质 2、良好 3、轻度污染 4、中度污染 5、重度污染 6、严重污染）
                                    String name = "";
                                    double value = list2.get(h).getAvrg();
                                    if(value>=1 && value<=1.5){
                                        name = "优质";
                                    }else if(value>1.5 && value<=2.5){
                                        name = "良好";
                                    }else if(value>2.5 && value<=3.5){
                                        name = "轻度污染";
                                    }else if(value>3.5 && value<=4.5){
                                        name = "中度污染";
                                    }else if(value>4.5 && value<=5.5){
                                        name = "重度污染";
                                    }else if(value>5.5 && value<=6){
                                        name = "严重污染";
                                    }
                                    responseVO.setQuality(name);
                                }
                            }
                        }

                        list.add(responseVO);
                    }
                }
            }
        }

        return list;
    }

}
