/**
 * BladeX Commercial License Agreement
 * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
 * <p>
 * Use of this software is governed by the Commercial License Agreement
 * obtained after purchasing a license from BladeX.
 * <p>
 * 1. This software is for development use only under a valid license
 * from BladeX.
 * <p>
 * 2. Redistribution of this software's source code to any third party
 * without a commercial license is strictly prohibited.
 * <p>
 * 3. Licensees may copyright their own code but cannot use segments
 * from this software for such purposes. Copyright of this software
 * remains with BladeX.
 * <p>
 * Using this software signifies agreement to this License, and the software
 * must not be used for illegal purposes.
 * <p>
 * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
 * not liable for any claims arising from secondary or illegal development.
 * <p>
 * Author: Chill Zhuang (bladejava@qq.com)
 */
package org.springblade.modules.nh.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.AllArgsConstructor;
import org.apache.commons.compress.utils.Lists;
import org.springblade.common.utils.CommonUtil;
import org.springblade.common.utils.UnitUtil;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.tool.utils.CollectionUtil;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.modules.nh.pojo.dto.sync.DayEnergyDTO;
import org.springblade.modules.nh.pojo.entity.MonitorEntryMonthStatEntity;
import org.springblade.modules.nh.pojo.entity.MonitorEntryYearStatEntity;
import org.springblade.modules.nh.pojo.vo.MonitorEntryMonthStatVO;
import org.springblade.modules.nh.excel.MonitorEntryMonthStatExcel;
import org.springblade.modules.nh.mapper.MonitorEntryMonthStatMapper;
import org.springblade.modules.nh.service.IMonitorEntryMonthStatService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.util.*;

/**
 * 电站月统计数据 服务实现类
 *
 * @author AlexWang
 * @since 2024-06-02
 */
@Service
@AllArgsConstructor
public class MonitorEntryMonthStatServiceImpl extends ServiceImpl<MonitorEntryMonthStatMapper, MonitorEntryMonthStatEntity> implements IMonitorEntryMonthStatService {

	private final BladeRedis bladeRedis;

	@Override
	public IPage<MonitorEntryMonthStatVO> selectMonitorEntryMonthStatPage(IPage<MonitorEntryMonthStatVO> page, MonitorEntryMonthStatVO monitorEntryMonthStat) {
		return page.setRecords(baseMapper.selectMonitorEntryMonthStatPage(page, monitorEntryMonthStat));
	}

	@Override
	public List<Map<String, Object>> overviewLastDays(String outStationIds, Integer days) {
		if(days==null) {
			days=3;
		}
		List<String> ids = CommonUtil.splitOutStationIds(outStationIds);
		if(CollectionUtil.isEmpty(ids))
			return null;

		List<Map<String, Object>> list = this.baseMapper.overviewLastDays(ids,days);
		Date now = new Date();
		for(int i=1;i<=days;i++){
			String key = DateUtil.format(DateUtil.minusDays(now,i),"yyyy-MM-dd");
			boolean hasFlag = false;
			for(Map<String, Object> map:list){
				if(map.get("day").equals(key)){
					hasFlag = true;
				}
			}
			if(!hasFlag){
				Map<String, Object> map0= new HashMap<>();
				map0.put("day",key);
				map0.put("energy",0);
				list.add(map0);
			}
		}

		// 根据"age"键的值对列表进行排序
		Collections.sort(list, new Comparator<Map<String, Object>>() {
			@Override
			public int compare(Map<String, Object> o1, Map<String, Object> o2) {
				// 确保比较的值是Integer类型
				String day1 = (String) o1.get("day");
				String day2 = (String) o2.get("day");
				return day1.compareTo(day2);
			}
		});




		return list;
	}

	@Override
	public List<MonitorEntryMonthStatExcel> exportMonitorEntryMonthStat(Wrapper<MonitorEntryMonthStatEntity> queryWrapper) {
		List<MonitorEntryMonthStatExcel> monitorEntryMonthStatList = baseMapper.exportMonitorEntryMonthStat(queryWrapper);
		//monitorEntryMonthStatList.forEach(monitorEntryMonthStat -> {
		//	monitorEntryMonthStat.setTypeName(DictCache.getValue(DictEnum.YES_NO, MonitorEntryMonthStat.getType()));
		//});
		return monitorEntryMonthStatList;
	}

	@Override
	public void syncMonthStatData(List<DayEnergyDTO> dayEnergyList) {
		if(CollectionUtil.isEmpty(dayEnergyList)) return;

		List<MonitorEntryMonthStatEntity> list = Lists.newArrayList();

		for (DayEnergyDTO item : dayEnergyList) {
			Date now = new Date();
			double energy = UnitUtil.convEnergy(item.getValue(), item.getUnit());
			MonitorEntryMonthStatEntity entity = new MonitorEntryMonthStatEntity();
			entity.setOutStationId(item.getStationId());
			entity.setStatDate(DateUtil.parse(item.getDate(),"yyyy-MM-dd"));
			entity.setCreateTime(now);
			entity.setUpdateTime(now);
			entity.setEnergy(energy);

			LambdaQueryWrapper<MonitorEntryMonthStatEntity> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.eq(MonitorEntryMonthStatEntity::getStatDate,entity.getStatDate())
				.eq(MonitorEntryMonthStatEntity::getOutStationId,entity.getOutStationId());
			List<MonitorEntryMonthStatEntity> tempList =this.list(queryWrapper);
			if(CollectionUtil.isEmpty(tempList)){
				list.add(entity);
			}else{
				MonitorEntryMonthStatEntity entity1 = tempList.get(0);
				LambdaUpdateWrapper<MonitorEntryMonthStatEntity> updateWrapper2=new LambdaUpdateWrapper<>();
				updateWrapper2.eq(MonitorEntryMonthStatEntity::getId,entity1.getId())
					.set(MonitorEntryMonthStatEntity::getEnergy,energy)
					.set(MonitorEntryMonthStatEntity::getUpdateTime,now);
				this.update(updateWrapper2);

			}

		}
		this.saveBatch(list,100);



	}

	@Override
	public Double sumEnergy(List<String> outStationIds, Date startDate, Date endDate) {
		Double result = this.baseMapper.sumEnergy(outStationIds,startDate,endDate);
		return result!=null?result:0.0;
	}

	@Override
	public Double getYesterdayEnergy(String outStationId) {
		String STATION_YESTERDAY_ENERGY = "STATION_YESTERDAY_ENERGY";
		String STATION_YESTERDAY_ENERGY_TIME = "STATION_YESTERDAY_ENERGY_OUT_TIME";

		if(CommonUtil.isOutTime(bladeRedis.get(STATION_YESTERDAY_ENERGY_TIME),6*60)){
			bladeRedis.del(STATION_YESTERDAY_ENERGY);
			Date yesterday = DateUtil.minusDays(DateUtil.now(),1);
			LambdaQueryWrapper<MonitorEntryMonthStatEntity> monthQuery = new LambdaQueryWrapper<>();
			monthQuery.eq(MonitorEntryMonthStatEntity::getStatDate,DateUtil.format(yesterday,"yyyy-MM-dd"));
			List<MonitorEntryMonthStatEntity> totallist = list(monthQuery);
			for(MonitorEntryMonthStatEntity item:totallist){
				bladeRedis.hSet(STATION_YESTERDAY_ENERGY,item.getOutStationId(),item.getEnergy());
			}
			bladeRedis.set(STATION_YESTERDAY_ENERGY_TIME,System.currentTimeMillis());
		}
		return bladeRedis.hGet(STATION_YESTERDAY_ENERGY,outStationId);
	}

	@Override
	public MonitorEntryMonthStatEntity getFirstEnergyDay(String outStationId) {
		LambdaQueryWrapper<MonitorEntryMonthStatEntity> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(MonitorEntryMonthStatEntity::getOutStationId,outStationId)
			.gt(MonitorEntryMonthStatEntity::getEnergy,0)
			.orderByAsc(MonitorEntryMonthStatEntity::getStatDate)
			.last("limit 1");
		return this.getOne(queryWrapper);
	}
}
