package com.gyee.dataadapter.controller;

import com.alibaba.druid.sql.visitor.functions.If;
import com.gyee.dataadapter.cache.MqttCache;
import com.gyee.dataadapter.entity.DoubleStatData;
import com.gyee.dataadapter.entity.PointData;
import com.gyee.dataadapter.entity.PointInfo;
import com.gyee.dataadapter.entity.TotalPointData;
import com.gyee.dataadapter.service.IAdapterService;
import com.gyee.dataadapter.service.TsDataService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/ts")
public class AdapterController {
    @Resource
    private IAdapterService dataClient;
    @Resource
    private TsDataService tsDataService;

    @GetMapping(value = "/history/list")
    public TotalPointData history(@RequestParam(value = "start") String start,
                                  @RequestParam(value = "end") String end,
                                  @RequestParam(value = "sampleType", required = false) int sampleType,
                                  @RequestParam(value = "sampleRate", required = false) int sampleRate,
                                  @RequestParam(value = "paths") String paths,
                                  @RequestParam(value = "pageIndex", required = false) String pageIndex,
                                  @RequestParam(value = "pageSize", required = false) String pageSize,
                                  @RequestParam(value = "isDesc", required = false, defaultValue = "false") boolean isDesc) {
        return dataClient.getTotalData(start, end, sampleType, sampleRate, paths, pageIndex, pageSize, isDesc);
    }

    @GetMapping(value = "/mqttMap")
    public Map<String, PointData> mqttMap() {
        return MqttCache.subData2;
    }

    @GetMapping(value = "/latest/list")
    public Map<String, PointInfo> latest(@RequestParam(value = "paths") String paths) {
        return dataClient.getLatestData(paths);
    }

    @GetMapping("/latest")
    public Map<String, PointData> getLatest(@RequestParam("keys") String keys) {
        return tsDataService.getLatest(keys);
    }

    @PostMapping("/latests")
    public Map<String, PointData> getLatestp(@RequestBody String keys) {
        return tsDataService.getLatest(keys);
    }

    @PostMapping("/latest")
    public Map<String, PointData> getLatestp(@RequestBody List<String> keys) {
        return tsDataService.getLatest(keys);
    }

    @GetMapping("/history/raw")
    public List<PointData> getHistoryRaw(@RequestParam("tagName") String tagName,
                                         @RequestParam("startTs") Long startTs, @RequestParam("endTs") Long endTs) {
        return tsDataService.getHistoryRaw(tagName, startTs, endTs);
    }

    @GetMapping("/history/snap")
    public List<PointData> getHistorySnap(@RequestParam("tagName") String tagName, @RequestParam("startTs") Long startTs,
                                          @RequestParam("endTs") Long endTs,
                                          @RequestParam(value = "interval", required = false) Integer interval) {

        return tsDataService.getHistorySnap(tagName, startTs, endTs, interval);
    }

    @GetMapping("/history/statso")
    public PointData getHistoryStat5(@RequestParam("tagName") String tagName,
                                           @RequestParam("startTs") Long startTs, @RequestParam("endTs") Long endTs,
                                           @RequestParam(value = "type", required = false) Integer type) {
        List<PointData> stat = tsDataService.getHistoryStat2(tagName, new Date(startTs), new Date(endTs), type);
        return stat.get(0);
    }

    @GetMapping("/history/stats")
    public List<PointData> getHistoryStat4(@RequestParam("tagName") String tagName,
                                           @RequestParam("startTs") Long startTs, @RequestParam("endTs") Long endTs,
                                           @RequestParam(value = "interval", required = false) Integer interval,
                                           @RequestParam(value = "type", required = false) Integer type) {
        return tsDataService.getHistoryStat(tagName, new Date(startTs), new Date(endTs), interval, type);
    }

    @GetMapping("/history/stat3")
    public List<PointData> getHistoryStat3(@RequestParam("tagName") String tagName,
                                          @RequestParam("startTs") Long startTs,
                                           @RequestParam("endTs") Long endTs,
                                          @RequestParam(value = "interval", required = false) Integer interval,
                                          @RequestParam(value = "type", required = false) Integer type) {
        return tsDataService.getHistoryStat(tagName, new Date(startTs), new Date(endTs), interval, type);
    }

    @GetMapping("/history/stat")
    public List<DoubleStatData> getHistoryStat2(@RequestParam("tagName") String tagName,
                                                @RequestParam("startTs") Long startTs,
                                                @RequestParam("endTs") Long endTs,
                                                @RequestParam(value = "interval", required = false) Integer interval) {
        List<DoubleStatData> result = new ArrayList<>();
        List<PointData> max = tsDataService.getHistoryStat(tagName, new Date(startTs), new Date(endTs), interval, 2);
        List<PointData> min = tsDataService.getHistoryStat(tagName, new Date(startTs), new Date(endTs), interval, 3);
        List<PointData> avg = tsDataService.getHistoryStat(tagName, new Date(startTs), new Date(endTs), interval, 4);
        if (max.size() == min.size() && min.size() == avg.size()) {
            for (int i = 0; i < max.size(); i++) {
                result.add(new DoubleStatData(max.get(i), min.get(i), avg.get(i)));
            }
        }
        return result;
    }


    @GetMapping("/history/stat2")
    public DoubleStatData getHistoryStat(@RequestParam("tagName") String tagName,
                                                @RequestParam("startTs") Long startTs,
                                                @RequestParam("endTs") Long endTs) {
        List<DoubleStatData> result = new ArrayList<>();
        List<PointData> max = tsDataService.getHistoryStat2(tagName, new Date(startTs), new Date(endTs),2);
        List<PointData> min = tsDataService.getHistoryStat2(tagName, new Date(startTs), new Date(endTs),  3);
        List<PointData> avg = tsDataService.getHistoryStat2(tagName, new Date(startTs), new Date(endTs),4);
        if (max.size() == min.size() && min.size() == avg.size()) {
            for (int i = 0; i < max.size(); i++) {
                result.add(new DoubleStatData(max.get(i), min.get(i), avg.get(i)));
            }
        }
        return result.get(0);
    }


    @GetMapping("/history/section")
    public Map<String, PointData> getHistorySection(@RequestParam("tagNames") String tagNames, @RequestParam("ts") Long ts) {
        return tsDataService.getHistorySection(ts, tagNames);
    }
    @PostMapping("/history/section")
    public Map<String, PointData> getHistorySectionp(@RequestBody String tagNames, @RequestParam("ts") Long ts) {
        return tsDataService.getHistorySection(ts, tagNames);
    }

    @PostMapping("/save/batch")
    public boolean writeLatestBatch(@RequestBody List<PointData> pointDataList) {
        pointDataList = pointDataList.stream().filter(pd -> !"INITIAL".equals(pd.getTagName())).collect(Collectors.toList());
        return tsDataService.writeLatest(pointDataList);
    }

    @PostMapping("/save")
    public boolean writeLatest(@RequestBody PointData PointData) {
        return writeLatestBatch(Collections.singletonList(PointData));
    }

}
