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

import cn.hutool.core.util.IdUtil;
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.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import org.apache.commons.compress.utils.Lists;
import org.springblade.common.cache.DictCache;
import org.springblade.common.enums.DictEnum;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.nh.excel.DeviceExcel;
import org.springblade.modules.nh.excel.PowerStationImport;
import org.springblade.modules.nh.factory.aiswei.constant.ContentType;
import org.springblade.modules.nh.factory.aiswei.constant.HttpHeader;
import org.springblade.modules.nh.factory.aiswei.util.HttpUtils;
import org.springblade.modules.nh.mapper.DeviceMapper;
import org.springblade.modules.nh.pojo.dto.DeviceDTO;
import org.springblade.modules.nh.pojo.dto.PowerStationPaymentTimeDTO;
import org.springblade.modules.nh.pojo.entity.*;
import org.springblade.modules.nh.pojo.vo.DeviceVO;
import org.springblade.modules.nh.pojo.vo.InverterDataVO;
import org.springblade.modules.nh.pojo.vo.MonitorInverterStatVO;
import org.springblade.modules.nh.service.*;
import org.springblade.modules.nh.wrapper.DeviceWrapper;
import org.springblade.modules.nh.wrapper.InverterDataWrapper;
import org.springblade.modules.nh.wrapper.MonitorInverterStatWrapper;
import org.springblade.modules.operation.pojo.vo.OperationSiteVO;
import org.springblade.modules.operation.service.impl.OperationSiteServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import scala.collection.mutable.StringBuilder;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 设备管理 服务实现类
 *
 * @author AlexWang
 * @since 2024-05-31
 */
@Service
@AllArgsConstructor
public class DeviceServiceImpl extends BaseServiceImpl<DeviceMapper, DeviceEntity> implements IDeviceService {

	private final IPowerStationService stationService;

	private final IInverterDataService inverterDataService;

	private final IMonitorInverterStatService monitorInverterStatService;

	private final IMonitorEntryStatService monitorEntryStatService;

	private final DeviceMsgService deviceMsgService;
	@Autowired
	OperationSiteServiceImpl siteService;
	@Override
	public IPage<DeviceVO> selectDevicePage(IPage<DeviceVO> page, DeviceVO device) {
		return page.setRecords(baseMapper.selectDevicePage(page, device));
	}

	@Override
	public List<DeviceEntity> listByPowerStation(PowerStationEntity powerStationEntity) {
		if(powerStationEntity==null || powerStationEntity.getId()==null) {
			return Lists.newArrayList();
		}
		LambdaQueryWrapper<DeviceEntity> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(DeviceEntity::getStationId,powerStationEntity.getId())
			.eq(DeviceEntity::getType,1)
			.isNotNull(DeviceEntity::getOutDeviceId);
		return list(queryWrapper);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateSn(Long id, String sn) {
		DeviceEntity device =this.getById(id);
		if(device==null) return;

		if(device.getSn().equals(sn)){
			return;
		}
		String contentMsg="修改"+device.getName()+" 设备S/N,原S/N:"+device.getSn()+",修改后S/N:"+sn;

		MonitorInverterStatEntity monitorInverterStat = monitorInverterStatService.getBySn(sn);

		LambdaUpdateWrapper<DeviceEntity> updateWrapper = new LambdaUpdateWrapper<>();
		updateWrapper.eq(DeviceEntity::getId,id)
			.set(DeviceEntity::getSn,sn);
		if(monitorInverterStat!=null) {
			updateWrapper
				.set(DeviceEntity::getOutStationId,monitorInverterStat.getOutStationId())
				.set(DeviceEntity::getOutDeviceId,monitorInverterStat.getOutInverterId());
		}
		this.update(updateWrapper);

		BladeUser user = AuthUtil.getUser();
        deviceMsgService.saveMsg(device.getStationId(),device.getId(),contentMsg,user.getUserName());

		if(1==device.getType()){
			LambdaUpdateWrapper<InverterDataEntity> inverterDataUpdateWrapper = new LambdaUpdateWrapper<>();
			inverterDataUpdateWrapper.eq(InverterDataEntity::getDeviceId,id)
				.set(InverterDataEntity::getSn,sn);
			inverterDataService.update(inverterDataUpdateWrapper);

			LambdaUpdateWrapper<PowerStationEntity> stationUpdateWrapper = new LambdaUpdateWrapper<>();
			stationUpdateWrapper.eq(PowerStationEntity::getId,device.getStationId());
				if(monitorInverterStat!=null){
					stationUpdateWrapper.set(PowerStationEntity::getOutStationId,monitorInverterStat.getOutStationId());
				}
			stationUpdateWrapper.set(PowerStationEntity::getSn,sn);
			stationService.update(stationUpdateWrapper);
		}

	}

	@Override
	public boolean updateGenDate(String id, String time) {

		PowerStationEntity entity = stationService.getById(id);
		if(StringUtil.isNotBlank(entity.getOutStationId())){
			LambdaUpdateWrapper<MonitorEntryStatEntity> statUpdateWrapper = new LambdaUpdateWrapper<>();
			statUpdateWrapper.in(MonitorEntryStatEntity::getOutStationId, Func.toStrList(entity.getOutStationId()))
				.set(MonitorEntryStatEntity::getFisGenerateTime,time);
			monitorEntryStatService.update(statUpdateWrapper);
		}

		LambdaUpdateWrapper<PowerStationEntity> stationUpdateWrapper = new LambdaUpdateWrapper<>();
		stationUpdateWrapper.eq(PowerStationEntity::getId,id)
			.set(PowerStationEntity::getStartGenDate,time);
		Map<String,String> querys  = Maps.newHashMap();
		querys.put("powerStationCode",entity.getStationCode());
		querys.put("time",time);
		Map<String, String> headers = Maps.newHashMap();
		headers.put(HttpHeader.HTTP_HEADER_CONTENT_TYPE, ContentType.CONTENT_TYPE_FORM);
		//同步户用系统
		try {

			HttpUtils.doPost("https://www.nhhyy.com/nhet/a","/main/redirect/updateFirstGenerationTime","",headers,querys,"");
		}catch (Exception e){
			log.error(e.getMessage());
		}

		return stationService.update(stationUpdateWrapper);
	}


	@Override
	public DeviceVO fillDetail(DeviceVO vo) {

		PowerStationEntity station = stationService.getById(vo.getStationId());
		vo.setStation(station);

		//获取外部逆变器的数据
		if(StringUtil.isNotBlank(vo.getOutDeviceId())){
			MonitorInverterStatEntity  inverterStat = monitorInverterStatService.realtimeDetail(vo.getOutDeviceId());
			if(inverterStat!=null){
				vo.setMonitorInverter(MonitorInverterStatWrapper.build().entityVO(inverterStat));
//				covertInverterData(vo.getInverterData(),vo.getMonitorInverter());
				inverterDataService.updateDataFromInverterStatByOutInverterId(vo.getOutDeviceId());
			}
		}

		//查询逆变器数据表数据
		LambdaQueryWrapper<InverterDataEntity> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(InverterDataEntity::getDeviceId,vo.getId());
		InverterDataEntity inverterDataEntity= inverterDataService.getOne(queryWrapper);

		if(inverterDataEntity!=null){
			vo.setInverterData(InverterDataWrapper.build().entityVO(inverterDataEntity));
		}

		return vo;
	}

	@Override
	public DeviceVO getDetail(Long id) {
		DeviceEntity entity = this.getById(id);

		if(entity==null) return null;

		return fillDetail(DeviceWrapper.build().entityVO(entity));

	}

	@Override
	public List<DeviceExcel> exportDevice(Wrapper<DeviceEntity> queryWrapper) {
		List<DeviceExcel> deviceList = baseMapper.exportDevice(queryWrapper);
		//deviceList.forEach(device -> {
		//	device.setTypeName(DictCache.getValue(DictEnum.YES_NO, Device.getType()));
		//});
		return deviceList;
	}

	@Override
	public DeviceEntity getInverterBySn(String sn) {
		LambdaQueryWrapper<DeviceEntity> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(DeviceEntity::getSn,sn)
			.eq(DeviceEntity::getType,1).eq(DeviceEntity::getIsDeleted,0).last("LIMIT 1");
		return this.getOne(queryWrapper);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public R syncDeviceData(DeviceDTO dto) {
		String  innerStationId = dto.getInnerStationId();
		if(StringUtil.isBlank(innerStationId)){
			return R.fail("设备关联的内部电站ID为空");
		}
		if(StringUtil.isBlank(dto.getOutDeviceId())){
			return R.fail("设备关联的外部设备ID为空");
		}

		LambdaQueryWrapper<DeviceEntity> deviceQueryWrapper = new LambdaQueryWrapper<>();
		deviceQueryWrapper.eq(DeviceEntity::getOutDeviceId,dto.getOutDeviceId())
			.or()
			.eq(DeviceEntity::getInnerDeviceId,dto.getInnerDeviceId());
		if(this.count(deviceQueryWrapper)>0){
			return R.fail("该设备已同步");
		}


		LambdaQueryWrapper<PowerStationEntity> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(PowerStationEntity::getInnerStationId,innerStationId);
		PowerStationEntity stationEntity = stationService.getOne(queryWrapper);
		if(stationEntity==null){
			return R.fail("设备关联的内部电站未同步");
		}

		LambdaQueryWrapper<DeviceEntity> queryWrapper2 = new LambdaQueryWrapper<>();
		queryWrapper2.eq(DeviceEntity::getInnerDeviceId,dto.getInnerDeviceId());
		if(this.count(queryWrapper2)>0){
			return R.fail("设备内部id重复，该电站已同步");
		}

		LambdaQueryWrapper<MonitorInverterStatEntity> queryWrapper3 = new LambdaQueryWrapper<>();
		queryWrapper3.eq(MonitorInverterStatEntity::getSn,dto.getSn());
		MonitorInverterStatEntity outInverter = monitorInverterStatService.getOne(queryWrapper3);

		DeviceEntity entity = Objects.requireNonNull(BeanUtil.copyProperties(dto, DeviceEntity.class));
		entity.setStationId(stationEntity.getId());
		entity.setOutStationId(null);
		if(outInverter!=null){
			entity.setOutDeviceId(outInverter.getOutInverterId());
		}else{
			entity.setOutDeviceId(null);
		}
		this.save(entity);

		try{
			//逆变器才有数据
			if(entity.getType()==1){
				InverterDataEntity dataEntity = Objects.requireNonNull(BeanUtil.copyProperties(dto, InverterDataEntity.class));
				dataEntity.setDeviceId(entity.getId());
				dataEntity.init();
				if(outInverter!=null){
					dataEntity.setOutDeviceId(outInverter.getOutInverterId());
					if(outInverter.getEtd()!=null){
						dataEntity.setEtd(BigDecimal.valueOf(outInverter.getEtd()));
					}
					if(outInverter.getEtm()!=null){
						dataEntity.setEtm(BigDecimal.valueOf(outInverter.getEtm()));
					}
					if(outInverter.getEty()!=null){
						dataEntity.setEty(BigDecimal.valueOf(outInverter.getEty()));
					}
					if(outInverter.getEto()!=null){
						dataEntity.setEto(BigDecimal.valueOf(outInverter.getEto()));
					}
					if (outInverter.getRealPower()!=null){
						dataEntity.setRealPower(BigDecimal.valueOf(outInverter.getRealPower()));
					}
				}
				inverterDataService.save(dataEntity);
			}
		}catch(Exception e){
			log.error("保存InverterData报错，{}",e);
		}


		return R.success("添加设备成功");
	}


	@Override
	@Transactional(rollbackFor = Exception.class)
	public R materialChangeCauseDeviceChange(List<DeviceDTO> list) {
		int m=0,n=0;
		List<String> ids = Lists.newArrayList();
		String inner_station_id=list.get(0).getInnerStationId();

		//删除系统原来的设备信息
		LambdaUpdateWrapper<DeviceEntity> updateWrapper1 = new LambdaUpdateWrapper<>();
		updateWrapper1.eq(DeviceEntity::getInnerStationId,inner_station_id)
			.set(DeviceEntity::getIsDeleted, BladeConstant.DB_IS_DELETED);
		update(updateWrapper1);

		String sn="";
		for(DeviceDTO dto:list){
			try{
				R r= syncDeviceData(dto);
				if(r.isSuccess()){
					m++;
					if(StringUtil.isNotBlank(dto.getSn())){
						sn=dto.getSn();
					}
				}else{
					n++;
					ids.add(dto.getInnerDeviceId());
				}
			}catch (Exception e){
				n++;
				ids.add(dto.getInnerDeviceId());
			}
		}
		if(StringUtil.isNotBlank(sn)){
			LambdaUpdateWrapper<PowerStationEntity> entityLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
			entityLambdaUpdateWrapper.eq(PowerStationEntity::getInnerStationId,inner_station_id);
			entityLambdaUpdateWrapper.set(PowerStationEntity::getSn,sn);
			stationService.update(entityLambdaUpdateWrapper);
		}
		if(n>0){
			StringBuilder sb = new StringBuilder("物料信息变更批量同步设备同步失败.");
			sb.append("成功："+m+"条；");
			sb.append("失败："+n+"条；");
			sb.append("失败的内部设备ID集合："+ JSON.toJSONString(ids));
			return R.fail(sb.toString());
		}else{
			return R.success("物料信息变更批量同步设备同步成功"+m+"条");
		}
	}

	@Override
	public List<DeviceMsgEntity> editSnMsg(String id) {
		LambdaQueryWrapper<DeviceMsgEntity> queryWrapper=new LambdaQueryWrapper<>();
		queryWrapper.eq(DeviceMsgEntity::getDeviceId,id);
		queryWrapper.orderByDesc(DeviceMsgEntity::getUpdateTime);
		return deviceMsgService.list(queryWrapper);
	}


	private void covertInverterData(InverterDataVO dataEntity, MonitorInverterStatVO outInverter){
		if(dataEntity==null || outInverter==null){
			return;
		}
		if(outInverter.getEtd()!=null){
			dataEntity.setEtd(BigDecimal.valueOf(outInverter.getEtd()));
		}
		if(outInverter.getEtm()!=null){
			dataEntity.setEtm(BigDecimal.valueOf(outInverter.getEtm()));
		}
		if(outInverter.getEty()!=null){
			dataEntity.setEty(BigDecimal.valueOf(outInverter.getEty()));
		}
		if(outInverter.getEto()!=null){
			dataEntity.setEto(BigDecimal.valueOf(outInverter.getEto()));
		}
		if(outInverter.getRealPower()!=null){
			dataEntity.setRealPower(BigDecimal.valueOf(outInverter.getRealPower()));
		}
		if(outInverter.getPac()!=null){
			dataEntity.setPac(BigDecimal.valueOf(outInverter.getPac()));
		}
		if(outInverter.getPwHour()!=null){
			dataEntity.setPwHour(BigDecimal.valueOf(outInverter.getPwHour()));
		}

	}

	@Override
	public void importPowerStation(List<PowerStationImport> list, Boolean isCovered) {
		int m=0,n=0;
		List<String> ids = org.apache.commons.compress.utils.Lists.newArrayList();
		List<OperationSiteVO> findSiteList =siteService.findSiteList();
		Map<String,OperationSiteVO> mapsite = findSiteList.stream().collect(Collectors.toMap(e -> e.getName().trim(), e -> e));

		for(PowerStationImport impo:list){
			try{
				LambdaQueryWrapper<PowerStationEntity> queryWrapper2 = new LambdaQueryWrapper<>();
				queryWrapper2.eq(PowerStationEntity::getStationCode,impo.getStationCode());
				if(stationService.count(queryWrapper2)>0){
					n++;
					continue;
				}
				String brand = DictCache.getKey(DictEnum.BRAND, impo.getBrand());
				PowerStationEntity entity = Objects.requireNonNull(BeanUtil.copyProperties(impo, PowerStationEntity.class));
				entity.init();
				entity.setInnerStationId(impo.getStationCode()+"736De");
				entity.setApplyStatus(1);
				entity.setStationName(entity.getOwnerName()+"的光伏电站");
				entity.setBrand(Integer.valueOf(brand));
				entity.setSource("2");
				if(mapsite.containsKey(entity.getOmProviderName().trim())) {
					OperationSiteVO site = mapsite.get(entity.getOmProviderName().trim());
					entity.setOmProviderId(site.getId());
				}else{
					entity.setOmProviderName("");
				}
				stationService.save(entity);

				String  innerStationId = entity.getInnerStationId();
				if(StringUtil.isNotBlank(impo.getNbqsn())){
					for(String nbqsn :impo.getNbqsn().split(",")){
						DeviceEntity device = new DeviceEntity();
						device.setStationId(entity.getId());
						device.setInnerStationId(innerStationId);
						device.setInnerDeviceId(IdUtil.randomUUID().replaceAll("-", ""));
						device.setOutStationId(null);
						device.setOutDeviceId(null);
						device.setType(1);
						device.setName("逆变器");
						device.setSn(nbqsn);
						device.setBarCode(nbqsn);
						device.setBrand(brand);
						this.save(device);

						InverterDataEntity dataEntity = new InverterDataEntity();
						dataEntity.setDeviceId(device.getId());
						dataEntity.setSn(nbqsn);
						dataEntity.setRealPower(impo.getActualCapacity());
						dataEntity.init();
						inverterDataService.save(dataEntity);
					}

				}
				if(StringUtil.isNotBlank(impo.getSn())){
					for(String sn :impo.getSn().split(",")){
						DeviceEntity device = new DeviceEntity();
						device.setStationId(entity.getId());
						device.setInnerStationId(innerStationId);
						device.setInnerDeviceId(IdUtil.randomUUID().replaceAll("-", ""));
						device.setOutStationId(null);
						device.setOutDeviceId(null);
						device.setType(2);
						device.setSn(sn);
						device.setName("通讯棒");
						device.setBarCode(sn);
						device.setBrand(brand);
						this.save(device);
					}
				}
				m++;

		}catch (Exception e){
				n++;
				ids.add(impo.getStationCode());
			}

		}

		if(n>0){
			StringBuilder sb = new StringBuilder("批量同步设备同步失败.");
			sb.append("成功："+m+"条；");
			sb.append("失败："+n+"条；");
			sb.append("失败的电站编码集合："+ JSON.toJSONString(ids));
			log.debug(sb.toString());
		}
	}

	public void editPaymentTime(PowerStationPaymentTimeDTO paymentTimeDTO){
		log.debug("editPaymentTime");
		Date date=DateUtil.parse(paymentTimeDTO.getPaymentTime(),"yyyy-MM-dd");
		Calendar calendar=Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.YEAR,1);
		Date warrantyExpiresTime=calendar.getTime();  //一年后的时间
		LambdaUpdateWrapper<PowerStationEntity> stationUpdateWrapper = new LambdaUpdateWrapper<>();
		stationUpdateWrapper.eq(PowerStationEntity::getInnerStationId,paymentTimeDTO.getInnerStationId())
			.set(PowerStationEntity::getPaymentTime,date)
			.set(PowerStationEntity::getWarrantyExpiresTime,warrantyExpiresTime);
		stationService.update(stationUpdateWrapper);
	}

}
