package org.springblade.modules.nh.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springblade.common.constant.NhConstants;
import org.springblade.common.enums.SysType;
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.StringUtil;
import org.springblade.modules.nh.excel.MonitorInverterStatExcel;
import org.springblade.modules.nh.factory.aiswei.dto.getinverterdatapagepro.GetInverterDataPageProR;
import org.springblade.modules.nh.factory.ginlong.GinlongApi;
import org.springblade.modules.nh.factory.ginlong.IRet;
import org.springblade.modules.nh.factory.ginlong.dto.inverterdetaillist.GetInverterDetailR;
import org.springblade.modules.nh.factory.goodwe.GoodweApi;
import org.springblade.modules.nh.factory.goodwe.GoodweRet;
import org.springblade.modules.nh.factory.goodwe.dto.getinventersmoredetailinfobysn.D;
import org.springblade.modules.nh.factory.goodwe.dto.getinventersmoredetailinfobysn.GetInventersMoreDetailInfoBySnResp;
import org.springblade.modules.nh.mapper.MonitorInverterStatMapper;
import org.springblade.modules.nh.pojo.dto.sync.InverterIdMap;
import org.springblade.modules.nh.pojo.entity.InverterUapEntity;
import org.springblade.modules.nh.pojo.entity.MonitorEntryStatEntity;
import org.springblade.modules.nh.pojo.entity.MonitorInverterStatEntity;
import org.springblade.modules.nh.pojo.vo.MonitorInverterStatVO;
import org.springblade.modules.nh.service.IInverterDataService;
import org.springblade.modules.nh.service.IMonitorInverterStatService;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 厂家逆变器表 服务实现类
 *
 * @author AlexWang
 * @since 2024-06-02
 */
@Slf4j
@Service
@AllArgsConstructor
public class MonitorInverterStatServiceImpl extends ServiceImpl<MonitorInverterStatMapper, MonitorInverterStatEntity> implements IMonitorInverterStatService {

	private final GinlongApi ginlongApi;

	private final GoodweApi goodweApi;

	private final BladeRedis redis;

	@Override
	public IPage<MonitorInverterStatVO> selectMonitorInverterStatPage(IPage<MonitorInverterStatVO> page, MonitorInverterStatVO monitorInverterStat) {
		return page.setRecords(baseMapper.selectMonitorInverterStatPage(page, monitorInverterStat));
	}

	@Override
	public MonitorInverterStatEntity realtimeDetail(String outInverterId) {
		LambdaQueryWrapper<MonitorInverterStatEntity> queryWrapper2 = new LambdaQueryWrapper<>();
		queryWrapper2.eq(MonitorInverterStatEntity::getOutInverterId,outInverterId);
		MonitorInverterStatEntity inverterStat = this.getOne(queryWrapper2);
		if(inverterStat== null){
			return null;
		}
		if(NhConstants.SYS_TYPE_GINLONG.equals(inverterStat.getSysType())){
			IRet<GetInverterDetailR> ret =  ginlongApi.inverterDetail(inverterStat.getVendorIndex(),outInverterId,null);
			GetInverterDetailR r = ret.getData();
			if(r != null){
				extractedUpdateFields(NhConstants.SYS_TYPE_GINLONG,inverterStat,r,new HashSet<>());
				this.updateById(inverterStat);
			}

		}else if(NhConstants.SYS_TYPE_GOODWE.equals(inverterStat.getSysType())){
			String rediskey = "goodwe_inverter_"+inverterStat.getSn();
			GetInventersMoreDetailInfoBySnResp resp = redis.get(rediskey);
			if(resp==null){
				GoodweRet<GetInventersMoreDetailInfoBySnResp>  ret = goodweApi.getInventersDetailBySn(1,inverterStat.getSn());
				resp = ret.getData();
				if(resp!=null){
					redis.setEx(rediskey,resp,5*60L);
				}
			}
			if(resp!=null){
				convertGoodweInverterDetailResp(inverterStat,resp);
				this.updateById(inverterStat);
			}
		}

		return inverterStat;
	}

	@Override
	public List<MonitorInverterStatExcel> exportMonitorInverterStat(Wrapper<MonitorInverterStatEntity> queryWrapper) {
		List<MonitorInverterStatExcel> monitorInverterStatList = baseMapper.exportMonitorInverterStat(queryWrapper);
		//monitorInverterStatList.forEach(monitorInverterStat -> {
		//	monitorInverterStat.setTypeName(DictCache.getValue(DictEnum.YES_NO, MonitorInverterStat.getType()));
		//});
		return monitorInverterStatList;
	}

	@Override
	public void syncInverterDetails(List<GetInverterDetailR> list, String sysType, Set<String> updateFields) {
		List<String> inverterIds = list.stream().map(GetInverterDetailR::getId).collect(Collectors.toList());
		List<InverterIdMap> inverterIdsMaps = this.baseMapper.findByInverterIds(inverterIds);
		Map<String, String> inverterId2LocalIdMap = inverterIdsMaps.stream().collect(Collectors.toMap(InverterIdMap::getOutInverterId, InverterIdMap::getId));

		List<GetInverterDetailR> updates = new ArrayList<>();
		for (GetInverterDetailR inverter : list) {
			String id = inverter.getId();
			if (inverterId2LocalIdMap.containsKey(id)) {
				updates.add(inverter);
			} else {
				MonitorInverterStatEntity stat = initNewInverterStat(sysType, inverter);
				stat.setVendorIndex(inverter.getVendorIndex());
				if (StringUtils.isBlank(inverter.getStationId())) {
					log.error("sync inverter detail error, sn:{}, sys_type:{}", inverter.getSn(), new SysType(sysType));
				} else {
					try{
						this.save(stat);
					}catch (Exception e){
						log.error("sync inverter detail error,this.save(stat) sn:{},e:{}", inverter.getSn(), e);
					}
				}
			}
		}

		if (!updates.isEmpty()) {
			List<MonitorInverterStatEntity> rs = Lists.newArrayList();
			for (GetInverterDetailR u : updates) {
				if(NhConstants.SYS_TYPE_SAJ.equals(sysType)
					&& u.getVendorIndex()==0){
					//三晶设备同步任务不更新
					continue;
				}
				MonitorInverterStatEntity r = new MonitorInverterStatEntity();
				r.setVendorIndex(u.getVendorIndex());
				Long inverterId = Long.parseLong(inverterId2LocalIdMap.get(u.getId()));
				r.setId(inverterId);
				r.setSn(u.getSn());// 逆变器sn

				r.setInverterId(inverterId);
				r.setOutInverterId(u.getId());// 外部逆变器id

				r.setOutStationId(u.getStationId());// 外部电站id
				if (StringUtils.isBlank(u.getStationId())) {
					continue;
				}
				if (updateFields.contains("sys_type") || updateFields.isEmpty()) {
					r.setSysType(sysType);
				}
				extractedUpdateFields(sysType , r, u, updateFields);

				rs.add(r);
			}

//			inverterDataService.syncFromSchedulerList(rs);
			boolean flag = this.updateBatchById(rs);

			log.info("逆变器 detail list updated flag is: {}", flag);
		}
	}

	@Override
	public MonitorInverterStatEntity initNewInverterStat(String sysType, GetInverterDetailR inverter) {
		MonitorInverterStatEntity stat = new MonitorInverterStatEntity();
		stat.setSn(inverter.getSn()); // 逆变器sn
		stat.setOutInverterId(inverter.getId()); // 外部逆变器id
		stat.setOutStationId(inverter.getStationId()); // 外部电站id
		stat.setEtd(UnitUtil.convEnergy(inverter.getEToday(), inverter.getETodayStr())); // 当日发电量
		stat.setEtm(UnitUtil.convEnergy(inverter.getEMonth(), inverter.getEMonthStr())); // 当月发电量
		stat.setEto(UnitUtil.convEnergy(inverter.getETotal(), inverter.getETotalStr())); // 累计发电量
		stat.setEty(UnitUtil.convEnergy(inverter.getEYear(), inverter.getEYearStr())); // 当年发电量
		stat.setCreateTime(new Date()); // 创建时间
		stat.setSyncTime(new Date(inverter.getDataTimestamp())); // 更新时间
		stat.setPac(UnitUtil.convPower(inverter.getPac(), inverter.getPacStr())); // 实时交流功率--有功功率
		stat.setPwHour(inverter.getFullHour()); // 发电小时数？（满发？）
		stat.setRealPower(UnitUtil.convPower(inverter.getPower(), inverter.getPowerStr())); // 实际安装功率？没什么用，可以考虑去掉
		stat.setPower(UnitUtil.convPower(inverter.getPower(), inverter.getPowerStr())); // 装机容量--锦浪有
		stat.setState(inverter.getState()); // 1.在线 2.离线，3.报警
		stat.setFullHour(inverter.getFullHour()); // 满发小时数
		stat.setFullHourStr(inverter.getFullHourStr()); // 满发小时数单位
		if (inverter.getUpdateShelfEndTime() != null) {
			stat.setUpdateShelfEndTime(new Date(inverter.getUpdateShelfEndTime())); // 质保结束时间
		}
		stat.setDcPac(UnitUtil.convVa(inverter.getDcPac(), inverter.getDcPacStr()));
		stat.setTemperature(inverter.getInverterTemperature());
		stat.setProductModel(inverter.getProductModel());
		stat.setApparentPower(inverter.getApparentPower());
		stat.setApparentPowerStr(inverter.getApparentPowerStr());
		stat.setReactivePower(inverter.getReactivePower());
		stat.setReactivePowerStr(inverter.getReactivePowerStr());
		stat.setName(inverter.getName());
		stat.setFac(UnitUtil.convHz(inverter.getFac(), inverter.getFacStr()));
		stat.setUpdateTime(new Date()); // 更新时间
		stat.setCollectorSn(inverter.getCollectorsn()); // 采集器sn
		stat.setModel(inverter.getModel());
		stat.setSysType(sysType);
		stat.setPowerFactor(inverter.getPowerFactor());
		stat.setFac(inverter.getFac());

		String pvModules = assemblePvModules(inverter,sysType);
		stat.setPvModules(pvModules);
		String acModules = assembleRSTModules(inverter,sysType);
		stat.setAcModules(acModules);
		return stat;
	}

	private void extractedUpdateFields(String sysType,MonitorInverterStatEntity r, GetInverterDetailR u,Set<String> updateFields) {
		if (updateFields.contains("etd") || updateFields.isEmpty()) {
			r.setEtd(UnitUtil.convEnergy(u.getEToday(), u.getETodayStr()));// 当日发电量
		}
		if (updateFields.contains("etm") || updateFields.isEmpty()) {
			r.setEtm(UnitUtil.convEnergy(u.getEMonth(), u.getEMonthStr()));// 当月发电量
		}
		if (updateFields.contains("eto") || updateFields.isEmpty()) {
			r.setEto(UnitUtil.convEnergy(u.getETotal(), u.getETotalStr()));
		}
		if (updateFields.contains("ety") || updateFields.isEmpty()) {
			r.setEty(UnitUtil.convEnergy(u.getEYear(), u.getEYearStr()));
		}
		if (updateFields.contains("sync_time") || updateFields.isEmpty()) {
			r.setSyncTime(new Date(u.getDataTimestamp()));
		}
		if (updateFields.contains("pac") || updateFields.isEmpty()) {
			r.setPac(UnitUtil.convPower(u.getPac(), u.getPacStr()));
		}
		if (updateFields.contains("pw_hour") || updateFields.isEmpty()) {
			r.setPwHour(u.getFullHour());
		}
		if (updateFields.contains("real_power") || updateFields.isEmpty()) {
			r.setRealPower(UnitUtil.convPower(u.getPower(), u.getPowerStr()));
		}
		if (updateFields.contains("power") || updateFields.isEmpty()) {
			r.setPower(UnitUtil.convPower(u.getPower(), u.getPowerStr()));
		}
		if (updateFields.contains("state") || updateFields.isEmpty()) {
			r.setState(u.getState());
		}
		if (updateFields.contains("full_hour") || updateFields.isEmpty()) {
			r.setFullHour(u.getFullHour());// 满发小时数
		}
		if (updateFields.contains("full_hour_str") || updateFields.isEmpty()) {
			r.setFullHourStr(u.getFullHourStr());// 满发小时数单位
		}
		if (u.getUpdateShelfEndTime() != null) {
			r.setUpdateShelfEndTime(new Date(u.getUpdateShelfEndTime()));// 质保结束时间
		}
		if (updateFields.contains("dc_pac") || updateFields.isEmpty()) { // goodwe 是计算出来的,通过 trySyncGoodweInverterStat 方法更新的，aiswei似乎没办法拿到
			r.setDcPac(UnitUtil.convVa(u.getDcPac(), u.getDcPacStr()));// 逆变器总直流输入功率，锦浪有该字段，且单位为VA,W和 VA是一回事吗？
		}
		if (updateFields.contains("fac") || updateFields.isEmpty()) {
			r.setFac(UnitUtil.convHz(u.getFac(), u.getFacStr()));
		}
		r.setUpdateTime(new Date());
		if (updateFields.contains("model") || updateFields.isEmpty()) {
			r.setModel(u.getModel());
		}
		if (updateFields.contains("temperature") || updateFields.isEmpty()) {
			r.setTemperature(u.getInverterTemperature());
		}
		if (updateFields.contains("name") || updateFields.isEmpty()) {
			r.setName(u.getName());
		}
		if (updateFields.contains("reactive_power") || updateFields.isEmpty()) {
			r.setReactivePower(u.getReactivePower());
		}
		if (updateFields.contains("reactive_power_str") || updateFields.isEmpty()) {
			r.setReactivePowerStr(u.getReactivePowerStr());
		}
		if (updateFields.contains("apparent_power") || updateFields.isEmpty()) {
			r.setApparentPower(u.getApparentPower());
		}
		if (updateFields.contains("apparent_power_str") || updateFields.isEmpty()) {
			r.setApparentPowerStr(u.getApparentPowerStr());
		}
		if (updateFields.contains("product_model") || updateFields.isEmpty()) {
			r.setProductModel(u.getProductModel());
		}

		if (updateFields.contains("collector_sn") || updateFields.isEmpty()) {
			r.setCollectorSn(u.getCollectorsn());
		}

		if (updateFields.contains("power_factor") || updateFields.isEmpty()) {
			r.setPowerFactor(u.getPowerFactor());
		}

		if (updateFields.contains("fac") || updateFields.isEmpty()) {
			r.setFac(u.getFac());
		}

		String pvModules = assemblePvModules(u,sysType);
		r.setPvModules(pvModules);
		String acModules = assembleRSTModules(u,sysType);
		r.setAcModules(acModules);
	}

	@Override
	public MonitorInverterStatEntity getBySn(String sn) {
		if(StringUtil.isBlank(sn))
		return null;
		LambdaQueryWrapper<MonitorInverterStatEntity> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(MonitorInverterStatEntity::getSn,sn);
		if(count(queryWrapper)>1){
			return null;
		}
		return getOne(queryWrapper);
	}

	@Override
	public List<String> getSnsByStation(String outStationId) {
		LambdaQueryWrapper<MonitorInverterStatEntity> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(MonitorInverterStatEntity::getOutStationId, outStationId)
			.select(MonitorInverterStatEntity::getSn);
		List<String> snList = this.listObjs(queryWrapper);
		return snList;
	}

	@Override
	public List<String> getInverterSns(String sysType) {
		return this.baseMapper.getInverterSns(sysType);
	}
	@Override
	public List<String> getInverterSns(String sysType,int index) {
		return this.baseMapper.getInverterSnsByIndex(sysType,index);
	}

	private String assemblePvModules(GetInverterDetailR detail,String sysType){
		InverterUapEntity pvUap = new InverterUapEntity();
		pvUap.setCreateTime(new Date());
		pvUap.setSn(detail.getSn()); // 逆变器sn
		pvUap.setOutInverterId(detail.getId()); // 外部逆变器id
		pvUap.setOutStationId(detail.getStationId()); // 外部电站id
		pvUap.setSysType(sysType);
		pvUap.setType(NhConstants.UAP_TYPE_DC);
		pvUap.setStateTime(CommonUtil.getNowHour());

		List<String> list = Lists.newArrayList();
		for(int i=1;i<=16;i++){
			Object iPvObj = CommonUtil.reflectGetField(detail,"iPv"+i);
			Object uPvObj = CommonUtil.reflectGetField(detail,"uPv"+i);
			if(iPvObj==null||uPvObj==null){
				break;
			}
			if(iPvObj.equals(0d) && uPvObj.equals(0d)){
				break;
			}
			try{
				CommonUtil.reflectSetField(pvUap,"uv"+i,uPvObj);
				CommonUtil.reflectSetField(pvUap,"ia"+i,iPvObj);
				CommonUtil.reflectSetField(pvUap,"p"+i,(Double)uPvObj*(Double)iPvObj);
			}catch (Exception e){

			}
			list.add(uPvObj+":"+iPvObj);
		}

		sendInverterDataToRedis(pvUap);
		return String.join("|", list);
	}

	private String assembleRSTModules(GetInverterDetailR detail,String sysType){
		InverterUapEntity pvUap = new InverterUapEntity();
		pvUap.setCreateTime(new Date());
		pvUap.setSn(detail.getSn()); // 逆变器sn
		pvUap.setOutInverterId(detail.getId()); // 外部逆变器id
		pvUap.setOutStationId(detail.getStationId()); // 外部电站id
		pvUap.setSysType(sysType);
		pvUap.setType(NhConstants.UAP_TYPE_AC);
		pvUap.setStateTime(CommonUtil.getNowHour());

		List<String> list = Lists.newArrayList();
		for(int i=1;i<=3;i++){
			Object iPvObj = CommonUtil.reflectGetField(detail,"iAc"+i);
			Object uPvObj = CommonUtil.reflectGetField(detail,"uAc"+i);
			if(iPvObj==null||uPvObj==null){
				break;
			}
			if(iPvObj.equals(0d) && uPvObj.equals(0d)){
				break;
			}
			try{
				CommonUtil.reflectSetField(pvUap,"uv"+i,uPvObj);
				CommonUtil.reflectSetField(pvUap,"ia"+i,iPvObj);
				CommonUtil.reflectSetField(pvUap,"p"+i,(Double)uPvObj*(Double)iPvObj);
			}catch (Exception e){

			}
			list.add(uPvObj+":"+iPvObj);
		}
		sendInverterDataToRedis(pvUap);
		return String.join("|", list);
	}

	private void sendInverterDataToRedis(InverterUapEntity pvUap){
		// 获取当前日期和时间
		LocalDateTime now = LocalDateTime.now();
		if(now.getHour()>=8 && now.getHour()<18){
			redis.sAdd(NhConstants.UAP_LIST_TEMP_KEY, pvUap);
		}
	}

	private void convertGoodweInverterDetailResp(MonitorInverterStatEntity stat,GetInventersMoreDetailInfoBySnResp inverter){

		if(inverter==null) return;

		stat.setEtd(inverter.getEday()); // 当日发电量
//		stat.setEtm(UnitUtil.convEnergy(inverter.getEMonth(), inverter.getEMonthStr())); // 当月发电量
		stat.setEto(inverter.getEtotal()); // 累计发电量
//		stat.setEty(UnitUtil.convEnergy(inverter.getEYear(), inverter.getEYearStr())); // 当年发电量
		stat.setSyncTime(new Date()); // 更新时间
		stat.setPac(inverter.getOut_pac()); // 实时交流功率--有功功率
//		stat.setPwHour(inverter.getFullHour()); // 发电小时数？（满发？）
		stat.setRealPower(inverter.getCapacity()); // 实际安装功率？没什么用，可以考虑去掉
		stat.setPower(inverter.getCapacity()); // 装机容量--锦浪有
		stat.setState(inverter.getStatus()); // 1.在线 2.离线，3.报警
//		stat.setFullHour(inverter.getFullHour()); // 满发小时数
//		stat.setFullHourStr(inverter.getFullHourStr()); // 满发小时数单位
//		if (inverter.getUpdateShelfEndTime() != null) {
//			stat.setUpdateShelfEndTime(new Date(inverter.getUpdateShelfEndTime())); // 质保结束时间
//		}
//		stat.setDcPac(UnitUtil.convVa(inverter.getDcPac(), inverter.getDcPacStr()));
		stat.setTemperature(inverter.getTempperature());
//		stat.setProductModel(inverter.getProductModel());
//		stat.setApparentPower(inverter.getApparentPower());
//		stat.setApparentPowerStr(inverter.getApparentPowerStr());
//		stat.setReactivePower(inverter.getReactivePower());
//		stat.setReactivePowerStr(inverter.getReactivePowerStr());
		stat.setName(inverter.getName());
//		stat.setFac(UnitUtil.convHz(inverter.getFac(), inverter.getFacStr()));
		stat.setUpdateTime(new Date()); // 更新时间
//		stat.setCollectorSn(inverter.getCollectorsn()); // 采集器sn
//		stat.setModel(inverter.getModel());
//		stat.setSysType(sysType);
//		stat.setPowerFactor(inverter.getPowerFactor());
//		stat.setFac(inverter.getFac());

		D d = inverter.getD();
		stat.setPac(UnitUtil.convPower(d.getPac(), "w"));

		String pvModules = CommonUtil.assembleIUData("vpv","ipv",12,d);
		stat.setPvModules(pvModules);
		String acModules = CommonUtil.assembleIUData("vac","iac",3,d);
		stat.setAcModules(acModules);

	}


	//	public static void main(String[] args) {
//		GetInverterDetailR  r = new GetInverterDetailR();
//		for(int i=1;i<10;i++){
//			CommonUtil.reflectSetField(r,"iPv"+i,10d+i);
//			CommonUtil.reflectSetField(r,"uPv"+i,200d+i);
//		}
//		System.out.println(JSON.toJSONString(r));
//		System.out.println(assemblePvModules(r));
//	}
}
