package com.gyee.frame.service.export;

import com.gyee.frame.common.conf.ExportConfig;
import com.gyee.frame.common.conf.ThreadPoolTaskConfig;
import com.gyee.frame.common.exception.QiNiuException;
import com.gyee.frame.common.exception.enums.QiNiuErrorEnum;
import com.gyee.frame.common.feign.RemoteServiceBuilder;
import com.gyee.frame.model.custom.export.TsPointData;
import com.gyee.frame.service.AnalysissubtablebottomService;
import com.gyee.frame.service.WindTurbineTestingPointAiService;
import com.gyee.frame.service.WindturbineService;
import com.gyee.frame.util.DateUtils;
import com.gyee.frame.util.task.TaskTemplateCallable;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.Future;
import java.util.stream.Collectors;


@Slf4j
@Service
public class GoldenService {


    @Resource
    private ExportConfig exportConfig;
    @Resource
    private ThreadPoolTaskConfig taskConfig;
    @Resource
    private RemoteServiceBuilder remoteService;
    @Resource
    private WindturbineService windturbineService;
    @Resource
    private WindTurbineTestingPointAiService windService;

    @Resource
    private AnalysissubtablebottomService analysissubtablebottomService;

    /**
     * 一天的时间戳
     */
    public static final Integer TIMES_TAMP_DAY = 86400;

    /**
     * 根据场站和风机ID查询
     *
     * @param station
     * @param wtId
     * @param templateId
     * @param startTs
     * @param endTs
     * @param interval
     * @return
     */
//    public List<Object> getHistoryDataSingle(String station, String wtId, int templateId, long startTs, long endTs, int interval) {
//        switch (templateId) {
//            case 1:
//                return getTemplateHistory1(station, wtId, startTs, endTs, interval);
//            default:
//                throw new QiNiuException(QiNiuErrorEnum.TEMPLATE_NO_SUPPORT);
//        }
//    }


    /**
     * 查询所有风机
     *
     * @param station
     * @param templateId
     * @param startTs
     * @param endTs
     * @param interval
     * @return
     */
    public Map<String, List<Object>> getHistoryDataAll(String station, int templateId, long startTs, long endTs, int interval) {
        switch (templateId) {
            case 1:
                return getTemplateHistory1(station, startTs, endTs, interval);
            case 2:
                return getTemplateHistory2(station, startTs, endTs, interval);
            default:
                throw new QiNiuException(QiNiuErrorEnum.TEMPLATE_NO_SUPPORT);
        }
    }


    /**
     * 模板1  场站所有风机数据
     *
     * @param station
     * @param startTs
     * @param endTs
     * @param interval
     * @return
     */
    private Map<String, List<Object>> getTemplateHistory1(String station, long startTs, long endTs, int interval) {
        // 风机ID、数据
        Map<String, List<Object>> map = new LinkedHashMap<>();

        try {
            List<String> winds = windturbineService.findWindTurbineAll(station);
            if (winds == null)
                return map;

            // 异步返回结果
            List<Future<Map<String, List<Object>>>> list = new LinkedList<>();
            for (String wind : winds) {
                TaskTemplateCallable task = new TaskTemplateCallable(windService, remoteService.ShardingService(),
                        exportConfig.getTemplate1(), station, wind, startTs, endTs, interval);
                Future submit = taskConfig.getExecutor().submit(task);
                list.add(submit);
            }

            // 返回结果处理
            for (Future<Map<String, List<Object>>> future : list) {
                Map<String, List<Object>> wtMap = future.get();
                for (Map.Entry<String, List<Object>> entry : wtMap.entrySet()) {
                    map.put(entry.getKey(), entry.getValue());
                }
            }

        } catch (Exception e) {
            log.error(e.getMessage());
            throw new QiNiuException(QiNiuErrorEnum.ERROR_DATA);
        }

        return map;
    }


    /**
     * 模板1  单机数据
     *
     * @param station
     * @param wtId
     * @param startTs
     * @param endTs
     * @param interval
     * @return
     */
//    private List<Object> getTemplateHistory1(String station, String wtId, long startTs, long endTs, int interval) {
//        List<Object> list = new ArrayList<>();
//        List<String> codes = exportConfig.getTemplate1();
//
//        // 第一列添加时间
//        List<String> intervals = dateInterval(startTs, endTs, interval);
//        list.add(intervals);
//
//        try {
//            for (String code : codes) {
//                List<WindTurbineTestingPointAi2> windPoints = windService.findPointsByUniformCodeAndStation(station, wtId, code);
//                if (windPoints == null || windPoints.size() == 0)
//                    continue;
//
//                WindTurbineTestingPointAi2 windPoint = windPoints.get(0);
//                List<TsPointData> data = remoteService.ShardingService().getHistorySnap(windPoint.getId(), startTs, endTs, interval);
//
//                List<Object> collect = new ArrayList<>();
//                // 故障状态或限电状态都是整型0或1
//                if (code.equals("GZZT") || code.equals("XDZT")) {
//                    if (data.size() == 0) {
//                        for (int i = 0; i < intervals.size(); i++)
//                            collect.add(0);
//                    } else {
//                        collect = data.stream().map(point -> (int) point.getDoubleValue()).collect(Collectors.toList());
//                    }
//                    list.add(collect);
//                } else {
//                    if (data.size() == 0) {
//                        for (int i = 0; i < intervals.size(); i++)
//                            collect.add(0.0);
//                    } else {
//                        collect = data.stream().map(TsPointData::getDoubleValue).collect(Collectors.toList());
//                    }
//                    list.add(collect);
//                }
//            }
//        } catch (QiNiuException e) {
//            log.error(e.getMessage());
//            throw new QiNiuException(QiNiuErrorEnum.ERROR_DATA);
//        }
//
//        return list;
//    }


    /**
     * 模板2  场站所有风机数据  日上网电量、上网功率、测风塔数据
     *
     * @param station
     * @param startTs
     * @param endTs
     * @return
     */
    private Map<String, List<Object>> getTemplateHistory2(String station, long startTs, long endTs, int interval) {
        // 风机ID、数据
        Map<String, List<Object>> map = new LinkedHashMap<>();

        try {
            // 上网电量
            String point = exportConfig.getTemplate2swdl().get(station);
            String[] points = point.split(",");
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String startTss = dateFormat.format(startTs);
            String endTss = dateFormat.format(endTs);
            List<Map> data = analysissubtablebottomService.selectByRecorddateGrop(startTss,endTss,station,points);


            //List<TsPointData> data = remoteService.ShardingService().getHistorySnap(point, startTs, endTs, TIMES_TAMP_DAY);
            List<Object> list = new ArrayList<>();
            //list.add(data.stream().map(p -> DateUtils.format(p.getTs(), DateUtils.DATE_PATTERN)).collect(Collectors.toList()));
            //list.add(data.stream().map(TsPointData::getDoubleValue).collect(Collectors.toList()));

            list.add(data.stream().map(p -> dateFormat.format(p.get("RECORDDATE"))).collect(Collectors.toList()));
            list.add(data.stream().map(p -> Double.valueOf(p.get("SWDL").toString())).collect(Collectors.toList()));
            map.put("swdl", list);

            // 上网功率
            String point2 = exportConfig.getTemplate2swgl().get(station);
            List<TsPointData> data2 = remoteService.ShardingService().getHistorySnap(point2, startTs, endTs, interval);
            List<Object> list2 = new ArrayList<>();
            list2.add(data2.stream().map(p -> DateUtils.format(p.getTs(), DateUtils.DATE_TIME_PATTERN)).collect(Collectors.toList()));
            list2.add(data2.stream().map(TsPointData::getDoubleValue).collect(Collectors.toList()));
            map.put("swgl", list2);

            // 测风塔数据
            String point3 = exportConfig.getTemplate2cft().get(station);
            List<Object> maps = getTemplateHistory2(startTs, endTs, interval, point3);
            map.put("cft", maps);

        } catch (QiNiuException e) {
            log.error(e.getMessage());
            throw new QiNiuException(QiNiuErrorEnum.ERROR_DATA);
        }

        return map;
    }


    /**
     * 模板2  场站数据
     *
     * @param startTs
     * @param endTs
     * @param interval
     * @param points
     * @return
     */
    private List<Object> getTemplateHistory2(long startTs, long endTs, int interval, String points) {
        List<Object> list = new ArrayList<>();

        // 第一列添加时间
        List<String> intervals = dateInterval(startTs, endTs, interval);
        list.add(intervals);

        try {
            String[] splits = points.split(",");
            for (String point : splits) {
                List<TsPointData> data = remoteService.ShardingService().getHistorySnap(point, startTs, endTs, interval);

                List<Object> collect = new ArrayList<>();
                if (data.size() == 0) {
                    for (int i = 0; i < intervals.size(); i++)
                        collect.add(0);
                } else {
                    collect = data.stream().map(TsPointData::getDoubleValue).collect(Collectors.toList());
                }
                list.add(collect);
            }

        } catch (QiNiuException e) {
            log.error(e.getMessage());
            throw new QiNiuException(QiNiuErrorEnum.ERROR_DATA);
        }

        return list;
    }


    /**
     * 分割时间
     *
     * @param st
     * @param et
     * @param interval
     * @return
     */
    private List<String> dateInterval(long st, long et, int interval) {
        List<String> list = new ArrayList<>();
        int val = interval * 1000;
        while (st < et) {
            list.add(DateUtils.format(st, DateUtils.DATE_TIME_PATTERN));
            st += val;
        }

        return list;
    }

}
