package com.yeejoin.amos.boot.module.hygf.biz.service.impl;

import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.*;

import com.alibaba.fastjson.JSONObject;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yeejoin.amos.boot.module.hygf.api.config.UserLimits;
import com.yeejoin.amos.boot.module.hygf.api.dto.JpInverterDtoNew;
import com.yeejoin.amos.boot.module.hygf.api.entity.TdHYGFInverterDayGenerate;
import com.yeejoin.amos.boot.module.hygf.api.entity.TdHYGFInverterMonthGenerate;
import com.yeejoin.amos.boot.module.hygf.api.entity.TdHYGFInverterYearGenerate;
import com.yeejoin.amos.boot.module.hygf.api.entity.TdHYGFInverterTotalGenerate;
import com.yeejoin.amos.boot.module.hygf.api.tdenginemapper.TdHYGFInverterDayGenerateMapper;
import com.yeejoin.amos.boot.module.hygf.api.tdenginemapper.TdHYGFInverterMonthGenerateMapper;
import com.yeejoin.amos.boot.module.hygf.api.tdenginemapper.TdHYGFInverterYearGenerateMapper;
import com.yeejoin.amos.boot.module.hygf.api.tdenginemapper.TdHYGFInverterMonthGenerateMapper;
import com.yeejoin.amos.boot.module.hygf.api.tdenginemapper.TdHYGFInverterYearGenerateMapper;
import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.module.hygf.api.dto.JpInverterDto;
import com.yeejoin.amos.boot.module.hygf.api.entity.JpInverter;
import com.yeejoin.amos.boot.module.hygf.api.mapper.JpInverterMapper;
import com.yeejoin.amos.boot.module.hygf.api.service.IJpInverterService;

/**
 * 户用光伏监盘逆变器表服务实现类
 *
 * @author system_generator
 * @date 2023-09-19
 */
@Service
public class JpInverterServiceImpl extends BaseService<JpInverterDto, JpInverter, JpInverterMapper>
        implements IJpInverterService {
    @Autowired
    TdHYGFInverterDayGenerateMapper tdHYGFInverterDayGenerateMapper;
    @Autowired
    TdHYGFInverterMonthGenerateMapper tdHYGFInverterMonthGenerateMapper;
    @Autowired
    TdHYGFInverterYearGenerateMapper tdHYGFInverterYearGenerateMapper;

    @Autowired
    JpInverterMapper jpInverterMapper;

    /**
     * 分页查询
     */
    public Page<JpInverterDto> queryForJpInverterPage(Page<JpInverterDto> page, JpInverterDto jpInverterDto) {
        Page<JpInverter> entiryPage = new Page<>(page.getCurrent(), page.getSize());
        LambdaQueryWrapper<JpInverter> wrapper = new LambdaQueryWrapper<>();
        if (jpInverterDto.getState() != null) {
            wrapper.eq(JpInverter::getState, jpInverterDto.getState());
        }
        if (StringUtils.isNotEmpty(jpInverterDto.getSnCode())) {
            wrapper.like(JpInverter::getSnCode, jpInverterDto.getSnCode());
        }
        if (!jpInverterDto.getStationIds().isEmpty()) {
            wrapper.in(JpInverter::getThirdStationId, jpInverterDto.getStationIds());
        }
        wrapper.orderByDesc(JpInverter::getUpdateTime);
        entiryPage = (Page<JpInverter>) this.page(entiryPage, wrapper);
        if (!ValidationUtil.isEmpty(entiryPage.getRecords())) {
            page.setTotal(entiryPage.getTotal());
            page.setPages(entiryPage.getPages());
            page.setCurrent(entiryPage.getCurrent());
            page.setSize(entiryPage.getSize());

            if (!ValidationUtil.isEmpty(entiryPage.getRecords()))
                page.setRecords(Bean.toModels(entiryPage.getRecords(), this.getModelClass()));
        }
        return page;
    }

    /**
     * 列表查询 示例
     */
    public List<JpInverterDto> queryForJpInverterList() {
        return this.queryForList("", false);
    }

    @UserLimits
    public List<JpInverterDtoNew> selectPageData(JpInverterDto jpInverterDto, int current, int size) {
        return this.getBaseMapper().selectPageData(jpInverterDto, current, size);
    }

    @UserLimits
    public long selectPageDataTota(JpInverterDto jpInverterDto) {
        return this.getBaseMapper().selectPageDataTotal(jpInverterDto);
    }

	public Map<String,Object> selectDayTrend(List<JSONObject>treeParams, String time, String snCode, String thirdStationId) {
        List<String> key = new ArrayList<>();
        treeParams.forEach(a->{
            if (a.get("key").toString().startsWith("acc")||a.get("key").toString().startsWith("acv")||a.get("key").toString().startsWith("pv")){
                key.add(a.get("key").toString().replace("_",""));
            }else {
                key.add(a.get("key").toString());
            }
        });
		List<Map<String,Object>> tdHYGFInverterDayGenerates = tdHYGFInverterDayGenerateMapper.selectDayTrend(key, time, snCode, thirdStationId);
        List<String> zData = new ArrayList<>();
        tdHYGFInverterDayGenerates.forEach(e->zData.add(e.get("workstatus").toString()) );
		Set<String> xData = new TreeSet<>();
		for (JSONObject treeParam : treeParams) {
			List<String> value = new ArrayList<>();
			for (Map<String, Object> obj : tdHYGFInverterDayGenerates) {
				xData.add(obj.get("time").toString().substring(0,obj.get("time").toString().length()-4));
                String key1 = treeParam.get("key").toString();
                if (treeParam.get("key").toString().startsWith("acc")||treeParam.get("key").toString().startsWith("acv")||treeParam.get("key").toString().startsWith("pv")){
                    key1 =treeParam.get("key").toString().replace("_","");
                }				value.add(obj.get(key1).toString());
			}
			treeParam.put("data",value);
		}
		Map<String,Object> map = new HashMap<>();
		map.put("xData",xData);
		map.put("yData",treeParams);
		map.put("zData",zData);
		return map;
	}

    public Page<TdHYGFInverterDayGenerate> jpInverterDayReport(int current, int size, String time, List<String> sncodes, List<String> stationIds) {
        Page<TdHYGFInverterDayGenerate> tdHYGFInverterDayGeneratePage = new Page<>();
        Date date = DateUtil.parse(time, "yyyy-MM-dd");
        Date timeStart = DateUtils.dateAddHours(date, -8);
        Date tiemEnd = DateUtils.dateAddHours(date, 16);
        String startTime = DateUtil.format(timeStart, "yyyy-MM-dd HH:mm:ss");
        String endTime = DateUtil.format(tiemEnd, "yyyy-MM-dd HH:mm:ss");
        //String startTime = DateUtil.format(date, "yyyy-MM-dd") + "00:00:00";
        //String endTime = DateUtil.format(date, "yyyy-MM-dd") + "23:59:59";
        QueryWrapper queryWrapper = new QueryWrapper<TdHYGFInverterDayGenerate>()
                .ge("created_time", startTime)
                .le("created_time", endTime)
                .in("third_station_id", stationIds);
        ;
        if (CollectionUtil.isNotEmpty(sncodes)) {
            queryWrapper.in("sn_code", sncodes);
        }
        queryWrapper.orderByDesc("created_time");
        List<TdHYGFInverterDayGenerate> tdHYGFInverterDayGenerates = tdHYGFInverterDayGenerateMapper.selectList(queryWrapper);
        tdHYGFInverterDayGeneratePage.setTotal(tdHYGFInverterDayGenerates.size());
        tdHYGFInverterDayGeneratePage.setSize(size);
        tdHYGFInverterDayGeneratePage.setCurrent(current);
        tdHYGFInverterDayGenerates = tdHYGFInverterDayGenerates.stream().filter(tdHYGFInverterDayGenerate -> StringUtils.isNotBlank(tdHYGFInverterDayGenerate.getSnCode().trim())).collect(Collectors.toList());
        int total = tdHYGFInverterDayGenerates.size();
        if (total  < (current * size)){
            current = 1;
        }
        tdHYGFInverterDayGenerates = tdHYGFInverterDayGenerates.subList((current - 1) * size, current * size > tdHYGFInverterDayGenerates.size() ? tdHYGFInverterDayGenerates.size() : current * size);
        tdHYGFInverterDayGenerates.forEach(tdHYGFInverterDayGenerate -> {
            Date date1 = new Date(tdHYGFInverterDayGenerate.getCreatedTime());
            tdHYGFInverterDayGenerate.setCreatedTimeStr(DateUtil.format(date1, DatePattern.NORM_DATETIME_PATTERN));
            tdHYGFInverterDayGenerate.setTotalGen(tdHYGFInverterDayGenerate.getTotalGen() == null ? 0:Double.valueOf(String.format("%.3f",tdHYGFInverterDayGenerate.getTotalGen()/1000)));
        });
        tdHYGFInverterDayGeneratePage.setRecords(tdHYGFInverterDayGenerates);
        return tdHYGFInverterDayGeneratePage;
    }

    public List<TdHYGFInverterDayGenerate> jpInverterDayReportExport(String time, List<String> sncodes, List<String> stationIds) {
        Date date = DateUtil.parse(time, "yyyy-MM-dd");
        String startTime = DateUtil.format(date, "yyyy-MM-dd") + "00:00:00";
        String endTime = DateUtil.format(date, "yyyy-MM-dd") + "23:59:59";
        QueryWrapper queryWrapper = new QueryWrapper<TdHYGFInverterDayGenerate>()
                .ge("created_time", startTime)
                .le("created_time", endTime)
                .in("third_station_id", stationIds);
        if (CollectionUtil.isNotEmpty(sncodes)) {
            queryWrapper.in("sn_code", sncodes);
        }
        queryWrapper.orderByDesc("created_time");
        List<TdHYGFInverterDayGenerate> tdHYGFInverterDayGenerates = tdHYGFInverterDayGenerateMapper.selectList(queryWrapper);
        tdHYGFInverterDayGenerates = tdHYGFInverterDayGenerates.stream().filter(tdHYGFInverterDayGenerate -> StringUtils.isNotBlank(tdHYGFInverterDayGenerate.getSnCode().trim())).collect(Collectors.toList());
        tdHYGFInverterDayGenerates.forEach(tdHYGFInverterDayGenerate -> {
            Date date1 = new Date(tdHYGFInverterDayGenerate.getCreatedTime());
            tdHYGFInverterDayGenerate.setCreatedTimeStr(DateUtil.format(date1, DatePattern.NORM_DATETIME_PATTERN));
        });
        return tdHYGFInverterDayGenerates;
    }

    public Page<TdHYGFInverterMonthGenerate> jpInverterMonthReport(int current, int size, String time, List<String> sncodes, List<String> stationIds) {
        Page<TdHYGFInverterMonthGenerate> tdHYGFInverterMonthGeneratePage = new Page<>();
        QueryWrapper queryWrapper = new QueryWrapper<TdHYGFInverterMonthGenerate>()
                .eq("year_month", time)
                .in("third_station_id", stationIds);
        if (CollectionUtil.isNotEmpty(sncodes)) {
            queryWrapper.in("sn_code", sncodes);
        }
        queryWrapper.orderByDesc("day_time");
        List<TdHYGFInverterMonthGenerate> tdHYGFInverterMonthGenerates = tdHYGFInverterMonthGenerateMapper.selectList(queryWrapper);
        tdHYGFInverterMonthGeneratePage.setTotal(tdHYGFInverterMonthGenerates.size());
        tdHYGFInverterMonthGeneratePage.setSize(size);
        tdHYGFInverterMonthGeneratePage.setCurrent(current);
        tdHYGFInverterMonthGenerates = tdHYGFInverterMonthGenerates.stream().filter(tdHYGFInverterMonthGenerate -> StringUtils.isNotBlank(tdHYGFInverterMonthGenerate.getSnCode().trim())).collect(Collectors.toList());
        int total = tdHYGFInverterMonthGenerates.size();
        if (total  < (current * size)){
            current = 1;
        }
        tdHYGFInverterMonthGenerates = tdHYGFInverterMonthGenerates.subList((current - 1) * size, current * size > tdHYGFInverterMonthGenerates.size() ? tdHYGFInverterMonthGenerates.size() : current * size);
        tdHYGFInverterMonthGenerates.forEach(tdHYGFInverterMonthGenerate -> tdHYGFInverterMonthGenerate.setFullhour(Double.valueOf(String.format("%.2f",tdHYGFInverterMonthGenerate.getFullhour()))));
        tdHYGFInverterMonthGeneratePage.setRecords(tdHYGFInverterMonthGenerates);
        return tdHYGFInverterMonthGeneratePage;
    }

    public List<TdHYGFInverterMonthGenerate> jpInverterMonthReportExport( String time, List<String> sncodes, List<String> stationIds) {
        QueryWrapper queryWrapper = new QueryWrapper<TdHYGFInverterMonthGenerate>()
                .eq("year_month", time)
                .in("third_station_id", stationIds);
        if (CollectionUtil.isNotEmpty(sncodes)) {
            queryWrapper.in("sn_code", sncodes);
        }
        queryWrapper.orderByDesc("day_time");
        List<TdHYGFInverterMonthGenerate> tdHYGFInverterMonthGenerates = tdHYGFInverterMonthGenerateMapper.selectList(queryWrapper);
        tdHYGFInverterMonthGenerates = tdHYGFInverterMonthGenerates.stream().filter(tdHYGFInverterMonthGenerate -> StringUtils.isNotBlank(tdHYGFInverterMonthGenerate.getSnCode().trim())).collect(Collectors.toList());
        tdHYGFInverterMonthGenerates.forEach(tdHYGFInverterMonthGenerate -> tdHYGFInverterMonthGenerate.setFullhour(Double.valueOf(String.format("%.2f",tdHYGFInverterMonthGenerate.getFullhour()))));
        return tdHYGFInverterMonthGenerates;
    }

    public Page<TdHYGFInverterYearGenerate> jpInverterYearReport(int current, int size, String time, List<String> sncodes, List<String> stationIds) {
        Page<TdHYGFInverterYearGenerate> tdHYGFInverterYearGeneratePage = new Page<>();
        QueryWrapper queryWrapper = new QueryWrapper<TdHYGFInverterYearGenerate>()
                .eq("year", time)
                .in("third_station_id", stationIds);
        if (CollectionUtil.isNotEmpty(sncodes)) {
            queryWrapper.in("sn_code", sncodes);
        }
        queryWrapper.orderByDesc("month_time");
        List<TdHYGFInverterYearGenerate> tdHYGFInverterYearGenerates = tdHYGFInverterYearGenerateMapper.selectList(queryWrapper);
        tdHYGFInverterYearGeneratePage.setTotal(tdHYGFInverterYearGenerates.size());
        tdHYGFInverterYearGeneratePage.setSize(size);
        tdHYGFInverterYearGeneratePage.setCurrent(current);
        tdHYGFInverterYearGenerates = tdHYGFInverterYearGenerates.stream().filter(tdHYGFInverterYearGenerate -> StringUtils.isNotBlank(tdHYGFInverterYearGenerate.getSnCode().trim())).collect(Collectors.toList());
        int total = tdHYGFInverterYearGenerates.size();
        if (total  < (current * size)){
            current = 1;
        }
        tdHYGFInverterYearGenerates = tdHYGFInverterYearGenerates.subList((current - 1) * size, current * size > tdHYGFInverterYearGenerates.size() ? tdHYGFInverterYearGenerates.size() : current * size);
        tdHYGFInverterYearGenerates.forEach(tdHYGFInverterYearGenerate -> tdHYGFInverterYearGenerate.setFullhour(Double.valueOf(String.format("%.2f",tdHYGFInverterYearGenerate.getFullhour()))));
        tdHYGFInverterYearGeneratePage.setRecords(tdHYGFInverterYearGenerates);
        return tdHYGFInverterYearGeneratePage;
    }

    public List<TdHYGFInverterYearGenerate> jpInverterYearReportExport(String time, List<String> sncodes, List<String> stationIds) {
        QueryWrapper queryWrapper = new QueryWrapper<TdHYGFInverterYearGenerate>()
                .eq("year", time)
                .in("third_station_id", stationIds);
        if (CollectionUtil.isNotEmpty(sncodes)) {
            queryWrapper.in("sn_code", sncodes);
        }
        queryWrapper.orderByDesc("month_time");
        List<TdHYGFInverterYearGenerate> tdHYGFInverterYearGenerates = tdHYGFInverterYearGenerateMapper.selectList(queryWrapper);
        tdHYGFInverterYearGenerates = tdHYGFInverterYearGenerates.stream().filter(tdHYGFInverterYearGenerate -> StringUtils.isNotBlank(tdHYGFInverterYearGenerate.getSnCode().trim())).collect(Collectors.toList());
        tdHYGFInverterYearGenerates.forEach(tdHYGFInverterYearGenerate -> tdHYGFInverterYearGenerate.setFullhour(Double.valueOf(String.format("%.2f",tdHYGFInverterYearGenerate.getFullhour()))));
        return tdHYGFInverterYearGenerates;
    }
    public List<Map<String, String>> getInverterSncodes(List<String> stationIds) {
        List<Map<String, String>> result = new ArrayList<>();
        QueryWrapper queryWrapper = new QueryWrapper<JpInverter>()
                .in("third_station_id", stationIds);
        queryWrapper.orderByAsc("third_station_id");
        List<JpInverter> jpInverterList = jpInverterMapper.selectList(queryWrapper);
        for (int i = 0; i < jpInverterList.size(); i++) {
            JpInverter jpInverter = jpInverterList.get(i);
            Map<String, String> item = new HashMap<>();
            if (StringUtils.isNotBlank(jpInverter.getSnCode())) {
                item.put("name", jpInverter.getSnCode().trim());
                item.put("value", jpInverter.getSnCode().trim());
                result.add(item);
            }

        }
        return result;
    }

    public Map<String,Object> selectMonthTrend(String time, String snCode, String thirdStationId) {
        Set<String> xData = new TreeSet<>();
        List<String> value1 = new ArrayList<>();
        List<String> value2 = new ArrayList<>();
        List<Map<String, Object>> maps = tdHYGFInverterMonthGenerateMapper.selectMonthTrend(time, snCode, thirdStationId);
        for (Map<String, Object> map : maps) {
            xData.add(map.get("daytime").toString());
            value1.add(map.get("generate").toString());
            value2.add(map.get("fullhour") == null?"0":String.format("%.2f",Double.valueOf(map.get("fullhour").toString())));
        }
        List<Map<String, Object>> yData = new ArrayList<>();
        Map<String,Object> map = new HashMap<>();
        Map<String,Object> map1 = new HashMap<>();
        map1.put("name","发电量");
        map1.put("unit","kW");
        map1.put("data",value1);
        yData.add(map1);
        Map<String,Object> map2 = new HashMap<>();
        map2.put("name","满发小时数");
        map2.put("unit","h");
        map2.put("data",value2);
        yData.add(map2);
        map.put("xData",xData);
        map.put("yData",yData);
        return map;
    }

    public Map<String,Object> selectYearTrend(String time, String snCode, String thirdStationId) {
        Set<String> xData = new TreeSet<>();
        List<String> value1 = new ArrayList<>();
        List<String> value2 = new ArrayList<>();
        List<Map<String, Object>> maps = tdHYGFInverterYearGenerateMapper.selectYearTrend(time, snCode, thirdStationId);
        for (Map<String, Object> map : maps) {
            xData.add(map.get("daytime").toString());
            value1.add(map.get("generate").toString());
            value2.add(map.get("fullhour") == null?"0":String.format("%.2f",Double.valueOf(map.get("fullhour").toString())));
        }
        List<Map<String, Object>> yData = new ArrayList<>();
        Map<String,Object> map = new HashMap<>();
        Map<String,Object> map1 = new HashMap<>();
        map1.put("name","发电量");
        map1.put("unit","kW");
        map1.put("data",value1);
        yData.add(map1);
        Map<String,Object> map2 = new HashMap<>();
        map2.put("name","满发小时数");
        map2.put("unit","h");
        map2.put("data",value2);
        yData.add(map2);
        map.put("xData",xData);
        map.put("yData",yData);
        return map;
    }

    public Map<String,Object> selectTotalTrend(String time, String snCode, String thirdStationId) {
        Set<String> xData = new TreeSet<>();
        List<String> value1 = new ArrayList<>();
        List<String> value2 = new ArrayList<>();
        List<Map<String, Object>> maps = tdHYGFInverterYearGenerateMapper.selectTotalTrend(time, snCode, thirdStationId);
        for (Map<String, Object> map : maps) {
            xData.add(map.get("daytime").toString());
            value1.add(map.get("generate").toString());
            value2.add(map.get("fullhour") == null?"0":String.format("%.2f",Double.valueOf(map.get("fullhour").toString())));
        }
        List<Map<String, Object>> yData = new ArrayList<>();
        Map<String,Object> map = new HashMap<>();
        Map<String,Object> map1 = new HashMap<>();
        map1.put("name","发电量");
        map1.put("unit","kW");
        map1.put("data",value1);
        yData.add(map1);
        Map<String,Object> map2 = new HashMap<>();
        map2.put("name","满发小时数");
        map2.put("unit","h");
        map2.put("data",value2);
        yData.add(map2);
        map.put("xData",xData);
        map.put("yData",yData);
        return map;
    }


    public Map<String,Object> jpInverterTotal(String snCode, String thirdStationId, String time, String date) {
        if (date.equals("day")){
            Map<String, Object> map = tdHYGFInverterMonthGenerateMapper.selectMonthTotal(time, snCode, thirdStationId);
            map.put("fullhour",String.format("%.2f",Double.valueOf(map.get("fullhour").toString())));
            return map;
        }else if (date.equals("month")){
            Map<String, Object> map = tdHYGFInverterYearGenerateMapper.selectYearTotal(time, snCode, thirdStationId);
            map.put("fullhour",String.format("%.2f",Double.valueOf(map.get("fullhour").toString())));
            return map;
        }else if (date.equals("year")){
            List<TdHYGFInverterTotalGenerate> tdHYGFInverterTotalGenerates = tdHYGFInverterYearGenerateMapper.selectTotalSum(time, snCode, thirdStationId);

          if (CollectionUtil.isNotEmpty(tdHYGFInverterTotalGenerates)){
              TdHYGFInverterTotalGenerate tdHYGFInverterTotalGenerate = tdHYGFInverterTotalGenerates.get(0);

              Map<String, Object> map = Bean.BeantoMap(tdHYGFInverterTotalGenerate);
              map.put("fullhour",String.format("%.2f",Double.valueOf(map.get("fullhour").toString())));
              return map;
          }
            Map<String,Object> map = new  HashMap<>();
            map.put("fullhour",0);
            map.put("income",0);
            map.put("generate",0);
            return map;
        }else {
            List<TdHYGFInverterTotalGenerate> maps = tdHYGFInverterYearGenerateMapper.selectTotalSum(null, snCode, thirdStationId);
            double fullhour = maps.stream().mapToDouble(TdHYGFInverterTotalGenerate::getFullhour).sum();
            double income = maps.stream().filter(e->null != e.getIncome() ).mapToDouble(TdHYGFInverterTotalGenerate::getIncome).sum();
            double generate = maps.stream().mapToDouble(TdHYGFInverterTotalGenerate::getGenerate).sum();
            Map<String,Object> map = new  HashMap<>();
            map.put("fullhour",String.format("%.2f",fullhour));
            map.put("income",income);
            map.put("generate",generate);
            return map;
        }

    }
}