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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.springblade.common.cache.DictCache;
import org.springblade.common.constant.MonitorConstants;
import org.springblade.common.constant.NhConstants;
import org.springblade.common.enums.DictEnum;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.mp.support.Condition;
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.utils.BeanUtil;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.nh.factory.aiswei.constant.Constants;
import org.springblade.modules.nh.factory.ginlong.dto.alarmlist.GetAlarmListR;
import org.springblade.modules.nh.pojo.dto.sync.InverterRecoverDTO;
import org.springblade.modules.nh.pojo.entity.MonitorEntryStatEntity;
import org.springblade.modules.order.pojo.entity.OperationOrderOperationInfoEntity;
import org.springblade.modules.order.service.impl.OperationOrderOperationInfoServiceImpl;
import org.springblade.modules.order.service.impl.OperationOrderServiceImpl;
import org.springblade.modules.nh.pojo.entity.AlarmInfoEntity;
import org.springblade.modules.nh.pojo.entity.PowerStationEntity;
import org.springblade.modules.order.constant.OrderConstants;
import org.springblade.modules.order.pojo.entity.OperationOrderEntity;
import org.springblade.modules.nh.pojo.vo.AlarmInfoVO;
import org.springblade.modules.nh.excel.AlarmInfoExcel;
import org.springblade.modules.nh.mapper.AlarmInfoMapper;
import org.springblade.modules.nh.pojo.vo.OverviewStaticDataVo;
import org.springblade.modules.nh.service.IAlarmInfoService;
import org.springblade.modules.nh.service.IPowerStationService;
import org.springblade.modules.order.utils.PlantformUtils;
import org.springblade.modules.order.utils.Target;
import org.springblade.modules.order.utils.WebPageFunUtils;
import org.springblade.modules.system.pojo.entity.Region;
import org.springblade.modules.system.service.IRegionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 设备告警信息表 服务实现类
 *
 * @author AlexWang
 * @since 2024-06-03
 */
@Service
@AllArgsConstructor
public class AlarmInfoServiceImpl extends BaseServiceImpl<AlarmInfoMapper, AlarmInfoEntity> implements IAlarmInfoService {

//	private final MonitorInverterStatMapper inverterStatMapper;

	private final IPowerStationService powerStationService;

	private final OperationOrderServiceImpl orderService;

	private final IRegionService regionService;

	private final MonitorEntryStatServiceImpl statService;

	@Autowired
	OperationOrderOperationInfoServiceImpl infoService;

	@Override
	public IPage<AlarmInfoVO> selectAlarmInfoPage(IPage<AlarmInfoVO> page, AlarmInfoVO alarmInfo) {
		return page.setRecords(baseMapper.selectAlarmInfoPage(page, alarmInfo));
	}

	@Override
	public OverviewStaticDataVo stationAlarm(String outStationId) {
		return this.baseMapper.stationAlarm(outStationId);
	}

	@Override
	public List<AlarmInfoExcel> exportAlarmInfo(Wrapper<AlarmInfoEntity> queryWrapper) {
		List<AlarmInfoEntity> alarmInfoList = this.list(queryWrapper);
		List<AlarmInfoExcel> result = Lists.newArrayList();
		alarmInfoList.forEach(alarmInfo -> {

			AlarmInfoExcel excel = new AlarmInfoExcel();
			BeanUtil.copyProperties(alarmInfo,excel);
			excel.setSource(DictCache.getValue(DictEnum.BRAND, alarmInfo.getSource()));
			excel.setType(DictCache.getValue("alarm_type", alarmInfo.getType()));
			excel.setCloseStr(DictCache.getValue("alarm_close_status", alarmInfo.getCloseStatus()));
			excel.setStatusStr(DictCache.getValue("alarm_info_status", alarmInfo.getStatus()));
			if(alarmInfo.getStartTime()!=null){
				excel.setStartTimeStr(DateUtil.formatDateTime(alarmInfo.getStartTime()));
			}
			PowerStationEntity station = powerStationService.getById(alarmInfo.getStationId());
			if(station!=null){
				excel.setOwnerName(station.getOwnerName());
				excel.setStationCode(station.getStationCode());
				result.add(excel);
			}
		});
		return result;
	}

	private AlarmInfoEntity getByOutStationId(String outStationId) {
		List<AlarmInfoEntity> list =this.list(new QueryWrapper<AlarmInfoEntity>().lambda()
			.eq(AlarmInfoEntity::getOutStationId, outStationId)
			.eq(AlarmInfoEntity::getCloseStatus, "1"));
		return list.isEmpty()?null:list.get(0);
	}

	@Override
	public void syncAlarmInfo(List<GetAlarmListR> list, String sysType) {
		if (CollectionUtils.isEmpty(list)) {
			return;
		}

		List<AlarmInfoEntity> alarmList = Lists.newArrayList();

		List<PowerStationEntity> stationEntityList = powerStationService.list(new QueryWrapper<PowerStationEntity>().lambda().isNotNull(PowerStationEntity::getOutStationId));
//		List<String> sns = list.stream().map(GetAlarmListR::getAlarmDeviceSn).collect(Collectors.toList());

//		List<MonitorInverterStatEntity> inverterStatEntities = inverterStatMapper.getInverterBySns(sns,sysType);
//		Map<String,MonitorInverterStatEntity> snMapInverter = inverterStatEntities.stream().collect(Collectors.toMap(e -> e.getSn(), e -> e));;

		Map<String,PowerStationEntity> idMapPowerStation = Maps.newHashMap();

		stationEntityList.forEach(item->{
			idMapPowerStation.put(item.getOutStationId(),item);
		});


		List<String> closedAlarmDeviceIdList = Lists.newArrayList();
		for (GetAlarmListR alarm : list) {
			String outStationId=alarm.getStationId();
//			MonitorInverterStatEntity inverterStat = snMapInverter.get(alarm.getAlarmDeviceSn());
			PowerStationEntity station = idMapPowerStation.get(outStationId);
			if(station==null) continue;

			AlarmInfoEntity entity = getByOutStationId(alarm.getStationId());
			if(entity==null){
				entity = new AlarmInfoEntity();
			}else{
				String closeStatus = calCloseStatus(sysType, alarm, entity);
				if(MonitorConstants.ALARM_CLOSE_YES.equals(closeStatus)){
					closedAlarmDeviceIdList.add(alarm.getAlarmDeviceSn());
				}
				continue;
			}

			entity.setSn(alarm.getAlarmDeviceSn());
//			entity.setIdCode(Objects.equals(sysType, NhConstants.SYS_TYPE_AISWEI) ? alarm.getWarningInfoData() : null);
//			entity.setDeviceType("0");
//			vs[colMap.get("`device_name`")] = StringUtils.defaultIfBlank(alarm.getMachine(), planMaterial == null ? null : planMaterial.getStr("name"));
//			vs[colMap.get("`device_type`")] = (planMaterial == null ? null : planMaterial.getStr("type"));
//			if(inverterStat!=null){
//				entity.setDeviceName(inverterStat.getName());
//			}
			entity.setStationId(station.getId());
			entity.setOutStationId(alarm.getStationId());
			entity.setStationName(station.getOwnerName()+station.getStationCode());
			entity.setType(convLevel(alarm.getAlarmLevel()));
			entity.setMalfunctionCode(alarm.getAlarmCode());
			entity.setSource(sysType);
			entity.setAlarmName(alarm.getAlarmMsg());
//			entity.setStatus(Integer.parseInt(MonitorConstants.ALARM_ST_NOT_CONFIRMED));

			String closeStatus = calCloseStatus(sysType, alarm, entity);
			if(MonitorConstants.ALARM_CLOSE_YES.equals(closeStatus)){
				continue;
			}

			entity.setModel(alarm.getModel());
			entity.setStartTime(new Date(alarm.getAlarmBeginTime()));
			entity.setStartTimeTsp(alarm.getAlarmBeginTime());
//			entity.setStationId(0l);
			if (alarm.getAlarmEndTime() != null) {
				entity.setEndTime(new Date(alarm.getAlarmEndTime()));
			}
			entity.setSuggestion(alarm.getAdvice());
			entity.setCloseStatus(closeStatus);
			entity.setCreateTime(new Date());
			entity.setUpdateTime(new Date());
			alarmList.add(entity);
		}
		this.saveOrUpdateBatch(alarmList);
		if(!CollectionUtils.isEmpty(closedAlarmDeviceIdList)){
			LambdaUpdateWrapper<AlarmInfoEntity> alarmUpdateWrapper = new LambdaUpdateWrapper<>();
			alarmUpdateWrapper.in(AlarmInfoEntity::getSn, closedAlarmDeviceIdList)
				.set(AlarmInfoEntity::getIsDeleted,"1")
				.set(AlarmInfoEntity::getCloseStatus,MonitorConstants.ALARM_CLOSE_NO)
				.set(AlarmInfoEntity::getSolution,"设备故障已处理，系统同步删除");
			this.update(alarmUpdateWrapper);
		}
	}

	private String calCloseStatus(String sysType, GetAlarmListR alarm, AlarmInfoEntity entity) {
		String closeStatus = MonitorConstants.ALARM_CLOSE_NO;
		if(StringUtils.isNotBlank(alarm.getState())){
			//状态:1未确认、2待处理、3处理中、4已解决
			int status = 1;
			if(NhConstants.SYS_TYPE_GINLONG.equals(sysType)){
				//0 = 未处理，1 = 已处理，2 = 已恢复
				if(!alarm.getState().equals("0")){
					status = 4;
					closeStatus = MonitorConstants.ALARM_CLOSE_YES;
				}
			}
			if(NhConstants.SYS_TYPE_GOODWE.equals(sysType)){
				//状态 1：已处理 0：未处理
				if(alarm.getState().equals("1")){
					status = 4;
					closeStatus = MonitorConstants.ALARM_CLOSE_YES;
				}
			}
			entity.setStatus(status);
		}
		return closeStatus;
	}

	// 数据库中存的告警类型:1故障、2告警、3提示、4建议
	// ginlong level 1 = 提示,2 = 一般,3 = 紧急
	// goodwe 没有，因此直接设为 2 = 一般
	// aiswei 没有，因此直接设为 2 = 一般
	private static String convLevel(String alarmLevel) {
		if (StringUtils.isBlank(alarmLevel)) {
			return MonitorConstants.ALARM_TYPE_ADVICE;
		}
		switch (alarmLevel) {
			case "1":
				return MonitorConstants.ALARM_TYPE_TIPS;
			case "2":
				return MonitorConstants.ALARM_TYPE_WARN;
			case "3":
				return MonitorConstants.ALARM_TYPE_FAULT;
			default:
				return MonitorConstants.ALARM_TYPE_ADVICE;
		}
	}

	@Override
	public void syncRecoverTime(List<InverterRecoverDTO> recoverList) {
		for (int i = 0, n = recoverList.size(); i < n; i++) {
			Date d = new Date();
			d.setTime(recoverList.get(i).getRecoverTime());
			LambdaUpdateWrapper<AlarmInfoEntity> updateWrapper = new LambdaUpdateWrapper<>();
			updateWrapper.eq(AlarmInfoEntity::getIdCode,recoverList.get(i).getFaultCode())
				.eq(AlarmInfoEntity::getSource,NhConstants.SYS_TYPE_AISWEI)
				.set(AlarmInfoEntity::getEndTime,d);
			this.update(updateWrapper);
		}
	}

	@Override
	public List<String> getIdCodes(String sysTypeAiswei) {
		return this.baseMapper.getIdCodes(sysTypeAiswei);
	}

	@Override
	public String getOrderNo(Long alarmId) {
		List<OperationOrderEntity> list = orderService.list(new QueryWrapper<OperationOrderEntity>().lambda().eq(OperationOrderEntity::getAlarmId,alarmId).notIn(OperationOrderEntity::getStatus,"5","6"));
		return CollectionUtils.isEmpty(list)?"":list.get(0).getNumber();
	}

	@Override
	public String getOrderNumber(Long entryId) {
		PowerStationEntity entity = powerStationService.getOne(new QueryWrapper<PowerStationEntity>().lambda().eq(PowerStationEntity::getId,entryId));
		return entity!=null?entity.getOrderNumber():"";
	}


	public static String getFirstDayofNextMonth(Date date , String format){
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		try {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime (date);
			calendar.set(Calendar.DAY_OF_MONTH,1);
			calendar.add(Calendar.MONTH, 1);
			return sdf.format(calendar.getTime());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public R turnMaintenance(String id) {
		BigDecimal bd = BigDecimal.ZERO;
		BladeUser user = AuthUtil.getUser();
		Date time = new Date();
		AlarmInfoEntity alarm = getById(id);
		if(alarm.getStatus()!=2){
			return R.fail(201,"当前状态不可转运维");
		}
		alarm.setStatus(3);

		PowerStationEntity customerEntry = powerStationService.getById(alarm.getStationId());
		if(StringUtils.isBlank(customerEntry.getOmProviderId())){
			throw  new ServiceException("该电站未绑定运维商，不可操作");
		}
		MonitorEntryStatEntity statEntity = statService.findByStationId(customerEntry.getOutStationId());
		String number = PlantformUtils.getOrderNumber();
		OperationOrderEntity order = new OperationOrderEntity();
		order.setNumber(number);
		order.setOrderType("4");//监控转运维
		order.setCreateTime(time);
		order.setRepairTime(time);
		order.setCreateBy(user.getUserId().toString());
		order.setApplianceCategory(alarm.getDeviceType());
		order.setApplianceModel(alarm.getModel());
		order.setApplianceBarcode(alarm.getSn());
		if (customerEntry != null) {
			Long count = orderService.findRetunCountByOrderId(customerEntry.getInnerStationId());
			if(count>0){
				throw  new ServiceException("该电站已经转运维，不可重复操作");
			}
			order.setAgentId(customerEntry.getAgentId());
			order.setAgentName(customerEntry.getAgentName());
			order.setCustomerName(customerEntry.getOwnerName());
			order.setPowerStationCode(customerEntry.getStationCode());
			order.setCapitalName(customerEntry.getCapitalName());
			order.setCapitalCode(customerEntry.getCapitalCode());

			Region region = new Region();
			region.setProvinceName(customerEntry.getProvince());
			region.setRegionLevel(1);
			Region detail = regionService.getOne(Condition.getQueryWrapper(region));
			if(detail!= null){
				order.setProvinceCode(detail.getProvinceCode());
			}
			order.setProvince(customerEntry.getProvince());
			region.setCityName(customerEntry.getCity());
			region.setRegionLevel(2);
			Region citys = regionService.getOne(Condition.getQueryWrapper(region));
			if(citys!= null){
				order.setCityCode(citys.getCityCode());
			}
			order.setCity(customerEntry.getCity());
			region.setDistrictName(customerEntry.getDistrict());
			region.setRegionLevel(3);
			Region distr = regionService.getOne(Condition.getQueryWrapper(region));
			if(distr!= null){
				order.setAreaCode(distr.getDistrictCode());
			}
			order.setArea(customerEntry.getDistrict());

			order.setCustomerAddress(customerEntry.getAddress());

			order.setCustomerMobile(customerEntry.getOwnerPhone());
			order.setPowerStationName(customerEntry.getStationCode());
			order.setEntryId(customerEntry.getInnerStationId());
			order.setApplianceBrand(DictCache.getValue(DictEnum.DEVICE_BRAND, customerEntry.getBrand()));
			if(statEntity.getFisGenerateTime()!= null){
				String shtime = getFirstDayofNextMonth(statEntity.getFisGenerateTime(),"yyyy-MM-dd");
				order.setApplianceBuyTime(DateUtil.parse(shtime,"yyyy-MM-dd"));
				order.setPutIntoTime(DateUtil.parse(shtime,"yyyy-MM-dd"));
			}
			//order.setApplianceBuyTime(DateUtil.plusMonths(customerEntry.getStartGenDate(),1));



			order.setSiteId(customerEntry.getOmProviderId());
			order.setSiteName(customerEntry.getOmProviderName());
			order.setStatus(OrderConstants.ORDER_STATUS_SERVICE);
			order.setSiteStatus(OrderConstants.SITE_STATUS_GET);
			order.setDispatchTime(time);
			if(order.getWarningStartDay()==null){
				order.setWarningStartDay(DateUtils.addDays(time,3));
			}
		}else{
			order.setSiteStatus("0");
			order.setStatus("1");
		}

		order.setRemarks(alarm.getMalfunctionCode()+","+alarm.getAlarmName());//故障码+告警名称(故障信息)
		order.setComplaintCount(0);
		order.setSiteCost(bd);
		order.setAccountsReceivable(bd);
		order.setTotalCollections(bd);
		order.setMileage(bd);
		order.setMileCost(bd);
		order.setServiceCost(bd);
		order.setFittingCost(bd);
		order.setSpecialInstallation("1");
		order.setAlarmId(alarm.getId());

		Target ta = new Target();
		ta.setD(DateUtil.formatDateTime(time));
		ta.setP(user.getNickName());
		ta.setC(user.getNickName() + "转运维接入");
		ta.setT(Target.NEW_ORDER);
		if (!orderService.save(order)) {
			return R.fail(201,"转运维失败");
		}
		customerEntry.setOrderNumber(order.getNumber());

		String str = WebPageFunUtils.appendOrderProcessDetail(ta, "");
		OperationOrderOperationInfoEntity info = new OperationOrderOperationInfoEntity();
		info.setOrderId(order.getId());
		info.setProcessDetail(str);
		if(StringUtil.isNotBlank(order.getSiteId())){
			info.setSiteId(order.getSiteId());
		}
		powerStationService.updateById(customerEntry);
		updateById(alarm);
		return R.status(infoService.save(info));
	}


}
