package com.xvji.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xvji.common.core.domain.AjaxResult;
import com.xvji.domain.Component;
import com.xvji.domain.TrainTask;
import com.xvji.domain.vo.PageResult;
import com.xvji.domain.vo.TrainTaskVO;
import com.xvji.mapper.TrainTaskMapper;
import com.xvji.service.ComponentService;
import com.xvji.service.TrainTaskService;
import org.aspectj.weaver.loadtime.Aj;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.BeanUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

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

/**
 * 训练任务控制器（兼容非Boolean类型enable，修复强转漏洞）
 */
@RestController
@RequestMapping("/task/train")
public class TrainTaskController {

    private static final Logger log = LoggerFactory.getLogger(TrainTaskController.class);

    @Autowired
    private TrainTaskService trainTaskService;

    @Autowired
    private ComponentService componentService;

    @Autowired
    private TrainTaskMapper trainTaskMapper;

    /**
     * 新增训练任务及关联组件
     */
    @PostMapping("/addTask")
    @Transactional
    public AjaxResult addTrainTask(@RequestBody Map<String, Object> taskInfo) {
        try {
            TrainTask task = new TrainTask();
            task.setTTaskName((String) taskInfo.get("tTaskName"));
            task.setTCronExpression((String) taskInfo.get("tCronExpression"));
            task.setTQuartzTask((String) taskInfo.get("tQuartzTask"));
            task.setTRunInfo((String) taskInfo.get("tRunInfo"));
            task.setTAnalysisReport((String) taskInfo.get("tAnalysisReport"));

//            Object taskStatusObj = taskInfo.get("tTaskStatus");
//            if (taskStatusObj != null){
//                try {
//                    Integer tTaskStatus = Integer.parseInt(taskStatusObj.toString());
//                    if (tTaskStatus != 0 && tTaskStatus != 1 && tTaskStatus != 2) {
//                        return AjaxResult.error("任务状态必须是0,1,2，请检查输入");
//                    }
//                    task.setTTaskStatus(tTaskStatus);
//                }catch (Exception e){
//                    return AjaxResult.error("传入的任务状态格式不正确");
//                }
//            }

            Object tTaskIdObj = taskInfo.get("tTaskId");
            Long manualTaskId = null;
            if (tTaskIdObj != null) {
                try {
                    manualTaskId = Long.parseLong(tTaskIdObj.toString());
                } catch (NumberFormatException e) {
                    return AjaxResult.error("传入的任务ID格式不正确，请传数字类型");
                }
                TrainTask existTask = trainTaskMapper.selectById(manualTaskId);
                if (existTask != null) {
                    return AjaxResult.error("任务ID已存在：" + manualTaskId + "，请更换其他ID");
                }
                task.setTTaskId(manualTaskId);
            }

            // 保存训练任务主表
            boolean taskAdded = trainTaskService.save(task);
            if (!taskAdded) {
                return AjaxResult.error("训练任务新增失败");
            }

            Long taskId = task.getTTaskId();
            List<Long> componentIds = new ArrayList<>();

            // 1. 数据获取组件
            Map<String, Object> dataAcquisition = (Map<String, Object>) taskInfo.get("dataAcquisition");
            if (dataAcquisition != null) {
                Boolean isEnable = parseEnableValue(dataAcquisition.get("isEnable"), "数据获取");
                String type = (String) dataAcquisition.get("componentType");
                String url = "http://ds3:10001/mysql_to_mongo";
                Component component = createComponent(taskId, type, dataAcquisition, isEnable ,url);
                if (componentService.save(component)) {
                    componentIds.add(component.getComponentId());
                } else {
                    throw new RuntimeException("数据获取组件保存失败");
                }
            }

            // 2. 数据处理组件
            Map<String, Object> dataCleaning = (Map<String, Object>) taskInfo.get("dataCleaning");
            if (dataCleaning != null) {
                Boolean isEnable = parseEnableValue(dataCleaning.get("isEnable"), "数据处理");
                String type = (String) dataCleaning.get("componentType");
                String url = "http://ds3:10013/pre_process";
                Component component = createComponent(taskId, type, dataCleaning, isEnable , url);
                if (componentService.save(component)) {
                    componentIds.add(component.getComponentId());
                } else {
                    throw new RuntimeException("数据处理组件保存失败");
                }
            }

            // 3. 限电清洗组件
            Map<String, Object> powerRationing = (Map<String, Object>) taskInfo.get("powerRationing");
            if (powerRationing != null) {
                Boolean isEnable = parseEnableValue(powerRationing.get("isEnable"), "限电清洗");
                String type = (String) powerRationing.get("componentType");
                String url = "";
                if ("限电清洗-光伏".equals(type)){
                    url = "http://ds3:10008/processing_limit_power_by_statistics_light";
                }else if ("限电清洗-风电".equals(type)){
                    url = "http://ds3:10009/processing_limit_power_by_statistics_wind";
                }
                Component component = createComponent(taskId, type, powerRationing, isEnable , url);
                if (componentService.save(component)) {
                    componentIds.add(component.getComponentId());
                } else {
                    throw new RuntimeException("限电清洗组件保存失败");
                }
            }

            // 4. 模型组件 + 关联模型测试组件
            Map<String, Object> model = (Map<String, Object>) taskInfo.get("model");
            if (model != null) {
                Boolean modelIsEnable = parseEnableValue(model.get("isEnable"), "模型");
                String modelType = (String) model.get("componentType");
                String url = "";
                if ("光伏物理模型".equals(modelType)){
                    url = "http://ds3:10014/model_prediction_photovoltaic_physical";
                }else if ("风电物理模型".equals(modelType)){
                    url = "http://ds3:10014/model_prediction_wind_physical";
                }else if ("Holtwinters模型".equals(modelType)){
                    url = "http://ds3:10007/model_prediction_holtwinters";
                }else if ("LSTM-训练".equals(modelType)){
                    url = "http://ds3:10003/tf_lstm_training";
                }else if ("机器学习模型-训练".equals(modelType)){
                    url = "http://ds3:10005/model_training_ml";
                }
                Component modelComponent = createComponent(taskId, modelType, model, modelIsEnable,url);
                if (componentService.save(modelComponent)) {
                    componentIds.add(modelComponent.getComponentId());

                    // 训练类模型关联测试组件
                    if ("LSTM-训练".equals(modelType) || "机器学习模型-训练".equals(modelType)) {
                        Map<String, Object> modelTest = (Map<String, Object>) taskInfo.get("modelTest");
                        if (modelTest != null) {
                            Boolean testIsEnable = parseEnableValue(modelTest.get("isEnable"), "模型测试");
                            String testType = (String) modelTest.get("componentType");
                            //暂无测试模型接口
                            Component testComponent = createComponent(taskId, testType, modelTest, testIsEnable , url);
                            if (componentService.save(testComponent)) {
                                componentIds.add(testComponent.getComponentId());
                            } else {
                                throw new RuntimeException(testType + "组件保存失败");
                            }
                        }
                    }
                } else {
                    throw new RuntimeException(modelType + "组件保存失败");
                }
            }

            // 5. 后处理组件
            Map<String, Object> postProcessing = (Map<String, Object>) taskInfo.get("processing");
            if (postProcessing != null) {
                Boolean isEnable = parseEnableValue(postProcessing.get("isEnable"), "后处理");
                String type = (String) postProcessing.get("componentType");
                String url = "http://ds3:10013/post_process";
                Component component = createComponent(taskId, type, postProcessing, isEnable , url);
                if (componentService.save(component)) {
                    componentIds.add(component.getComponentId());
                } else {
                    throw new RuntimeException("后处理组件保存失败");
                }
            }

            // 6. 分析报告组件
            Map<String, Object> analysisReport = (Map<String, Object>) taskInfo.get("report");
            if (analysisReport != null) {
                Boolean isEnable = parseEnableValue(analysisReport.get("isEnable"), "分析报告");
                String type = (String) analysisReport.get("componentType");
                String url = "http://ds3:10012/analysis_report_small";
                Component component = createComponent(taskId, type, analysisReport, isEnable , url);
                if (componentService.save(component)) {
                    componentIds.add(component.getComponentId());
                } else {
                    throw new RuntimeException("分析报告组件保存失败");
                }
            }

            // 更新任务关联组件ID
            if (!componentIds.isEmpty()) {
                String componentIdsStr = componentIds.stream()
                        .map(String::valueOf)
                        .collect(java.util.stream.Collectors.joining(","));
                task.setTComponentIds(componentIdsStr);
                trainTaskService.updateById(task);
            }

            return AjaxResult.success("训练任务新增成功");
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("新增失败：" + e.getMessage());
        }
    }

    /**
     * 查询所有任务以及组件参数
     * @param pageNum
     * @param pageSize
     * @param taskName
     * @return
     */
    @GetMapping("/queryTasks")
    public AjaxResult queryTrainTasks(
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize,
            @RequestParam(required = false) String taskName) {

        try {
            Page<TrainTask> page = new Page<>(pageNum, pageSize);
            QueryWrapper<TrainTask> queryWrapper = new QueryWrapper<>();
            if (StringUtils.hasText(taskName)) {
                queryWrapper.like("T_TASK_NAME", taskName);
            }
            queryWrapper.orderByDesc("T_CREATE_TIME");

            Page<TrainTask> taskPage = trainTaskService.page(page, queryWrapper);
            List<TrainTaskVO> taskVOList = taskPage.getRecords().stream().map(task -> {
                TrainTaskVO vo = new TrainTaskVO();
                BeanUtils.copyProperties(task, vo);

                // 关键修改：将分析报告值添加到VO中，前端列表可直接获取
                vo.setTAnalysisReport(task.getTAnalysisReport());

                // 解析组件ID并查询组件（原有逻辑）
                String componentIds = task.getTComponentIds();
                if (StringUtils.hasText(componentIds)) {
                    List<Long> ids = Arrays.stream(componentIds.split(","))
                            .map(Long::parseLong)
                            .collect(Collectors.toList());
                    List<Component> components = componentService.listByIds(ids);
                    vo.setComponents(components);
                }
                return vo;
            }).collect(Collectors.toList());

            PageResult<TrainTaskVO> result = new PageResult<>(
                    taskPage.getTotal(),
                    pageNum,
                    pageSize,
                    taskVOList
            );

            return AjaxResult.success(result);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("查询训练任务失败：" + e.getMessage());
        }
    }

    /**
     * 删除任务
     * @param tTaskId
     * @return
     */
    @DeleteMapping("/{tTaskId}")
    public AjaxResult deleteById(@PathVariable Long tTaskId){

        try {
            Boolean result = trainTaskService.deleteTrainTaskWithComponents(tTaskId);
            if (result){
                return AjaxResult.success("训练任务删除成功");
            }else {
                return AjaxResult.error("训练任务id不存在");
            }

        }catch (Exception e){
            return AjaxResult.error("训练任务删除失败" + e.getMessage());
        }
    }


    /**
     * 编辑训练任务
     * @param taskInfo
     * @return
     */
    @Transactional
    @PostMapping("/updateTask")
    public AjaxResult updateTask(@RequestBody Map<String , Object> taskInfo){

        try {
            TrainTask task = new TrainTask();
            if (taskInfo == null){
                return AjaxResult.error("训练任务不存在 , 无法编辑");
            }
            Object tTaskIdObj = taskInfo.get("tTaskId");
            if (tTaskIdObj == null){
                return AjaxResult.error("训练任务id不能为空");
            }
            Long tTaskId = null;
            try {
                tTaskId = Long.parseLong(tTaskIdObj.toString());
            } catch (NumberFormatException e) {
                return AjaxResult.error("传入的任务ID格式不正确，请传数字类型");
            }

            Object taskStatusObj = taskInfo.get("tTaskStatus");
//            Integer tTaskStatus = null;
//            if (taskStatusObj != null){
//                try {
//                    tTaskStatus = Integer.parseInt(taskStatusObj.toString());
//                    if (tTaskStatus != 0 && tTaskStatus != 1 && tTaskStatus != 2) {
//                        return AjaxResult.error("任务状态必须是0,1,2，请检查输入");
//                    }
//                }catch (Exception e){
//                    return AjaxResult.error("传入的任务状态格式不正确");
//                }
//            }

            task.setTTaskName((String) taskInfo.get("tTaskName"));
            task.setTCronExpression((String) taskInfo.get("tCronExpression"));
            task.setTQuartzTask((String) taskInfo.get("tQuartzTask"));
            task.setTRunInfo((String) taskInfo.get("tRunInfo"));
            task.setTAnalysisReport((String) taskInfo.get("tAnalysisReport"));
//            task.setTTaskStatus(tTaskStatus);
            task.setTTaskId(tTaskId);
            boolean updateTask = trainTaskService.updateById(task);
            if (!updateTask){
                return AjaxResult.error("更新训练任务失败");
            }

            // 先删除原关联组件
            QueryWrapper<Component> componentWrapper = new QueryWrapper<>();
            componentWrapper.eq("TASK_ID", tTaskId)
                    .eq("TASK_TYPE", 0);
            componentService.remove(componentWrapper);

            List<Long> componentIds = new ArrayList<>();

            // 1. 数据获取组件
            Map<String, Object> dataAcquisition = (Map<String, Object>) taskInfo.get("dataAcquisition");
            if (dataAcquisition != null) {
                Boolean isEnable = parseEnableValue(dataAcquisition.get("isEnable"), "数据获取");
                String type = (String) dataAcquisition.get("componentType");
                String url = "http://ds3:10001/mysql_to_mongo";
                Component component = createComponent(tTaskId, type, dataAcquisition, isEnable ,url);
                if (componentService.save(component)) {
                    componentIds.add(component.getComponentId());
                } else {
                    throw new RuntimeException("数据获取组件保存失败");
                }
            }

            // 2. 数据处理组件
            Map<String, Object> dataCleaning = (Map<String, Object>) taskInfo.get("dataCleaning");
            if (dataCleaning != null) {
                Boolean isEnable = parseEnableValue(dataCleaning.get("isEnable"), "数据处理");
                String type = (String) dataCleaning.get("componentType");
                String url = "http://ds3:10013/pre_process";
                Component component = createComponent(tTaskId, type, dataCleaning, isEnable , url);
                if (componentService.save(component)) {
                    componentIds.add(component.getComponentId());
                } else {
                    throw new RuntimeException("数据处理组件保存失败");
                }
            }

            // 3. 限电清洗组件
            Map<String, Object> powerRationing = (Map<String, Object>) taskInfo.get("powerRationing");
            if (powerRationing != null) {
                Boolean isEnable = parseEnableValue(powerRationing.get("isEnable"), "限电清洗");
                String type = (String) powerRationing.get("componentType");
                String url = "";
                if ("限电清洗-光伏".equals(type)){
                    url = "http://ds3:10008/processing_limit_power_by_statistics_light";
                }else if ("限电清洗-风电".equals(type)){
                    url = "http://ds3:10009/processing_limit_power_by_statistics_wind";
                }
                Component component = createComponent(tTaskId, type, powerRationing, isEnable , url);
                if (componentService.save(component)) {
                    componentIds.add(component.getComponentId());
                } else {
                    throw new RuntimeException("限电清洗组件保存失败");
                }
            }

            // 4. 模型组件 + 关联模型测试组件
            Map<String, Object> model = (Map<String, Object>) taskInfo.get("model");
            if (model != null) {
                Boolean modelIsEnable = parseEnableValue(model.get("isEnable"), "模型");
                String modelType = (String) model.get("componentType");
                String url = "";
                if ("光伏物理模型".equals(modelType)){
                    url = "http://ds3:10014/model_prediction_photovoltaic_physical";
                }else if ("风电物理模型".equals(modelType)){
                    url = "http://ds3:10014/model_prediction_wind_physical";
                }else if ("Holtwinters模型".equals(modelType)){
                    url = "http://ds3:10007/model_prediction_holtwinters";
                }else if ("LSTM-训练".equals(modelType)){
                    url = "http://ds3:10003/tf_lstm_training";
                }else if ("机器学习模型-训练".equals(modelType)){
                    url = "http://ds3:10005/model_training_ml";
                }
                Component modelComponent = createComponent(tTaskId, modelType, model, modelIsEnable,url);
                if (componentService.save(modelComponent)) {
                    componentIds.add(modelComponent.getComponentId());

                    // 训练类模型关联测试组件
                    if ("LSTM-训练".equals(modelType) || "机器学习模型-训练".equals(modelType)) {
                        Map<String, Object> modelTest = (Map<String, Object>) taskInfo.get("modelTest");
                        if (modelTest != null) {
                            Boolean testIsEnable = parseEnableValue(modelTest.get("isEnable"), "模型测试");
                            String testType = (String) modelTest.get("componentType");
                            //暂无测试模型接口
                            Component testComponent = createComponent(tTaskId, testType, modelTest, testIsEnable , url);
                            if (componentService.save(testComponent)) {
                                componentIds.add(testComponent.getComponentId());
                            } else {
                                throw new RuntimeException(testType + "组件保存失败");
                            }
                        }
                    }
                } else {
                    throw new RuntimeException(modelType + "组件保存失败");
                }
            }

            // 5. 后处理组件
            Map<String, Object> postProcessing = (Map<String, Object>) taskInfo.get("processing");
            if (postProcessing != null) {
                Boolean isEnable = parseEnableValue(postProcessing.get("isEnable"), "后处理");
                String type = (String) postProcessing.get("componentType");
                String url = "";
                if ("后处理".equals(type)){
                    url = "http://ds3:10013/post_process";
                }
                Component component = createComponent(tTaskId, type, postProcessing, isEnable , url);
                if (componentService.save(component)) {
                    componentIds.add(component.getComponentId());
                } else {
                    throw new RuntimeException("后处理组件保存失败");
                }
            }

            // 6. 分析报告组件
            Map<String, Object> analysisReport = (Map<String, Object>) taskInfo.get("report");
            if (analysisReport != null) {
                Boolean isEnable = parseEnableValue(analysisReport.get("isEnable"), "分析报告");
                String type = (String) analysisReport.get("componentType");
                String url = "";
                if ("分析报告".equals(type)){
                    url = "http://ds3:10012/analysis_report_small";
                }
                Component component = createComponent(tTaskId, type, analysisReport, isEnable , url);
                if (componentService.save(component)) {
                    componentIds.add(component.getComponentId());
                } else {
                    throw new RuntimeException("分析报告组件保存失败");
                }
            }

            // 更新任务关联组件ID
            if (!componentIds.isEmpty()) {
                String componentIdsStr = componentIds.stream()
                        .map(String::valueOf)
                        .collect(java.util.stream.Collectors.joining(","));
                task.setTComponentIds(componentIdsStr);
                trainTaskService.updateById(task);
            }


            return AjaxResult.success("更新训练任务成功");
        }catch (Exception e){
            e.printStackTrace();
            return AjaxResult.error("更新训练任务失败" + e.getMessage());
        }
    }

    ///////////////////////////////////////////////////////////////////////////
    /**
     * 使用解析后的isEnable，删除错误强转
     */
    private Component createComponent(Long taskId, String componentType, Map<String, Object> config, Boolean isEnable , String url) {
        Component component = new Component();
        component.setTaskId(taskId);
        component.setTaskType(0); // 训练任务固定标识
        component.setComponentType(componentType);
        component.setParamsMap((Map<String, Object>) config.get("params")); // 组件参数
        component.setIsEnable(isEnable); // 仅使用解析后的isEnable值，无强转
        component.setInterfaceUrl(url); // 接口地址
        return component;
    }

    /**
     * 统一解析isEnable值，兼容非Boolean类型
     */
    private Boolean parseEnableValue(Object enableObj, String componentName) {
        if (enableObj instanceof Boolean) {
            return (Boolean) enableObj;
        }
        // 非Boolean类型或null，默认false并记录日志
        if (enableObj != null) {
            log.warn("组件[{}]的enable参数类型错误非boolean类型，实际类型为{} 值{}，默认设为false",
                    componentName, enableObj.getClass().getSimpleName(), enableObj);
        } else {
            log.warn("组件[{}]未传递enable参数，已默认设为false", componentName);
        }
        return false;
    }

}