package com.njcn.event.service.distribution.Impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.njcn.common.pojo.constant.BizParamConstant;
import com.njcn.common.pojo.dto.SimpleDTO;
import com.njcn.common.pojo.param.StatisticsBizBaseParam;
import com.njcn.device.pms.api.PmsGeneralDeviceInfoClient;
import com.njcn.device.pms.api.PwMonitorClient;
import com.njcn.device.pms.api.StatationStatClient;
import com.njcn.device.pms.pojo.dto.PmsGeneralDeviceDTO;
import com.njcn.device.pms.pojo.dto.PwPmsMonitorDTO;
import com.njcn.device.pms.pojo.param.PmsDeviceInfoParam;
import com.njcn.device.pms.pojo.param.PmsStatationStatInfoParam;
import com.njcn.device.pms.pojo.param.PwPmsMonitorParam;
import com.njcn.device.pms.pojo.po.StatationStat;
import com.njcn.event.mapper.distribution.PwEventCategoryDetailsMapper;
import com.njcn.event.mapper.majornetwork.RStatSubstationMapper;
import com.njcn.event.pojo.param.UniversalFrontEndParam;
import com.njcn.event.pojo.po.EventDistributionStatisticsPO;
import com.njcn.event.pojo.po.EventDurationLineChartPO;
import com.njcn.event.pojo.po.EventFeatureAmplitudeLineChartPO;
import com.njcn.event.pojo.po.RmpEventDetailPO;
import com.njcn.event.pojo.vo.EventDistributionStatisticsTableVO;
import com.njcn.event.pojo.vo.EventFeatureAmplitudeCurveVO;
import com.njcn.event.pojo.vo.RStatSubstationVO;
import com.njcn.event.pojo.vo.SimpleVO;
import com.njcn.event.service.distribution.PwEventCategoryDetailsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 配网-暂态事件分布统计
 *
 * @author yzh
 * @date 2022/10/28
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class PwEventCategoryDetailsServiceImpl implements PwEventCategoryDetailsService {

    private final PwMonitorClient pwMonitorClient;
    private final PwEventCategoryDetailsMapper pwEventCategoryDetailsMapper;
    private final RStatSubstationMapper rStatSubstationMapper;
    private final PmsGeneralDeviceInfoClient pmsGeneralDeviceInfoClient;
    private final StatationStatClient statationStatClient;

    /**
     * 获取配网暂态事件分布统计
     *
     * @param param 条件参数
     * @return 配网暂态事件分布统计
     */
    @Override
    public List<EventDistributionStatisticsTableVO> getPwEventCategoryDetails(StatisticsBizBaseParam param) {
        // 获取单位下的监测点id集合

        PwPmsMonitorParam pwPmsMonitorParam = new PwPmsMonitorParam();
        pwPmsMonitorParam.setOrgId(param.getId());
        List<String> monitorIds = pmsGeneralDeviceInfoClient.getPwPmsMonitorIds(pwPmsMonitorParam).getData();

        // 创建集合，返回数据
        List<EventDistributionStatisticsTableVO> vos = new ArrayList<>();

        if (CollectionUtil.isEmpty(monitorIds)) {
            return Collections.emptyList();
        }
        // 获取暂态指标分布统计
        EventDistributionStatisticsPO po = pwEventCategoryDetailsMapper.getPwEventCategoryDetailsMapper(
                monitorIds,
                param.getStartTime(),
                param.getEndTime());

        if (ObjectUtil.isEmpty(po)) {
            return Collections.emptyList();
        }

        // 特征幅值10%
        // 创建对象返回参数
        EventDistributionStatisticsTableVO featureAmplitude10 = new EventDistributionStatisticsTableVO();
        featureAmplitude10.setFeatureAmplitude("10%");
        featureAmplitude10.setDuration20(po.getFeatureAmplitude10with20s());
        featureAmplitude10.setDuration100(po.getFeatureAmplitude10with100s());
        featureAmplitude10.setDuration500(po.getFeatureAmplitude10with500s());
        featureAmplitude10.setDuration1000(po.getFeatureAmplitude10with1000s());
        featureAmplitude10.setDuration3000(po.getFeatureAmplitude10with3000s());
        featureAmplitude10.setDuration20000(po.getFeatureAmplitude10with20000s());
        featureAmplitude10.setDuration60000(po.getFeatureAmplitude10with60000s());
        featureAmplitude10.setDuration180000(po.getFeatureAmplitude10with180000s());

        // 特征幅值40%
        // 创建对象返回参数
        EventDistributionStatisticsTableVO featureAmplitude40 = new EventDistributionStatisticsTableVO();
        featureAmplitude40.setFeatureAmplitude("40%");
        featureAmplitude40.setDuration20(po.getFeatureAmplitude40with20s());
        featureAmplitude40.setDuration100(po.getFeatureAmplitude40with100s());
        featureAmplitude40.setDuration500(po.getFeatureAmplitude40with500s());
        featureAmplitude40.setDuration1000(po.getFeatureAmplitude40with1000s());
        featureAmplitude40.setDuration3000(po.getFeatureAmplitude40with3000s());
        featureAmplitude40.setDuration20000(po.getFeatureAmplitude40with20000s());
        featureAmplitude40.setDuration60000(po.getFeatureAmplitude40with60000s());
        featureAmplitude40.setDuration180000(po.getFeatureAmplitude40with180000s());

        // 特征幅值70%
        // 创建对象返回参数
        EventDistributionStatisticsTableVO featureAmplitude70 = new EventDistributionStatisticsTableVO();
        featureAmplitude70.setFeatureAmplitude("70%");
        featureAmplitude70.setDuration20(po.getFeatureAmplitude70with20s());
        featureAmplitude70.setDuration100(po.getFeatureAmplitude70with100s());
        featureAmplitude70.setDuration500(po.getFeatureAmplitude70with500s());
        featureAmplitude70.setDuration1000(po.getFeatureAmplitude70with1000s());
        featureAmplitude70.setDuration3000(po.getFeatureAmplitude70with3000s());
        featureAmplitude70.setDuration20000(po.getFeatureAmplitude70with20000s());
        featureAmplitude70.setDuration60000(po.getFeatureAmplitude70with60000s());
        featureAmplitude70.setDuration180000(po.getFeatureAmplitude70with180000s());
        // 特征幅值85%
        // 创建对象返回参数
        EventDistributionStatisticsTableVO featureAmplitude85 = new EventDistributionStatisticsTableVO();
        featureAmplitude85.setFeatureAmplitude("85%");
        featureAmplitude85.setDuration20(po.getFeatureAmplitude85with20s());
        featureAmplitude85.setDuration100(po.getFeatureAmplitude85with100s());
        featureAmplitude85.setDuration500(po.getFeatureAmplitude85with500s());
        featureAmplitude85.setDuration1000(po.getFeatureAmplitude85with1000s());
        featureAmplitude85.setDuration3000(po.getFeatureAmplitude85with3000s());
        featureAmplitude85.setDuration20000(po.getFeatureAmplitude85with20000s());
        featureAmplitude85.setDuration60000(po.getFeatureAmplitude85with60000s());
        featureAmplitude85.setDuration180000(po.getFeatureAmplitude85with180000s());
        // 特征幅值90%
        // 创建对象返回参数
        EventDistributionStatisticsTableVO featureAmplitude90 = new EventDistributionStatisticsTableVO();
        featureAmplitude90.setFeatureAmplitude("90%");
        featureAmplitude90.setDuration20(po.getFeatureAmplitude90with20s());
        featureAmplitude90.setDuration100(po.getFeatureAmplitude90with100s());
        featureAmplitude90.setDuration500(po.getFeatureAmplitude90with500s());
        featureAmplitude90.setDuration1000(po.getFeatureAmplitude90with1000s());
        featureAmplitude90.setDuration3000(po.getFeatureAmplitude90with3000s());
        featureAmplitude90.setDuration20000(po.getFeatureAmplitude90with20000s());
        featureAmplitude90.setDuration60000(po.getFeatureAmplitude90with60000s());
        featureAmplitude90.setDuration180000(po.getFeatureAmplitude90with180000s());
        // 属性赋值
        vos.add(featureAmplitude10);
        vos.add(featureAmplitude40);
        vos.add(featureAmplitude70);
        vos.add(featureAmplitude85);
        vos.add(featureAmplitude90);

        return vos;
    }

    /**
     * 获取配网持续时间概率分布函数
     *
     * @param param 条件参数
     * @return 配网持续时间概率分布函数
     * @author yzh
     * @date 2022/10/31
     */
    @Override
    public List<SimpleVO> getPwDurationLineChart(StatisticsBizBaseParam param) {
        // 创建集合返回数据
        List<SimpleVO> result = new ArrayList<>();
        // 获取单位下的监测点id集合
        PwPmsMonitorParam pwPmsMonitorParam = new PwPmsMonitorParam();
        pwPmsMonitorParam.setOrgId(param.getId());
        List<String> monitorIds = pmsGeneralDeviceInfoClient.getPwPmsMonitorIds(pwPmsMonitorParam).getData();

        if (CollectionUtil.isEmpty(monitorIds)) {
            return Collections.emptyList();
        }
        // 获取持续时间折线图
        EventDurationLineChartPO po = pwEventCategoryDetailsMapper.getPwEventDurationLineChart(
                monitorIds,
                param.getStartTime(),
                param.getEndTime());
        if (ObjectUtil.isEmpty(po)) {
            return Collections.emptyList();
        }
        SimpleVO vo100 = new SimpleVO();
        vo100.setName("0.1");
        vo100.setValue(po.getDuration100());
        SimpleVO vo250 = new SimpleVO();
        vo250.setName("0.25");
        vo250.setValue(po.getDuration250());
        SimpleVO vo500 = new SimpleVO();
        vo500.setName("0.5");
        vo500.setValue(po.getDuration500());
        SimpleVO vo1000 = new SimpleVO();
        vo1000.setName("1");
        vo1000.setValue(po.getDuration1000());
        SimpleVO vo1100 = new SimpleVO();
        vo1100.setName("1.1");
        vo1100.setValue(po.getDuration1100());

        // 创建map集合，封装数据
        result.add(vo100);
        result.add(vo250);
        result.add(vo500);
        result.add(vo1000);
        result.add(vo1100);

        return result;

    }

    /**
     * 获取配网暂降幅值概率分布函数
     *
     * @param param 条件参数
     * @return java.util.List<com.njcn.event.pojo.vo.SimpleVO>
     * @author yzh
     * @date 2022/10/31
     */
    @Override
    public List<SimpleVO> getPwFeatureAmplitudeLineChart(StatisticsBizBaseParam param) {
        // 创建集合返回数据
        List<SimpleVO> result = new ArrayList<>();

        // 获取单位下的监测点id集合
        PwPmsMonitorParam pwPmsMonitorParam = new PwPmsMonitorParam();
        pwPmsMonitorParam.setOrgId(param.getId());
        List<String> monitorIds = pmsGeneralDeviceInfoClient.getPwPmsMonitorIds(pwPmsMonitorParam).getData();

        if (CollectionUtil.isEmpty(monitorIds)) {
            return Collections.emptyList();
        }
        // 获取特征幅值折线图
        EventFeatureAmplitudeLineChartPO po = pwEventCategoryDetailsMapper.getPwEventFeatureAmplitudeLineChart(monitorIds,
                param.getStartTime(),
                param.getEndTime());

        if (ObjectUtil.isEmpty(po)) {
            return Collections.emptyList();
        }

        SimpleVO vo10 = new SimpleVO();
        vo10.setName("10%");
        vo10.setValue(po.getFeatureAmplitude10());
        SimpleVO vo20 = new SimpleVO();
        vo20.setName("20%");
        vo20.setValue(po.getFeatureAmplitude20());
        SimpleVO vo30 = new SimpleVO();
        vo30.setName("30%");
        vo30.setValue(po.getFeatureAmplitude30());
        SimpleVO vo40 = new SimpleVO();
        vo40.setName("40%");
        vo40.setValue(po.getFeatureAmplitude40());
        SimpleVO vo50 = new SimpleVO();
        vo50.setName("50%");
        vo50.setValue(po.getFeatureAmplitude50());
        SimpleVO vo60 = new SimpleVO();
        vo60.setName("60%");
        vo60.setValue(po.getFeatureAmplitude60());
        SimpleVO vo70 = new SimpleVO();
        vo70.setName("70%");
        vo70.setValue(po.getFeatureAmplitude70());
        SimpleVO vo80 = new SimpleVO();
        vo80.setName("80%");
        vo80.setValue(po.getFeatureAmplitude80());
        SimpleVO vo90 = new SimpleVO();
        vo90.setName("90%");
        vo90.setValue(po.getFeatureAmplitude90());

        // 创建map集合，封装数据
        result.add(vo10);
        result.add(vo20);
        result.add(vo30);
        result.add(vo40);
        result.add(vo50);
        result.add(vo60);
        result.add(vo70);
        result.add(vo80);
        result.add(vo90);

        return result;
    }

    /**
     * 获取配网暂态指标分布统计曲线图
     *
     * @param param 条件参数
     * @return com.njcn.event.pojo.vo.EventFeatureAmplitudeCurveVO
     * @author yzh
     * @date 2022/10/31
     */
    @Override
    public EventFeatureAmplitudeCurveVO getPwEventFeatureAmplitudeCurve(StatisticsBizBaseParam param) {
        // 获取单位下的监测点id集合
        PwPmsMonitorParam pwPmsMonitorParam = new PwPmsMonitorParam();
        pwPmsMonitorParam.setOrgId(param.getId());
        List<String> monitorIds = pmsGeneralDeviceInfoClient.getPwPmsMonitorIds(pwPmsMonitorParam).getData();

        if (CollectionUtil.isEmpty(monitorIds)) {
            return EventFeatureAmplitudeCurveVO.empty();
        }

        // 获取监测点暂态事件明细数据
        List<RmpEventDetailPO> rmpEventDetailList = pwEventCategoryDetailsMapper.getPwRmpEventDetail(monitorIds, param.getStartTime(), param.getEndTime());
        if (CollUtil.isEmpty(rmpEventDetailList)) {
            return EventFeatureAmplitudeCurveVO.empty();
        }


        List<EventFeatureAmplitudeCurveVO.EventFeatureAmplitudeCurveDataList> curveDataList = rmpEventDetailList.parallelStream()
                .map(dto -> {
                    EventFeatureAmplitudeCurveVO.EventFeatureAmplitudeCurveDataList eventFeatureAmplitudeCurve = new EventFeatureAmplitudeCurveVO.EventFeatureAmplitudeCurveDataList();
                    eventFeatureAmplitudeCurve.setMeasurementPointId(dto.getMeasurementPointId());
                    eventFeatureAmplitudeCurve.setFeatureAmplitude(dto.getFeatureAmplitude());
                    eventFeatureAmplitudeCurve.setDuration(dto.getDuration());

                    eventFeatureAmplitudeCurve.setStartTime(dto.getStartTime());

                    return eventFeatureAmplitudeCurve;
                })
                .collect(Collectors.toCollection(() -> Collections.synchronizedList(new ArrayList<>())));

        return EventFeatureAmplitudeCurveVO.buildVO(rmpEventDetailList.size(), curveDataList);
    }

    @Override
    public List<RStatSubstationVO> getRStatSubstation(UniversalFrontEndParam param) {

        //远程调用监测点信息接口
        PmsDeviceInfoParam pms = new PmsDeviceInfoParam();
        pms.setDeptIndex(param.getId());
        pms.setStatisticalType(new SimpleDTO());
        //获取配网台账信息(根据台账信息获取，变电站的集合包括所有的子集变电站)
        List<PmsGeneralDeviceDTO> data = pmsGeneralDeviceInfoClient.getPwPmsDeviceInfoWithOrgId(pms).getData();
        List<String> ids = new ArrayList<>();
        data.stream().forEach(e -> ids.addAll(e.getPowerrIdList()));

        // 查询变电站信息
        PmsStatationStatInfoParam pmsStatationStatInfoParam = new PmsStatationStatInfoParam();
        pmsStatationStatInfoParam.setPowerIds(ids);
        if (!StringUtils.isEmpty(param.getSubName())) {
            pmsStatationStatInfoParam.setPowerName(param.getSubName());
        }

        List<StatationStat> powerInfo = statationStatClient.getPowerInfo(pmsStatationStatInfoParam).getData();
        if (CollUtil.isEmpty(powerInfo)) {
            return Collections.emptyList();
        }

        // 取出变电站id
        List<String> powerIds = powerInfo.stream().map(StatationStat::getPowerId).collect(Collectors.toList());
        //创建返回集合
        List<RStatSubstationVO> result = new ArrayList<>();

        // 类型（1年 2季度 3月份 4日
        switch (param.getType().toString()) {
            case BizParamConstant.STAT_BIZ_YEAR:
                // 获取年变电站暂态指标分类统计表
                result = rStatSubstationMapper.getYearInfo(powerIds, param.getStartTime(), param.getEndTime());
                break;
            case BizParamConstant.STAT_BIZ_QUARTER:
                // 获取季变电站暂态指标分类统计表
                result = rStatSubstationMapper.getQuarterInfo(powerIds, param.getStartTime(), param.getEndTime());
                break;
            case BizParamConstant.STAT_BIZ_MONTH:
                // 获取月变电站暂态指标分类统计表
                result = rStatSubstationMapper.getMonthInfo(powerIds, param.getStartTime(), param.getEndTime());
                break;
            default:
                break;
        }
        if (CollUtil.isEmpty(result)) {
            return Collections.emptyList();
        }
        // 将变电站信息根据变电站id转换成map集合(当出现重复数据，用第二条)
        Map<String, StatationStat> powerMap = powerInfo.stream().collect(
                Collectors.toMap(StatationStat::getPowerId, Function.identity(), (key1, key2) -> key2));
        // 属性赋值(获取部门名称，变电站名称)
        return result.stream().peek(vo -> {
            String substationId = vo.getSubstationId();
            vo.setDeptId(powerMap.get(substationId).getOrgId());
            vo.setSubstationName(powerMap.get(substationId).getPowerName());
            vo.setDeptName(powerMap.get(substationId).getOrgName());
        }).collect(Collectors.toList());
    }

    /**
     * 获取单位id
     *
     * @param param 条件参数
     * @return 单位id
     */
    private List<PwPmsMonitorDTO> getPwMonitorList(StatisticsBizBaseParam param) {
        // 获取单位下的监测点id集合
        PwPmsMonitorParam pwPmsMonitorParam = new PwPmsMonitorParam();
        pwPmsMonitorParam.setOrgId(param.getId());
        return pwMonitorClient
                .getPwMonitorList(pwPmsMonitorParam)
                .getData();
    }
}
