package com.xzzn.ems.service.impl;

import com.xzzn.common.utils.DateUtils;
import com.xzzn.common.utils.StringUtils;
import com.xzzn.ems.domain.EmsSiteSetting;
import com.xzzn.ems.domain.vo.*;
import com.xzzn.ems.mapper.*;
import com.xzzn.ems.service.IEmsSiteService;
import com.xzzn.ems.service.IHomePageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 首页看板+站点地图 服务层实现
 *
 */
@Service
public class HomePageServiceImpl implements IHomePageService
{
    private static final int LIMIT_TIME = 6;

    @Autowired
    private IEmsSiteService emsSiteService;
    @Autowired
    private EmsSiteSettingMapper emsSiteMapper;
    @Autowired
    private EmsAlarmRecordsMapper alarmRecordsMapper;
    @Autowired
    private EmsDailyChargeDataMapper emsDailyChargeDataMapper;
    @Autowired
    private EmsAmmeterDataMapper emsAmmeterDataMapper;

    @Override
    public SiteTotalInfoVo getSiteTotalInfo() {
        SiteTotalInfoVo siteTotalInfoVo = new SiteTotalInfoVo();
        siteTotalInfoVo = emsSiteService.getSiteTotalInfo();
        // 获取总充+总放
        String nowData = DateUtils.getDate();
        Map<String,BigDecimal> data  = emsDailyChargeDataMapper.getAllSiteChargeData(nowData,null);
        if(data != null){
            siteTotalInfoVo.setTotalChargedCap(data.get("totalChargedCap"));
            siteTotalInfoVo.setTotalDischargedCap(data.get("totalDischargedCap"));
        }
        return siteTotalInfoVo;
    }

    // 单站点基本信息
    @Override
    public SingleSiteBaseInfo getSingleSiteBaseInfo(String siteId) {
        SingleSiteBaseInfo singleSiteBaseInfo = new SingleSiteBaseInfo();

        if (!StringUtils.isEmpty(siteId)) {
            // 站点基本信息
            EmsSiteSetting emsSite = emsSiteMapper.selectEmsSiteSettingBySiteId(siteId);
            if (emsSite != null) {
                // 装机功率+装机容量
                singleSiteBaseInfo.setSiteName(emsSite.getSiteName());
                singleSiteBaseInfo.setInstallCapacity(emsSite.getInstallCapacity());
                singleSiteBaseInfo.setInstallPower(emsSite.getInstallPower());
                String[] siteLocation = new String[2];
                siteLocation[0] = emsSite.getLongitude() == null ? ""  : emsSite.getLongitude().toString();
                siteLocation[1] = emsSite.getLatitude() ==  null ? ""  : emsSite.getLatitude().toString();
                singleSiteBaseInfo.setSiteLocation(siteLocation);//站点位置
                singleSiteBaseInfo.setSiteAddress(emsSite.getSiteAddress());
                singleSiteBaseInfo.setRunningTime(emsSite.getRunningTime() == null ? null :
                        DateUtils.parseDateToStr("yyyy-MM-dd",emsSite.getRunningTime()));//投运时间
                // 获取单站点的总充+总放
                String nowData = DateUtils.getDate();
                Map<String,BigDecimal> data  = emsDailyChargeDataMapper.getAllSiteChargeData(nowData,siteId);
                if (data != null) {
                    singleSiteBaseInfo.setTotalChargedCap(data.get("totalChargedCap"));
                    singleSiteBaseInfo.setTotalDisChargedCap(data.get("totalDischargedCap"));
                }
                // 七天放电数据统计 默认从今天往前7天
                LocalDate sevenDaysAgo = LocalDate.now().minusDays(LIMIT_TIME);
                Date startDate = DateUtils.toDate(sevenDaysAgo);
                Date endDate = new Date();
                List<SiteMonitorDataVo> siteMonitorDataVoList = emsDailyChargeDataMapper.getSingleSiteChargeData(siteId,startDate,endDate);
                singleSiteBaseInfo.setSevenDayDisChargeStats(siteMonitorDataVoList);
                // 充放电基本数据处理
                dealSiteChargeDate(singleSiteBaseInfo,siteMonitorDataVoList);
            }
        }

        return singleSiteBaseInfo;
    }

    private void dealSiteChargeDate(SingleSiteBaseInfo singleSiteBaseInfo, List<SiteMonitorDataVo> siteMonitorDataVoList) {
        if (siteMonitorDataVoList != null && !siteMonitorDataVoList.isEmpty()) {
            for (SiteMonitorDataVo sitePcsData : siteMonitorDataVoList) {
                // 获取当天的充电量+放电量
                String dayDate = sitePcsData.getAmmeterDate();
                boolean isToday= DateUtils.checkIsToday(dayDate);
                if(isToday){
                    singleSiteBaseInfo.setDayChargedCap(sitePcsData.getChargedCap());
                    singleSiteBaseInfo.setDayDisChargedCap(sitePcsData.getDisChargedCap());
                }
            }
        }
    }

    /**
     * 首页看板-数据概览
     */
    @Override
    public HomePageDataViewVo getHomePageDataList() {
        HomePageDataViewVo  homePageDataViewVo = new HomePageDataViewVo();
        // 电量指标
        //List<ElectricIndexList> electricDataList = emsPcsDataMapper.getElectDataList();
        List<ElectricIndexList> electricDataList = getElectricDataList2();
        homePageDataViewVo.setElecDataList(electricDataList);
        // 系统效率
        List<SystemEfficiencyList> systemEfficiencyLists = new ArrayList<>();
        if (electricDataList != null && !electricDataList.isEmpty()) {
            for (ElectricIndexList electricIndexList : electricDataList) {
                SystemEfficiencyList systemEfficiency = new SystemEfficiencyList();
                systemEfficiency.setDateMonth(electricIndexList.getDateMonth());

                BigDecimal dailyEfficiency = new BigDecimal(0);
                BigDecimal chargeEnergy = electricIndexList.getChargeEnergy();
                BigDecimal disChargeEnergy = electricIndexList.getDisChargeEnergy();
                if (chargeEnergy != null && disChargeEnergy != null
                        && chargeEnergy.compareTo(BigDecimal.ZERO) > 0
                        && disChargeEnergy.compareTo(BigDecimal.ZERO) >= 0) {
                    dailyEfficiency = electricIndexList.getDisChargeEnergy().divide(electricIndexList.getChargeEnergy(), 2, RoundingMode.HALF_UP);
                    dailyEfficiency = dailyEfficiency.multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP);
                }
                systemEfficiency.setSystemEfficiency(dailyEfficiency);
                systemEfficiencyLists.add(systemEfficiency);
            }
        }
        homePageDataViewVo.setSysEfficList(systemEfficiencyLists);
        // 告警趋势
        List<AlarmTrendList> alarmTrendList = alarmRecordsMapper.getAlarmTrendList();
        homePageDataViewVo.setAlarmDataList(alarmTrendList);
        // 设备告警占比
        List<DeviceAlarmProportionList> deviceAlarmPropList = alarmRecordsMapper.getDeviceAlarmPropList();
        homePageDataViewVo.setDeviceAlarmList(deviceAlarmPropList);
        // 告警等级分布
        List<AlarmGradeList> alarmLevelList = alarmRecordsMapper.getAlarmGradeList();
        if (alarmLevelList != null && !alarmLevelList.isEmpty()) {
            BigDecimal total = new BigDecimal(alarmLevelList.size());
            for (AlarmGradeList alarmGradeList : alarmLevelList) {
                if (alarmGradeList.getDataNum() != 0
                        && total.compareTo(BigDecimal.ZERO) > 0) {
                    BigDecimal percent = new BigDecimal(alarmGradeList.getDataNum()).divide(total, 2, RoundingMode.HALF_UP)
                            .multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP);
                    alarmGradeList.setPercent(percent);
                }
            }
        }
        homePageDataViewVo.setAlarmLevelList(alarmLevelList);
        return homePageDataViewVo;
    }

    private List<ElectricIndexList> getElectricDataList2() {
        List<ElectricIndexList> electricDataList = new ArrayList<>();
        electricDataList = emsDailyChargeDataMapper.getAllSiteChargeDataByMonth();
        return  electricDataList;
    }

    private List<ElectricIndexList> getElectricDataList() {
        List<ElectricIndexList> electricDataList = new ArrayList<>();
        // 获取每个月最早和最晚的时间
        List<MonthlyTimeRange> timeRanges = emsAmmeterDataMapper.getMonthlyTimeRanges();
        if (timeRanges.isEmpty()) {
            return Collections.emptyList();
        }
        // 遍历收集所有需要查询的时间点（最早+最晚）
        List<TimePointQuery> timePointQueries = new ArrayList<>();
        for (MonthlyTimeRange range : timeRanges) {
            timePointQueries.add(new TimePointQuery(range.getSiteId(),range.getFirstDataTime()));
            timePointQueries.add(new TimePointQuery(range.getSiteId(),range.getLastDataTime()));
        }
        // 批量获取所有时间点对应的数据值转化为map
        List<TimePointValue> timePointValues = emsAmmeterDataMapper.batchGetTimePointValues(timePointQueries);
        Map<String, TimePointValue> valueMap = timePointValues.stream()
                .collect(Collectors.toMap(
                        v -> v.getSiteId() + "_" + v.getDataUpdateTime().toString(),
                        v -> v
                ));
        // 缓存每个站点的上月最晚电量 key=siteId, value=上月最晚时间对应数据
        Map<String, TimePointValue> lastMonthMap = new HashMap<>();

        // 组装结果-key=统计月，value=统计月的数据
        Map<String, ElectricIndexList> elecDataMap = new HashMap<>();
        for (MonthlyTimeRange timeRange : timeRanges) {
            String dataMonth = timeRange.getMonth();
            String siteId = timeRange.getSiteId();

            BigDecimal totalChargeData = new BigDecimal(0);
            BigDecimal totalDisChargeData = new BigDecimal(0);
            // 获取本月最晚数据
            TimePointValue monthLastValue = valueMap.get(siteId +"_"+timeRange.getLastDataTime());
            BigDecimal lastChargeValue = new BigDecimal(0);
            BigDecimal lastDisChargeValue = new BigDecimal(0);
            if (monthLastValue != null) {
                lastChargeValue = monthLastValue.getTotalChargeData() == null ? BigDecimal.ZERO : monthLastValue.getTotalChargeData();
                lastDisChargeValue = monthLastValue.getTotalDischargeData() == null ? BigDecimal.ZERO : monthLastValue.getTotalDischargeData();

            }// 看是否有缓存上个月最晚电量，没有则是首月
            if (!lastMonthMap.containsKey(siteId)) {
                // 首月充放电 = 本月最晚数据 - 本月最早数据
                TimePointValue monthFirstValue = valueMap.get(siteId +"_"+timeRange.getFirstDataTime());
                BigDecimal firstChargeValue =  new BigDecimal(0);
                BigDecimal firstDisChargeValue = new BigDecimal(0);
                if (monthLastValue != null) {
                    firstChargeValue = monthFirstValue.getTotalChargeData() == null ? BigDecimal.ZERO : monthFirstValue.getTotalChargeData();
                    firstDisChargeValue = monthFirstValue.getTotalDischargeData() == null ? BigDecimal.ZERO : monthFirstValue.getTotalDischargeData();
                }
                totalChargeData = lastChargeValue.subtract(firstChargeValue);
                totalDisChargeData = lastDisChargeValue.subtract(firstDisChargeValue);
            } else {// 非本月充放电 = 本月最晚数据 - 上月最晚数据
                TimePointValue lastValue = lastMonthMap.get(siteId);
                if (lastValue == null) {// 缓存找不到上月数据，则取本月最早数据
                    lastValue = valueMap.get(siteId +"_"+timeRange.getFirstDataTime());
                }
                BigDecimal lastMonthChargeValue = new BigDecimal(0);
                BigDecimal lastMonthDisChargeValue =  new BigDecimal(0);
                if (lastValue != null) {
                    lastMonthChargeValue = lastValue.getTotalChargeData() == null ? BigDecimal.ZERO : lastValue.getTotalChargeData();
                    lastMonthDisChargeValue = lastValue.getTotalDischargeData() == null ? BigDecimal.ZERO : lastValue.getTotalDischargeData();
                }totalChargeData = lastChargeValue.subtract(lastMonthChargeValue);
                totalDisChargeData = lastDisChargeValue.subtract(lastMonthDisChargeValue);
            }
            // 缓存最晚数据
            lastMonthMap.put(siteId,monthLastValue);

            ElectricIndexList electricIndexList = new ElectricIndexList();
            // 判断map里面是否已经有排序月份
            if (elecDataMap.containsKey(dataMonth)) {
                electricIndexList = elecDataMap.get(dataMonth);
                totalChargeData = totalChargeData.add(electricIndexList.getChargeEnergy());
                totalDisChargeData = totalDisChargeData.add(electricIndexList.getDisChargeEnergy());
            }
            electricIndexList.setDateMonth(dataMonth);
            electricIndexList.setChargeEnergy(totalChargeData);
            electricIndexList.setDisChargeEnergy(totalDisChargeData);
            elecDataMap.put(dataMonth,electricIndexList);
        }
        // 按月份升序排序后返回
        electricDataList = elecDataMap.values().stream()
                .sorted(Comparator.comparing(ElectricIndexList::getDateMonth))
                .collect(Collectors.toList());
        return  electricDataList;
    }
    // 从timeRangeList中获取指定站点+月份的时间范围
    private MonthlyTimeRange getSiteRangeByMonth(List<MonthlyTimeRange> rangeList, String siteId, String month) {
        return rangeList.stream()
                .filter(r -> siteId.equals(r.getSiteId()) && month.equals(r.getMonth()))
                .findFirst() .orElse(null);
    }


    @Override
    public List<SiteMonitorDataVo> getSevenChargeData(DateSearchRequest requestVo) {
        String siteId = requestVo.getSiteId();

        // 默认时间-7天
        dealRequestTime(requestVo);
        Date startDate = requestVo.getStartDate();
        Date endDate = requestVo.getEndDate();
        // 七天放电数据统计
        List<SiteMonitorDataVo> siteMonitorDataVoList = emsDailyChargeDataMapper.getSingleSiteChargeData(siteId,startDate,endDate);
        return siteMonitorDataVoList;
    }

    // 统计入参时间处理
    public void dealRequestTime(DateSearchRequest requestVo){

        Date startDate = requestVo.getStartDate();
        Date endDate = requestVo.getEndDate();
        if (startDate == null && endDate == null) {
            // 如果没有传时间，默认从今天往前7天
            LocalDate sevenDaysAgo = LocalDate.now().minusDays(6);
            startDate = DateUtils.toDate(sevenDaysAgo);
            endDate = new Date();
            requestVo.setStartDate(startDate);
            requestVo.setEndDate(endDate);
        }
    }
}
