package com.gyee.wisdom.dataadapter.websocket;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gyee.wisdom.common.data.photovoltaic.InverterBasicData;
import com.gyee.wisdom.common.data.timeseries.*;
import com.gyee.wisdom.dataadapter.domain.timeseries.TsDataService;
import com.gyee.wisdom.dataadapter.domain.timeseries.TsPointService;
import com.gyee.wisdom.dataadapter.help.Constant;
import com.gyee.wisdom.dataadapter.websocket.domain.WindturbineData;
import com.gyee.wisdom.dataadapter.websocket.session.StompSessionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.annotation.SubscribeMapping;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.*;


@Controller
public class WebSocketTsDataController {

    @Autowired
    protected TsDataService tsDataService;

    @Autowired
    protected TsPointService tsPointService;

    @Autowired
    private StompSessionService stompSessionService;

    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;

    @SubscribeMapping("/subscribe")
    public boolean subscribeTopic(SimpMessageHeaderAccessor headerAccessor) {
        List<String> topic = headerAccessor.getNativeHeader("topic");
        String sessionId = headerAccessor.getSessionId();
        stompSessionService.subscribeTopic(sessionId, topic.get(0));
        return true;
    }

    @SubscribeMapping("/unsubscribe")
    public boolean unSubscribeTopic(SimpMessageHeaderAccessor headerAccessor) {
        List<String> topic = headerAccessor.getNativeHeader("topic");
        String sessionId = headerAccessor.getSessionId();
        stompSessionService.unSubscribeTopic(sessionId, topic.get(0));
        return true;
    }

    @SubscribeMapping("/test")
    public List<GeneralTsData> listTest(SimpMessageHeaderAccessor headerAccessor) {
        List<String> jsonList = headerAccessor.getNativeHeader("json");
        //json转集合
        JSONArray jsonArray = JSON.parseArray(jsonList.get(0));
        List<TsPointData> list = JSONObject.parseArray(jsonArray.toJSONString(), TsPointData.class);

        //json转对象
        JSONObject obj = JSONObject.parseObject("{'ts':1529658448797,'status':1}");
        GeneralTsData tsData = JSONObject.toJavaObject(obj, GeneralTsData.class);

        List<GeneralTsData> list1 = new ArrayList<>();
        GeneralTsData data1 = new GeneralTsData();
        GeneralTsData data2 = new GeneralTsData();

        data1.setTs(new Date().getTime());
        data2.setTs(new Date().getTime());

        data1.setStatus((short) 1);
        data2.setStatus((short) 1);
        list1.add(data1);
        list1.add(data2);
        list1.add(data1);
        list1.add(data2);

        return list1;

    }

    @SubscribeMapping("/latest")
    public Map<String, TsData> getLatest(SimpMessageHeaderAccessor headerAccessor) {

        List<String> keyList = headerAccessor.getNativeHeader("keyStr");
        List<String> thingTypeList = headerAccessor.getNativeHeader("thingType");
        List<String> thingIdList = headerAccessor.getNativeHeader("thingId");
        List<String> uniformCodesList = headerAccessor.getNativeHeader("uniformCodes");

        if (keyList.size() > 0) {
            String[] tagNames = keyList.get(0).split(",");
            Map<String, TsData> data = tsDataService.getLatest(tagNames);
            if (data == null) {
                Map<String, TsData> nullData = new HashMap<>();
                return nullData;
            } else {
                return data;
            }
        } else if (thingTypeList.size() > 0 && thingIdList.size() > 0 && uniformCodesList.size() > 0) {
            String[] uCodes = uniformCodesList.get(0).split(",");
            return tsDataService.getLatestByUniformCodes(thingTypeList.get(0), thingIdList.get(0), uCodes);
        } else {
            Map<String, TsData> nullData = new HashMap<>();
            return nullData;
        }
    }


    @SubscribeMapping("/history/raw")
    public List<TsData> getHistoryRaw(SimpMessageHeaderAccessor headerAccessor) {

        List<String> tagNameList = headerAccessor.getNativeHeader("tagName");
        List<String> thingTypeList = headerAccessor.getNativeHeader("thingType");
        List<String> thingIdList = headerAccessor.getNativeHeader("thingId");
        List<String> uniformCodesList = headerAccessor.getNativeHeader("uniformCode");
        List<String> startTsList = headerAccessor.getNativeHeader("startTs");
        List<String> endTsList = headerAccessor.getNativeHeader("endTs");

        if (tagNameList.size() > 0 && startTsList.size() > 0 && endTsList.size() > 0)
            return tsDataService.getHistoryRaw(tagNameList.get(0), Long.valueOf(startTsList.get(0)), Long.valueOf(endTsList.get(0)));

        if (thingTypeList.size() > 0 && thingIdList.size() > 0 && uniformCodesList.size() > 0 && startTsList.size() > 0 && endTsList.size() > 0) {
            return tsDataService.getHistoryRaw(thingTypeList.get(0), thingIdList.get(0), uniformCodesList.get(0), Long.valueOf(startTsList.get(0)), Long.valueOf(endTsList.get(0)));
        } else
            return null;
    }

    @SubscribeMapping("/history/snap")
    public List<TsData> getHistorySnap(SimpMessageHeaderAccessor headerAccessor) {

        List<String> tagNameList = headerAccessor.getNativeHeader("tagName");
        List<String> thingTypeList = headerAccessor.getNativeHeader("thingType");
        List<String> thingIdList = headerAccessor.getNativeHeader("thingId");
        List<String> uniformCodesList = headerAccessor.getNativeHeader("uniformCode");
        List<String> startTsList = headerAccessor.getNativeHeader("startTs");
        List<String> endTsList = headerAccessor.getNativeHeader("endTs");
        List<String> intervalList = headerAccessor.getNativeHeader("interval");

        if (tagNameList.size() > 0 && startTsList.size() > 0 && endTsList.size() > 0 && intervalList.size() > 0)
            return tsDataService.getHistorySnap(tagNameList.get(0), Long.valueOf(startTsList.get(0)), Long.valueOf(endTsList.get(0)), Integer.valueOf(intervalList.get(0)));
        if (thingIdList.size() > 0 && thingTypeList.size() > 0 && uniformCodesList.size() > 0 && startTsList.size() > 0 && endTsList.size() > 0 && intervalList.size() > 0) {
            return tsDataService.getHistorySnap(thingTypeList.get(0), thingIdList.get(0), uniformCodesList.get(0), Long.valueOf(startTsList.get(0)), Long.valueOf(endTsList.get(0)), Integer.valueOf(intervalList.get(0)));
        } else
            return null;

    }

    @SubscribeMapping("/history/stat")
    public List<DoubleStatData> getHistoryStat(SimpMessageHeaderAccessor headerAccessor) {

        List<String> tagNameList = headerAccessor.getNativeHeader("tagName");
        List<String> thingTypeList = headerAccessor.getNativeHeader("thingType");
        List<String> thingIdList = headerAccessor.getNativeHeader("thingId");
        List<String> uniformCodesList = headerAccessor.getNativeHeader("uniformCode");
        List<String> startTsList = headerAccessor.getNativeHeader("startTs");
        List<String> endTsList = headerAccessor.getNativeHeader("endTs");
        List<String> intervalList = headerAccessor.getNativeHeader("interval");

        if (tagNameList.size() > 0 && startTsList.size() > 0 && endTsList.size() > 0 && intervalList.size() > 0)
            return tsDataService.getHistoryStat(tagNameList.get(0), Long.valueOf(startTsList.get(0)), Long.valueOf(endTsList.get(0)), Integer.valueOf(intervalList.get(0)));
        if (thingIdList.size() > 0 && thingTypeList.size() > 0 && uniformCodesList.size() > 0 && startTsList.size() > 0 && endTsList.size() > 0 && intervalList.size() > 0) {
            return tsDataService.getHistoryStat(thingTypeList.get(0), thingIdList.get(0), uniformCodesList.get(0), Long.valueOf(startTsList.get(0)), Long.valueOf(endTsList.get(0)), Integer.valueOf(intervalList.get(0)));
        } else
            return null;

    }

    @SubscribeMapping("/history/section")
    public Map<String, TsData> getHistorySection(SimpMessageHeaderAccessor headerAccessor) throws Exception {
        List<String> tagNameList = headerAccessor.getNativeHeader("tagNames");
        List<String> tsList = headerAccessor.getNativeHeader("ts");
        try {
            if (tagNameList.size() > 0 && tsList.size() > 0) {
                String[] tagNameArr = tagNameList.get(0).split(",");
                return tsDataService.getHistorySection(Long.valueOf(tsList.get(0)), tagNameArr);
            } else
                return null;

        } catch (Exception e) {
            return null;
        }

    }

    @SubscribeMapping("/write/history/batch")
    public boolean writeHistoryBatch(SimpMessageHeaderAccessor headerAccessor) {
        List<String> jsonList = headerAccessor.getNativeHeader("tsDataList");
        if (jsonList.size() > 0) {
            JSONArray jsonArray = JSON.parseArray(jsonList.get(0));
            List<TsPointData> list = JSONObject.parseArray(jsonArray.toJSONString(), TsPointData.class);
            try {
                tsDataService.writeHistory(list);
                return true;
            } catch (Exception e) {
                return false;
            }
        } else
            return false;


    }

    @PostMapping("/write/history")
    @ResponseBody
    public boolean writeHistory(SimpMessageHeaderAccessor headerAccessor) {
        List<String> jsonList = headerAccessor.getNativeHeader("tsData");
        if (jsonList.size() > 0) {
            JSONObject obj = JSONObject.parseObject(jsonList.get(0));
            TsPointData tsData = JSONObject.toJavaObject(obj, TsPointData.class);
            try {
                List<TsPointData> list = new ArrayList<>();
                list.add(tsData);
                tsDataService.writeHistory(list);
                return true;
            } catch (Exception e) {
                return false;
            }
        } else
            return false;

    }

    @PostMapping("/write/history/list")
    @ResponseBody
    public boolean writeHistoryList(SimpMessageHeaderAccessor headerAccessor) {
        List<String> jsonList = headerAccessor.getNativeHeader("tsData");
        if (jsonList.size() > 0) {
            JSONObject obj = JSONObject.parseObject(jsonList.get(0));
            TsPointDataList tsData = JSONObject.toJavaObject(obj, TsPointDataList.class);
            try {
                List<TsPointData> tsDataList = new ArrayList<>();
                if (tsData != null) {
                    for (int i = 0; i < tsData.getTsDataList().size(); i++) {
                        TsPointData data = new TsPointData();
                        data.setTagName(tsData.getTagName());
                        data.setTsData(tsData.getTsDataList().get(i));
                        tsDataList.add(data);
                    }
                    tsDataService.writeHistory(tsDataList);
                    return true;
                } else {
                    return false;
                }
            } catch (Exception e) {
                return false;
            }
        } else
            return false;

    }


    @PostMapping("/write/latest/batch")
    @ResponseBody
    public boolean writeLatestBatch(SimpMessageHeaderAccessor headerAccessor) throws Exception {

        List<String> jsonList = headerAccessor.getNativeHeader("tsDataList");
        if (jsonList.size() > 0) {
            JSONArray jsonArray = JSON.parseArray(jsonList.get(0));
            List<TsPointData> list = JSONObject.parseArray(jsonArray.toJSONString(), TsPointData.class);

            return tsDataService.writeLatest(list);
        } else
            return false;
    }

    @PostMapping("/write/latest")
    @ResponseBody
    public boolean writeLatest(SimpMessageHeaderAccessor headerAccessor) throws Exception {
        List<String> jsonList = headerAccessor.getNativeHeader("tsData");
        if (jsonList.size() > 0) {
            JSONObject obj = JSONObject.parseObject(jsonList.get(0));
            TsPointData tsData = JSONObject.toJavaObject(obj, TsPointData.class);

            List<TsPointData> tsDataList = new ArrayList<>();
            tsDataList.add(tsData);
            return tsDataService.writeLatest(tsDataList);
        } else
            return false;

    }

    /**
     * @description websocket广播方法
     * @author wanghs
     * @date 2019-09-23
     * @param distination 广播地址
     * @param sendMap 消息体
     * @return void
     */
    public void SendWindToAll(String destination, Map<String, WindturbineData> sendMap){
        simpMessagingTemplate.convertAndSend(destination,sendMap);
        Constant.dOneLine(" 风 ");
    }

    public void SendPVToAll(String destination, Map<String,InverterBasicData> pvDataMap)
    {
        simpMessagingTemplate.convertAndSend(destination,pvDataMap);
        Constant.dOneLine(" 光 ");
    }
}

