package org.springblade.modules.nh.controller;

import com.alibaba.excel.exception.ExcelAnalysisException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import lombok.AllArgsConstructor;
import jakarta.validation.Valid;

import org.apache.commons.compress.utils.Lists;
import org.springblade.common.constant.NhConstants;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.material.excel.MaterialImporter;
import org.springblade.modules.nh.excel.MaterialExcel;
import org.springblade.modules.nh.excel.PowerStationImport;
import org.springblade.modules.nh.excel.PowerStationImporter;
import org.springblade.modules.nh.job.InefficientScheduler;
import org.springblade.modules.nh.pojo.dto.PowerStationDTO;
import org.springblade.modules.nh.pojo.dto.StationDTO;
import org.springblade.modules.nh.pojo.vo.InverterTreeVO;
import org.springblade.modules.nh.service.IPowerStationInefficientService;
import org.springblade.modules.operation.excel.EntryPaymentTimeExcel;
import org.springblade.modules.operation.excel.EntrySiteExcel;
import org.springblade.modules.operation.pojo.entity.OperationSiteEmployeeEntity;
import org.springblade.modules.operation.pojo.entity.OperationSiteEntity;
import org.springblade.modules.operation.service.IOperationSiteEmployeeService;
import org.springblade.modules.operation.service.IOperationSiteService;
import org.springblade.modules.order.pojo.entity.OperationOrderEntity;
import org.springblade.modules.order.pojo.vo.SelectVo;
import org.springblade.modules.order.service.IOperationOrderCallbackService;
import org.springblade.modules.order.service.IOperationOrderService;
import org.springblade.modules.order.utils.ExcelReader;
import org.springblade.modules.system.excel.RegionExcel;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.modules.nh.pojo.entity.PowerStationEntity;
import org.springblade.modules.nh.pojo.vo.PowerStationVO;
import org.springblade.modules.nh.excel.PowerStationExcel;
import org.springblade.modules.nh.wrapper.PowerStationWrapper;
import org.springblade.modules.nh.service.IPowerStationService;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.excel.util.ExcelUtil;
import org.springblade.core.tool.constant.BladeConstant;

import java.util.ArrayList;
import java.util.Map;
import java.util.List;
import java.util.stream.Collectors;

import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;

/**
 * 电站 控制器
 *
 * @author AlexWang
 * @since 2024-05-31
 */
@RestController
@AllArgsConstructor
@RequestMapping("nh/powerStation")
@Tag(name = "电站", description = "电站接口")
public class PowerStationController extends BladeController {

	private final IPowerStationService powerStationService;

	private final IOperationSiteEmployeeService employeeService;


	private final IOperationSiteService operationSiteService;

	private final IOperationOrderCallbackService operationOrderCallbackService;

	private final IOperationOrderService orderService;
	private final InefficientScheduler inefficientScheduler;

	private final IPowerStationInefficientService powerStationInefficientService;

	@GetMapping("/lazy-tree")
	@ApiOperationSupport(order = 1)
	@Operation(summary = "懒加载树形结构", description = "树形结构")
	public R<List<InverterTreeVO>> lazyTree(String parentId,String parentName,int level) {
		List<InverterTreeVO> tree = powerStationService.getLazyTree(parentId,parentName,level);
		return R.data(tree);
	}

	@GetMapping("/total-tree")
	@ApiOperationSupport(order = 1)
	@Operation(summary = "懒加载树形结构", description = "树形结构")
	public R<InverterTreeVO> totalTree() {
		return R.data(powerStationService.getTotalTree());
	}

	/**
	 * 电站 详情
	 */
	@GetMapping("/getMapDistribute")
	@ApiOperationSupport(order = 1)
	@Operation(summary = "详情", description  = "传入powerStation")
	public R getMapDistribute(String keyword) {
		return powerStationService.getMapdistribution();
	}

	/**
	 * 电站 详情
	 */
	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@Operation(summary = "详情", description  = "传入powerStation")
	public R<PowerStationVO> detail(PowerStationEntity powerStation) {
		return R.data(powerStationService.getStationDetail(powerStation));
	}
	/**
	 * 电站 详情
	 */
	@GetMapping("/staticsStatus")
	@ApiOperationSupport(order = 1)
	@Operation(summary = "获取电站状态统计数量", description  = "传入powerStation")
	public R staticsStatus() {
		return R.data(powerStationService.staticsStatus());
	}
	/**
	 * 电站 详情
	 */
	@GetMapping("/staticsYkStatus")
	@ApiOperationSupport(order = 1)
	@Operation(summary = "获取电站状态统计数量", description  = "传入powerStation")
	public R staticsYkStatus() {
		return R.data(powerStationService.staticsYkStatus());
	}

	@GetMapping("/staticsHomeOverview")
	@ApiOperationSupport(order = 1)
	@Operation(summary = "获取电站状态统计数量", description  = "传入powerStation")
	public R staticsHomeOverview() {
		return R.data(powerStationService.staticsHomeOverview(null));
	}

	@GetMapping("/projectCompanyGenerationData")
	@ApiOperationSupport(order = 1)
	@Operation(summary = "根据公司来统计发电情况", description  = "传入powerStation")
	public R projectCompanyGenerationData(String type) {
		return R.data(powerStationService.statByProjectCompany(type,null));
	}

	/**
	 * 首页发电趋势
	 */
	@GetMapping(value = "powerGenerationTrendsHome")
	@Operation(summary = "发电趋势")
	public R powerGenerationTrendsHome(String type){
		return R.data(powerStationService.powerGenerationTrendsHome(type,""));
	}

	/**
	 * 发电趋势
	 */
	@GetMapping(value = "powerGenerationTrends")
	@Operation(summary = "发电趋势")
	public R powerGenerationTrends(@Parameter(name = "entryId", required = true,description = "电站id")Long entryId,@Parameter(name = "stationCode", required = true,description = "电站stationCode")String stationCode,@Parameter(name = "type", required = true,description = "类型 7天：week")String type,@Parameter(name = "time", required = true,description = "当前时间")String time){
		return R.data(powerStationService.powerGenerationTrends(entryId,type,time,stationCode));
	}
	/**
	 * 电站 分页
	 */
	@GetMapping("/list")
	@ApiOperationSupport(order = 2)
	@Operation(summary = "分页", description  = "传入powerStation")
	public R<IPage<PowerStationVO>> list(@Parameter(hidden = true) @RequestParam Map<String, Object> powerStation, Query query) {
		QueryWrapper<PowerStationEntity> queryWrapper =Condition.getQueryWrapper(powerStation, PowerStationEntity.class);
		String omProviderId = operationSiteService.getOmProviderId();
		if(StringUtil.isNotBlank(omProviderId)){
			queryWrapper.lambda().eq(PowerStationEntity::getOmProviderId,omProviderId);
		}
		//queryWrapper.lambda().eq(PowerStationEntity::getApplyStatus,1);
		IPage<PowerStationEntity> pages = powerStationService.page(Condition.getPage(query), queryWrapper);
		IPage<PowerStationVO> ret = PowerStationWrapper.build().pageVO(pages);
		ret.getRecords().forEach(item->{
			Double weekAvgEnergy = inefficientScheduler.getAvgHoursDefault(item);
			item.setWeekAvgEnergy(weekAvgEnergy);
		});
		return R.data(ret);
	}

	/**
	 * 电站 分页
	 */
	@GetMapping("/mapSearch")
	@ApiOperationSupport(order = 2)
	@Operation(summary = "分页", description  = "传入powerStation")
	public R mapSearch(String keyword) {
		if(StringUtil.isBlank(keyword)) return R.data(Lists.newArrayList());
		LambdaQueryWrapper<PowerStationEntity> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.like(PowerStationEntity::getStationCode,keyword)
			.or()
			.like(PowerStationEntity::getOwnerName,keyword);
		List<PowerStationEntity> list = powerStationService.list(queryWrapper);
		return R.data(list);
	}

	/**
	 * 电站 自定义分页
	 */
	@GetMapping("/page")
	@ApiOperationSupport(order = 3)
	@Operation(summary = "分页", description  = "传入powerStation")
	public R<IPage<PowerStationVO>> page(StationDTO powerStation, Query query) {
		powerStation.setApplyStatus(1);
		IPage<PowerStationVO> pages = powerStationService.selectPowerStationPage(Condition.getPage(query), powerStation);
		pages.getRecords().forEach(item->{
			Double weekAvgEnergy = inefficientScheduler.getAvgHoursDefault(item);
			item.setWeekAvgEnergy(weekAvgEnergy);
		});
		return R.data(pages);
	}

	/**
	 * 电站 友夸列表数据
	 */
	@GetMapping("/pageYk")
	@ApiOperationSupport(order = 3)
	@Operation(summary = "友夸列表数据", description  = "传入powerStation")
	public R<IPage<PowerStationVO>> pageYk(StationDTO powerStation, Query query) {
		powerStation.setSource("2");
		IPage<PowerStationVO> pages = powerStationService.selectPowerStationPage(Condition.getPage(query), powerStation);
		return R.data(pages);
	}



	/**
	 * 电站 新增
	 */
	@PostMapping("/save")
	@ApiOperationSupport(order = 4)
	@Operation(summary = "新增", description  = "传入powerStation")
	public R save(@Valid @RequestBody PowerStationEntity powerStation) {
		return R.status(powerStationService.save(powerStation));
	}

	/**
	 * 电站 修改
	 */
	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@Operation(summary = "修改", description  = "传入powerStation")
	public R update(@Valid @RequestBody PowerStationEntity powerStation) {
		return R.status(powerStationService.updateById(powerStation));
	}

	/**
	 * 电站 新增或修改
	 */
	@PostMapping("/submit")
	@ApiOperationSupport(order = 6)
	@Operation(summary = "新增或修改", description  = "传入powerStation")
	public R submit(@Valid @RequestBody PowerStationEntity powerStation) {
		return R.status(powerStationService.saveOrUpdate(powerStation));
	}

	/**
	 * 电站 删除
	 */
	@PostMapping("/remove")
	@ApiOperationSupport(order = 7)
	@Operation(summary = "删除", description  = "传入ids")
	public R remove(@Parameter(name = "主键集合", required = true) @RequestParam String ids) {
		return R.status(powerStationService.removeByIds(Func.toLongList(ids)));
	}


	/**
	 * 导出数据
	 */
	@GetMapping("/export-powerStation")
	@ApiOperationSupport(order = 9)
	@Operation(summary = "导出数据", description  = "传入powerStation")
	public void exportPowerStation(StationDTO powerStation, BladeUser bladeUser, HttpServletResponse response) {
		powerStation.setApplyStatus(1);
		List<PowerStationExcel> list = powerStationService.exportPowerStation(powerStation);
		ExcelUtil.export(response, "电站数据" + DateUtil.time(), "电站数据表", list, PowerStationExcel.class);
	}

	/**
	 * 导出数据
	 */
	@GetMapping("/export-YkpowerStation")
	@ApiOperationSupport(order = 9)
	@Operation(summary = "导出友夸数据", description  = "传入powerStation")
	public void exportYkPowerStation(StationDTO powerStation, BladeUser bladeUser, HttpServletResponse response) {
		powerStation.setSource("2");
		List<PowerStationExcel> list = powerStationService.exportPowerStation(powerStation);
		ExcelUtil.export(response, "电站数据" + DateUtil.time(), "电站数据表", list, PowerStationExcel.class);
	}

	/**
	 * 我得电站
	*/
	@GetMapping("/findMyPowerStation")
	@ApiOperationSupport(order = 3)
	@Operation(summary = "我得电站", description  = "传入condition")
	public R<IPage<PowerStationEntity>> findMyPowerStation(Query query,BladeUser bladeUser,@Parameter(name = "condition",description = "查询条件") String condition) {
		if(!"6".equals(bladeUser.getDeptId())){
			return R.fail(201,"获取数据失败");
		}
		OperationSiteEmployeeEntity emp = employeeService.getEmployeByUserId(bladeUser.getUserId());
		IPage<PowerStationEntity> pages = powerStationService.findMyPowerStation(Condition.getPage(query), emp.getId(),emp.getSiteId(),condition);
		return R.data(pages);
	}


	@PostMapping("/bindingSite")
	@ApiOperationSupport(order = 10)
	@Operation(summary = "绑定服务商", description  = "传入powerStation")
	public R bindingSite(@Valid String id,String omProviderId) {
		OperationSiteEntity site = operationSiteService.getById(omProviderId);
		List<PowerStationEntity> entry = Lists.newArrayList();
		BladeUser user= AuthUtil.getUser();
		for(String enid :id.split(",")){
			PowerStationEntity powerStation = powerStationService.getById(enid);
			powerStation.setOmProviderName(site.getName());
			powerStation.setOmProviderId(omProviderId);
			powerStation.setBindingUnbindId(user.getUserId());
			entry.add(powerStation);
		}
		powerStationInefficientService.updateSiteName(id,site);
		return R.status(powerStationService.updateBatchById(entry));
	}

	/**
	 * 解绑运维商
	*/
	@PostMapping("/unbindSite")
	@ApiOperationSupport(order = 10)
	@Operation(summary = "解绑服务商", description  = "传入id")
	public R unbindSite(String id){
		List<PowerStationEntity> entry = Lists.newArrayList();
		BladeUser user= AuthUtil.getUser();
		for(String enid :id.split(",")){
			PowerStationEntity powerStation = powerStationService.getById(enid);
			List<OperationOrderEntity> list = orderService.findOrderListBySiteId(powerStation.getStationCode());
			if(!CollectionUtils.isEmpty(list)){
				return R.fail(201,"当前有服务中的工单，不可解绑");
			}
			powerStation.setOmProviderName("");
			powerStation.setOmProviderId("");
			powerStation.setBindingUnbindId(user.getUserId());
			entry.add(powerStation);
		}
		powerStationInefficientService.deleteSiteName(id);
		return R.status(powerStationService.updateBatchById(entry));
	}

	/**
	 * 电站下拉选
	 */
	@GetMapping("/getSelectPowerStaion")
	@ApiOperationSupport(order = 3)
	@Operation(summary = "电站下拉选", description  = "传入condition")
	public R<List<StationDTO>> getSelectPowerStaion(Query query, @RequestParam Map<String, Object> map) {
	    List<StationDTO> list=powerStationService.getSelectPowerStaion(map);
		return R.data(list);
	}


	/**
	 * 根据电站编码带出 相应信息
	*/
	@PostMapping("/getStationDetailByPowCode")
	@ApiOperationSupport(order = 11)
	@Operation(summary = "根据电站编码带出相应信息", description  = "传入powerStationCode")
	public R<List<PowerStationDTO>> getStationDetailByPowCode(String powerStationCode){
		List<PowerStationDTO> entry = powerStationService.getStationListByPowCode(powerStationCode);
		List<SelectVo> brands = operationOrderCallbackService.getAllBrand();
		Map<String,String> maps =brands.stream().collect(Collectors.toMap(SelectVo::getCode, SelectVo::getName));
		if(entry != null && entry.size()>0){
			for(PowerStationDTO en :entry){
				if(en.getBrand()!= null){
					if(maps.containsKey(en.getBrand().toString())){
						en.setBrandName(maps.get(en.getBrand().toString()));
					}
					en.setAddress(en.getAddress().replaceAll(en.getProvince()+en.getCity()+en.getDistrict(), ""));
				}

			}
		}
		return R.data(entry);
	}
	/**
	 * 导出模板
	 */
	@GetMapping("export-template")
	@ApiOperationSupport(order = 12)
	@Operation(summary = "导出模板")
	public void exportUser(HttpServletResponse response) {
		List<EntrySiteExcel> list = new ArrayList<>();
		ExcelUtil.export(response, "导入绑定运维商模板", "绑定运维商表", list, EntrySiteExcel.class);
	}


	/**
	 * 导入绑定
	 */
	@PostMapping("import-site")
	@ApiOperationSupport(order = 12)
	@Operation(summary = "导入绑定运维商", description = "传入excel")
	public R importUser(MultipartFile file, Integer isCovered) {

		List<EntrySiteExcel> list ;
		try{
			list = ExcelReader.readExcel(file, EntrySiteExcel.class);
		}catch (ExcelAnalysisException e){
			return R.fail(e.getMessage());
		}
		if(list.isEmpty()){
			return R.fail("文档数据为空");
		}
		return powerStationService.importSite(list);
	}

	/**
	 * 导出电站模板
	 */
	@GetMapping("export-entry")
	@ApiOperationSupport(order = 12)
	@Operation(summary = "导出模板")
	public void exportEntry(HttpServletResponse response) {
		List<PowerStationImport> list = new ArrayList<>();
		ExcelUtil.export(response, "导入电站模板", "导入电站", list, PowerStationImport.class);
	}


	/**
	 * 导入投放时间的模板
	 */
	@GetMapping("exportTemplatePaymentTime")
	@ApiOperationSupport(order = 19)
	@Operation(summary = "导入投放时间的模板")
	public void exportTemplatePaymentTime(HttpServletResponse response) {
		List<EntryPaymentTimeExcel> list = new ArrayList<>();
		ExcelUtil.export(response, "导入投放时间模板", "导入投放时间", list, EntryPaymentTimeExcel.class);
	}


	/**
	 * 导入投放时间
	 */
	@PostMapping("importPaymentTime")
	@ApiOperationSupport(order = 20)
	@Operation(summary = "导入投放时间", description = "传入excel")
	public R importPaymentTime(MultipartFile file) {
		List<EntryPaymentTimeExcel> list ;
		try{
			list = ExcelReader.readExcel(file, EntryPaymentTimeExcel.class);
		}catch (ExcelAnalysisException e){
			return R.fail(e.getMessage());
		}
		if(list.isEmpty()){
			return R.fail("文档数据为空");
		}
		 powerStationService.importPaymentTime(list);
		return R.success("");
	}
}
