package org.springblade.modules.nh.api;

import com.alibaba.fastjson.JSON;
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.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.compress.utils.Lists;
import org.springblade.common.constant.NhConstants;
import org.springblade.common.utils.CommonUtil;
import org.springblade.common.utils.TaskControl;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.excel.util.ExcelUtil;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.annotation.PreAuth;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.constant.RoleConstant;
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.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.ginlong.scheduler.GinlongStationMonthEachRunner;
import org.springblade.modules.nh.factory.goodwe.scheduler.GoodweStationFisGenDateEachRunner;
import org.springblade.modules.nh.factory.goodwe.scheduler.GoodweStationMonthEachRunner;
import org.springblade.modules.nh.factory.goodwe.scheduler.GoodweStationYearEachRunner;
import org.springblade.modules.nh.job.InefficientScheduler;
import org.springblade.modules.nh.pojo.dto.DeviceDTO;
import org.springblade.modules.nh.pojo.dto.MonitorEntryStatDTO;
import org.springblade.modules.nh.pojo.dto.PowerStationDTO;
import org.springblade.modules.nh.pojo.dto.PowerStationPaymentTimeDTO;
import org.springblade.modules.nh.pojo.entity.DeviceEntity;
import org.springblade.modules.nh.pojo.entity.InefficientSettingEntity;
import org.springblade.modules.nh.pojo.entity.MonitorEntryStatEntity;
import org.springblade.modules.nh.pojo.entity.PowerStationEntity;
import org.springblade.modules.nh.pojo.vo.DeviceVO;
import org.springblade.modules.nh.pojo.vo.MonitorEntryStatVO;
import org.springblade.modules.nh.service.*;
import org.springblade.modules.nh.wrapper.DeviceWrapper;
import org.springblade.modules.nh.wrapper.MonitorEntryStatWrapper;
import org.springblade.modules.nh.wrapper.PowerStationWrapper;
import org.springframework.web.bind.annotation.*;
import scala.collection.mutable.StringBuilder;

import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 设备管理 控制器
 *
 * @author AlexWang
 * @since 2024-05-31
 */
@RestController
@AllArgsConstructor
@RequestMapping("nat/open")
@Tag(name = "设备管理", description = "设备管理接口")
public class NatOpenController extends BladeController {

	private final IPowerStationService stationService;

	private final IInverterDataService dataService;

	private final IMonitorEntryStatService entryStatService;

	private final IMonitorEntryMonthStatService monthStatService;

	private final IDeviceService deviceService;

	private final IAlarmInfoService alarmInfoService;


	/**
	 * 电站实时数据
	 */
	@GetMapping(value = "stationLastDaysEnergy")
	@Operation(summary = "电站实时数据")
	public R stationLastDaysEnergy(
		@Parameter(description = "内部电站ID", required = true) String innerStationId,
		@Parameter(description = "需要最近的天数", required = true) Integer days){
		PowerStationEntity entity= stationService.getByInnerId(innerStationId);
		if(entity== null){
			return R.status(false);
		}
		return R.data(monthStatService.overviewLastDays(entity.getOutStationId(),days));
	}

	/**
	 * 电站实时数据
	 */
	@GetMapping(value = "stationRealtimeInfo")
	@Operation(summary = "电站实时数据")
	public R<MonitorEntryStatDTO> stationRealtimeInfo(String innerStationId){
		PowerStationEntity entity= stationService.getByInnerId(innerStationId);
		if(entity==null || StringUtil.isBlank(entity.getOutStationId())){
			return R.fail("该电站不存在，或者电站绑定的厂家电站不存在");
		}
		MonitorEntryStatVO vo = entryStatService.realTimeDetail(PowerStationWrapper.build().entityVO(entity));
		MonitorEntryStatDTO dto = MonitorEntryStatWrapper.build().entityDTO(vo);
		dto.setPac(dataService.sumPacByStationId(entity.getId()));
		dto.setOverviewVo(alarmInfoService.stationAlarm(vo.getOutStationId()));
		dto.setInnerStationId(innerStationId);
		return R.data(dto);
	}

	/**
	 * 发电趋势
	 */
	@GetMapping(value = "powerGenerationTrends")
	@Operation(summary = "发电趋势")
	public R powerGenerationTrends(String innerStationId,String type,String time){
		return R.data(stationService.powerGenTrendsByInnerId(innerStationId,type,time));
	}

	/**
	 * 添加电站
	 */
	@PostMapping("/addPowerStation")
	@ApiOperationSupport(order = 1)
	@Operation(summary = "添加电站", description  = "传入device")
	public R addPowerStation(@Valid @RequestBody PowerStationDTO dto) {
		return stationService.syncPowerStation(dto);
	}

	/**
	 * 添加电站
	 */
	@PostMapping("/updatePowerStation")
	@ApiOperationSupport(order = 1)
	@Operation(summary = "添加电站", description  = "传入device")
	public R updatePowerStation(@Valid @RequestBody PowerStationDTO dto) {
		PowerStationEntity station = stationService.getPowerStationByInId(dto.getInnerStationId());
		if(station==null){
			return R.fail("不存在的电站");
		}
		//更新电站
		LambdaUpdateWrapper<PowerStationEntity> updateWrapper = new LambdaUpdateWrapper<>();
		updateWrapper.eq(PowerStationEntity::getId, station.getId());
		if(dto.getApplyStatus()!=null){
			updateWrapper.set(PowerStationEntity::getApplyStatus,dto.getApplyStatus());
		}
		if(dto.getStartGenDate()!=null){
			updateWrapper.set(PowerStationEntity::getStartGenDate,dto.getStartGenDate());
		}
		if(dto.getMergeTime()!=null){
			updateWrapper.set(PowerStationEntity::getMergeTime,dto.getMergeTime());
		}
		stationService.update(updateWrapper);
		//更新同步电站
		if(StringUtil.isNotBlank(station.getOutStationId()) && dto.getStartGenDate()!=null){
			LambdaUpdateWrapper<MonitorEntryStatEntity> updateWrapper2 = new LambdaUpdateWrapper<>();
			updateWrapper2.eq(MonitorEntryStatEntity::getOutStationId,station.getOutStationId())
				.set(MonitorEntryStatEntity::getFisGenerateTime,dto.getStartGenDate());
			entryStatService.update(updateWrapper2);
		}

		return R.success("更新成功");
	}

	/**
	 * 批量添加电站
	 */
	@PostMapping("/batchAddPowerStation")
	@ApiOperationSupport(order = 2)
	@Operation(summary = "添加电站", description  = "传入device")
	public R batchAddPowerStation(@Valid @RequestBody List<PowerStationEntity> stationList) {
		return R.status(stationService.saveBatch(stationList));
	}
	/**
	 * 批量修改电站信息
	*/
	@PostMapping("/batchUpdateStation")
	@ApiOperationSupport(order = 2)
	@Operation(summary = "更新电站", description  = "传入")
	public R batchUpdateStation(@Valid @RequestBody List<PowerStationEntity> stationList){
		return R.status(stationService.batchUpdateStation(stationList));
	}


	/**
	 * 添加设备
	 */
	@PostMapping("/addDevice")
	@ApiOperationSupport(order = 3)
	@Operation(summary = "添加设备", description  = "传入device")
	public R addDevice(@Valid @RequestBody DeviceDTO deviceDTO) {
		return deviceService.syncDeviceData(deviceDTO);
	}

	/**
	 * 添加设备
	 */
	@PostMapping("/batchAddDevice")
	@ApiOperationSupport(order = 3)
	@Operation(summary = "批量添加设备", description  = "传入device")
	public R batchAddDevice(@Valid @RequestBody List<DeviceDTO> list) {
		int m=0,n=0;
		List<String> ids = Lists.newArrayList();
		for(DeviceDTO dto:list){
			try{
				R r= deviceService.syncDeviceData(dto);
				if(r.isSuccess()){
					m++;
				}else{
					n++;
					ids.add(dto.getInnerDeviceId());
				}
			}catch (Exception e){
				n++;
				ids.add(dto.getInnerDeviceId());
			}

		}
		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+"条");
		}
	}

	/**
	 * 物料信息变更导致的更新设备信息
	 */
	@PostMapping("/materialChangeCauseDeviceChange")
	@ApiOperationSupport(order = 3)
	@Operation(summary = "物料信息变更导致的更新设备信息", description  = "传入device")
	public R materialChangeCauseDeviceChange(@Valid @RequestBody List<DeviceDTO> list) {
		return deviceService.materialChangeCauseDeviceChange(list);
	}


	/**
	 * 维护回款时间--投放通过时间
	 */
	@PostMapping("/editPaymentTime")
	@ApiOperationSupport(order = 1)
	@Operation(summary = "维护回款时间-投放通过时间", description  = "传入device")
	public R editPaymentTime(@RequestBody PowerStationPaymentTimeDTO dto) {
		deviceService.editPaymentTime(dto);
		return R.success("保存成功");
	}
}
