package org.jeecg.modules.stm.metric.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 
 
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;

import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.stm.act.metric.entity.StMetric;
import org.jeecg.modules.stm.act.metric.service.IStMetricService;
import org.jeecg.modules.stm.act.metric.vo.StMetricVo;
import org.jeecg.modules.stm.metric.entity.MetricMonitorSet;
import org.jeecg.modules.stm.metric.entity.MetricMonitorSetHistory;
import org.jeecg.modules.stm.metric.entity.MetricReport;
import org.jeecg.modules.stm.metric.entity.MetricTaskAlloc;
import org.jeecg.modules.stm.metric.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import org.jeecg.modules.stm.utils.CommonUtil;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.jeecg.modules.stm.utils.UserUtil;

/**
 * @Description: 监测方案
 * @Author: jeecg-boot
 * @Date:   2023-07-15
 * @Version: V1.0
 */

@RestController
@RequestMapping("/metric/metricMonitorSet")
@Slf4j
public class MetricMonitorSetController extends JeecgController<MetricMonitorSet, IMetricMonitorSetService> {
	@Autowired
	private IMetricMonitorSetService metricMonitorSetService;
	 @Autowired
	 private IStMetricService stMetricService;
	 @Autowired
	 private IMetricTaskAllocService metricTaskAllocService;
	 @Autowired
	 private IMetricReportService metricReportService;
	 @Autowired
	 private IMetricMonitorSetOtherService metricMonitorSetOtherService;

	 @Autowired
	 private IMetricMonitorSetHistoryService metricMonitorSetHistoryService;



	 @GetMapping(value = "/list")
	 public Result<IPage<MetricMonitorSet>> queryPageList(MetricMonitorSet metricMonitorSet,
			  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
			  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
			  HttpServletRequest req) {

		 String strName = metricMonitorSet.getMtrcName();
		 if(strName!=null &&strName.indexOf("*")==-1) {
			 metricMonitorSet.setMtrcName("*"+strName+"*");
		 }
		 QueryWrapper<MetricMonitorSet> queryWrapper = QueryGenerator.initQueryWrapper(metricMonitorSet, req.getParameterMap());
		 Page<MetricMonitorSet> page = new Page<MetricMonitorSet>(pageNo, pageSize);

		 IPage<MetricMonitorSet> pageList = metricMonitorSetService.queryWithPage(page, queryWrapper);
		 return Result.OK(pageList);
	 }

	 /**
	  * 查询当前用户应填写的指标
	  * @param metricMonitorSet
	  * @param req
	  * @return
	  */
	 @GetMapping(value = "/queryForCurUser")
	 public Result<IPage<MetricMonitorSet>> queryForCurUser(MetricMonitorSet metricMonitorSet,
					   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
					   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
					   HttpServletRequest req) {
		 LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		 QueryWrapper<MetricMonitorSet> queryWrapper = QueryGenerator.initQueryWrapper(metricMonitorSet, req.getParameterMap());
		 if (!sysUser.getUsername().equals("admin")) {
			 queryWrapper.apply(" mtrc_no in (SELECT DISTINCT mtrc_no from metric_task_alloc WHERE reporter= '" + sysUser.getId() + "')");
		 }
		 queryWrapper.orderByAsc("mtrc_no");
		 Page<MetricMonitorSet> page = new Page<MetricMonitorSet>(pageNo, pageSize);
		 IPage<MetricMonitorSet> pageList = metricMonitorSetService.queryWithPage(page, queryWrapper);
		 return Result.OK(pageList);
	 }

	 @GetMapping(value = "/queryAllMetric")
	 public Result<IPage<MetricMonitorSet>> queryAllMetric(MetricMonitorSet metricMonitorSet,String mtrcnos,
				  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
				  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
				  HttpServletRequest req) {
		 QueryWrapper<MetricMonitorSet> queryWrapper = QueryGenerator.initQueryWrapper(metricMonitorSet, req.getParameterMap());
		 if(mtrcnos!=null) {
			 queryWrapper.in("mtrc_no",mtrcnos.split(","));
		 }
		 queryWrapper.orderByAsc("mtrc_no");
		 Page<MetricMonitorSet> page = new Page<MetricMonitorSet>(pageNo, pageSize);
		 IPage<MetricMonitorSet> pageList = metricMonitorSetService.queryWithPage(page, queryWrapper);
		 return Result.OK(pageList);
	 }


	 @GetMapping(value = "/queryAllMetricNoPage")
	 public Result<List<MetricMonitorSet>> queryAllMetricNoPage(MetricMonitorSet metricMonitorSet,String mtrcnos,
																HttpServletRequest req) {
		 QueryWrapper<MetricMonitorSet> queryWrapper = QueryGenerator.initQueryWrapper(metricMonitorSet, req.getParameterMap());
		 if(mtrcnos!=null) {
			 queryWrapper.in("mtrc_no",mtrcnos.split(","));
		 }
		 queryWrapper.orderByAsc("mtrc_no");
		 List<MetricMonitorSet> list = metricMonitorSetService.list(queryWrapper);
		 return Result.OK(list);
	 }
	
	/**
	 *   添加
	 *
	 * @param metricMonitorSet
	 * @return
	 */
	@AutoLog(value = "监测方案-添加")

	@RequiresPermissions("metric:metric_monitor_set:add")
	@PostMapping(value = "/add")
	public Result<MetricMonitorSet> add(@RequestBody MetricMonitorSet metricMonitorSet) {
		if(metricMonitorSet.getMtrcNo()==null||metricMonitorSet.getMtrcNo().length()==0){
			String mtrcCode = metricMonitorSetService.metricNo(metricMonitorSet.getMtrcCtp());
			metricMonitorSet.setMtrcNo(mtrcCode);
		}
		metricMonitorSet.setMtrcSourceTp(1);
		metricMonitorSetService.save(metricMonitorSet);
		return Result.OK("添加成功！",metricMonitorSet);
	}

	 @PostMapping(value = "/batchAdd")
	 public Result<String> batchAdd(@RequestBody Map param) {
		 String tmpStr =param.get("metricNos").toString();
		 String[] tmpAry = tmpStr.split(",");
		 QueryWrapper<StMetric> queryWrapper = new QueryWrapper<>();
		 queryWrapper.in("metric_no",tmpAry);
		 List<StMetric> list =  stMetricService.list(queryWrapper);

		 QueryWrapper<MetricMonitorSet> queryWrapperMonitor = new QueryWrapper<>();
		 queryWrapperMonitor.in("mtrc_no",tmpAry);
		 List<MetricMonitorSet> listExist =  metricMonitorSetService.list(queryWrapperMonitor);
		 List<MetricMonitorSet> saveList = new ArrayList<MetricMonitorSet>();
		 List<String> existList= new ArrayList<>();
		 for(int j=0;j<listExist.size();j++) {
			 existList.add(listExist.get(j).getMtrcNo());
		 }
		 for(int i=0;i<list.size();i++) {
			 StMetric stMetric = list.get(i);
			 String strMetrcNo = stMetric.getMetricNo();
			 if(existList.contains(strMetrcNo)) {
				 continue;
			 }
			 MetricMonitorSet metricMonitorSet = new MetricMonitorSet();
			 metricMonitorSet.setMtrcNo(stMetric.getMetricNo());
			 metricMonitorSet.setMtrcName(stMetric.getMetricName());
			 metricMonitorSet.setDes(stMetric.getMetricDesc());
			 metricMonitorSet.setCollMethod(Integer.parseInt(stMetric.getCollectCode()));
			 metricMonitorSet.setCollFreq(Integer.parseInt(stMetric.getCollectRateCode()));
			 metricMonitorSet.setMtrcTp(Integer.parseInt(stMetric.getMetricTypeCode()));
			 metricMonitorSet.setMtrcSourceTp(0);
			 metricMonitorSet.setMtrcCtp(1);
			 saveList.add(metricMonitorSet);
		 }

		 metricMonitorSetService.saveBatch(saveList);
		 return Result.OK("添加成功！");
	 }

	 @PostMapping(value = "/addFromStMetric")
	 public Result<String> addFromStMetric(@RequestBody StMetricVo stMetric) {
		 QueryWrapper<MetricMonitorSet> queryWrapper = new QueryWrapper<>();
		 queryWrapper.eq("mtrc_no",stMetric.getMetricNo());
		 MetricMonitorSet existObj =  metricMonitorSetService.getOne(queryWrapper);
		 if(existObj!=null) {
			 return Result.OK("该记录已经在监管库存在！不能重复添加");
		 }
		 MetricMonitorSet metricMonitorSet = new MetricMonitorSet();
		 metricMonitorSet.setMtrcNo(stMetric.getMetricNo());
		 metricMonitorSet.setMtrcName(stMetric.getMetricName());
		 metricMonitorSet.setDes(stMetric.getMetricDesc());
		 metricMonitorSet.setCollMethod(Integer.parseInt(stMetric.getCollectCode()));
		 metricMonitorSet.setCollFreq(Integer.parseInt(stMetric.getCollectRateCode()));
		 metricMonitorSet.setMtrcTp(Integer.parseInt(stMetric.getMetricTypeCode()));
		 metricMonitorSet.setMtrcSourceTp(0);
		 metricMonitorSet.setMtrcCtp(1);
		 metricMonitorSetService.save(metricMonitorSet);
		 return Result.OK("添加成功！");
	 }
	
	/**
	 *  编辑
	 *
	 * @param metricMonitorSet
	 * @return
	 */
	@AutoLog(value = "监测方案-编辑")

	@RequiresPermissions("metric:metric_monitor_set:edit")
	@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
	public Result<String> edit(@RequestBody MetricMonitorSet metricMonitorSet) {
		try {
			if (metricMonitorSet == null || metricMonitorSet.getId() == null) {
				return Result.error("参数不能为空");
			}
			MetricMonitorSet oldMetric = metricMonitorSetService.getById(metricMonitorSet.getId());
			if (oldMetric == null) {
				return Result.error("监控指标不存在");
			}
			if (StringUtils.isBlank(metricMonitorSet.getMtrcNo())) {
				if(metricMonitorSet.getMtrcCtp()==null) {
					if(metricMonitorSet.getFormulas()!=null) {
						String mtrcCode = metricMonitorSetService.metricNo(2);
						metricMonitorSet.setMtrcNo(mtrcCode);
					} else {
						String mtrcCode = metricMonitorSetService.metricNo(1);
						metricMonitorSet.setMtrcNo(mtrcCode);
					}

				} else {
					String mtrcCode = metricMonitorSetService.metricNo(metricMonitorSet.getMtrcCtp());
					metricMonitorSet.setMtrcNo(mtrcCode);
				}

			}

			saveHistoryRecord(oldMetric);
			if (!metricMonitorSetService.updateById(metricMonitorSet)) {
				return Result.error("更新监控指标失败");
			}
			updateRelatedRiskLevels(metricMonitorSet);
			return Result.OK("编辑成功!");
		} catch (Exception e) {
			log.error("编辑监控指标失败: {}", e.getMessage(), e);
			return Result.error("编辑失败，请稍后重试");
		}
	}


	private void saveHistoryRecord(MetricMonitorSet oldMetric) {
		MetricMonitorSetHistory history = new MetricMonitorSetHistory();
		BeanUtils.copyProperties(oldMetric, history);
		history.setId(null); // 确保新记录

		if (!metricMonitorSetHistoryService.save(history)) {
			log.warn("保存历史记录失败，监控指标ID: {}", oldMetric.getId());
		}
	}

	private void updateRelatedRiskLevels(MetricMonitorSet metricMonitorSet) {
		String mtrcNo = metricMonitorSet.getMtrcNo();
		if (StringUtils.isBlank(mtrcNo)) {
			return;
		}

		List<MetricReport> reports = metricReportService.list(
			new QueryWrapper<MetricReport>().eq("mtrc_no", mtrcNo)
		);

		if (reports.isEmpty()) {
			return;
		}
		List<MetricReport> reportsToUpdate = reports.stream()
				.filter(report -> {
					try {
						Double fillVals = Double.valueOf(report.getFillVals());
						int newRiskLevel = CommonUtil.computeRiskLevel(fillVals, metricMonitorSet);
						return newRiskLevel != report.getRiskLevel();
					} catch (NumberFormatException e) {
						log.warn("填充值格式错误，报告ID: {}, 值: {}", report.getId(), report.getFillVals());
						return false;
					}
				})
				.peek(report -> {
					try {
						Double fillVals = Double.valueOf(report.getFillVals());
						int newRiskLevel = CommonUtil.computeRiskLevel(fillVals, metricMonitorSet);
						report.setRiskLevel(newRiskLevel);
					} catch (NumberFormatException e) {
						log.error("填充值格式错误，报告ID: {}", report.getId(), e);
					}
				})
				.collect(Collectors.toList());

		if (!reportsToUpdate.isEmpty()) {
			metricReportService.updateBatchById(reportsToUpdate);
		}
	}
	
	/**
	 *   通过id删除
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "监测方案-通过id删除")

	@RequiresPermissions("metric:metric_monitor_set:delete")
	@DeleteMapping(value = "/delete")
	public Result<String> delete(@RequestParam(name="id",required=true) String id) {
		MetricMonitorSet metricMonitorSet =metricMonitorSetService.getById(id);
		QueryWrapper<MetricTaskAlloc> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("mtrc_no",metricMonitorSet.getMtrcNo());
		metricTaskAllocService.remove(queryWrapper);
		QueryWrapper<MetricReport> queryReportWrapper = new QueryWrapper<>();
		queryReportWrapper.eq("mtrc_no",metricMonitorSet.getMtrcNo());
		metricReportService.remove(queryReportWrapper);
		metricMonitorSetService.removeById(id);
		metricMonitorSetOtherService.removeById(id);
		return Result.OK("删除成功!");
	}
	
	/**
	 *  批量删除
	 *
	 * @param ids
	 * @return
	 */
	@AutoLog(value = "监测方案-批量删除")

	@RequiresPermissions("metric:metric_monitor_set:deleteBatch")
	@DeleteMapping(value = "/deleteBatch")
	public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
		this.metricMonitorSetService.removeByIds(Arrays.asList(ids.split(",")));
		return Result.OK("批量删除成功!");
	}
	
	/**
	 * 通过id查询
	 *
	 * @param id
	 * @return
	 */
	//@AutoLog(value = "监测方案-通过id查询")

	@GetMapping(value = "/queryById")
	public Result<MetricMonitorSet> queryById(@RequestParam(name="id",required=true) String id) {
		MetricMonitorSet metricMonitorSet = metricMonitorSetService.getById(id);
		if(metricMonitorSet==null) {
			return Result.error("未找到对应数据");
		}
		return Result.OK(metricMonitorSet);
	}


	@GetMapping(value = "/queryByMtrcNo")
	public Result<MetricMonitorSet> queryByMtrcNo(@RequestParam(name="mtrcNo",required=true) String mtrcNo) {
		LambdaQueryWrapper<MetricMonitorSet> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(MetricMonitorSet::getMtrcNo, mtrcNo);
		MetricMonitorSet metricMonitorSet = metricMonitorSetService.getOne(wrapper);
		if(metricMonitorSet == null) {
			return Result.error("未找到对应数据");
		}
		return Result.OK(metricMonitorSet);
	}



    /**
    * 导出excel
    *
    * @param request
    * @param metricMonitorSet
    */
    @RequiresPermissions("metric:metric_monitor_set:exportXls")
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, MetricMonitorSet metricMonitorSet) {
        return super.exportXls(request, metricMonitorSet, MetricMonitorSet.class, "监测方案");
    }

    /**
      * 通过excel导入数据
    *
    * @param request
    * @param response
    * @return
    */
    @RequiresPermissions("metric:metric_monitor_set:importExcel")
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, MetricMonitorSet.class);
    }

	 @PostMapping(value = "/batchImmportBase")
	 public Result<String> batchImmport(@RequestBody List<MetricMonitorSet> monitorSetList) {
		 int cnt = monitorSetList.size();
		 List<String> noBaseList = metricMonitorSetService.getNextMetricNoByCurNo(1,cnt);
		 int i=0;
		 for (MetricMonitorSet mset : monitorSetList) {
			 mset.setMtrcCtp(1);
			 setDefaultVale(mset);
			 mset.setMtrcNo(noBaseList.get(i++));
		 }
		 metricMonitorSetService.saveBatch(monitorSetList);
		 return Result.OK("添加成功！");
	 }

	 @PostMapping(value = "/batchImmportCalculate")
	 public Result<String> batchImmportCalculate(@RequestBody List<MetricMonitorSet> monitorSetList) {
		 int cnt = monitorSetList.size();
		 List<String> noComputeList = metricMonitorSetService.getNextMetricNoByCurNo(2,cnt);
		 int i=0;
		 for (MetricMonitorSet mset : monitorSetList) {
			 mset.setMtrcCtp(2);
			 setDefaultVale(mset);
			 mset.setMtrcNo(noComputeList.get(i++));
		 }
		 metricMonitorSetService.saveBatch(monitorSetList);
		 return Result.OK("添加成功！");
	 }

	 private void setDefaultVale(MetricMonitorSet mset) {
		if(mset.getCollFreq()==null) {
			mset.setCollFreq(3);  //3=月
		}
		if(mset.getCreatedUser()==null) {
			mset.setCreatedUser(UserUtil.getUserId());
		}
		if(mset.getCollMethod()==null) {
			mset.setCollFreq(1);
		}

		if(mset.getMtrcTp()==null) {
			mset.setCollFreq(2);
		}

	 }
}
