package com.yfd.platform.modules.experimentalData.controller;


import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yfd.platform.annotation.Log;
import com.yfd.platform.component.TaskStatusHolder;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.modules.experimentalData.domain.TsNodes;
import com.yfd.platform.modules.experimentalData.service.ITsNodesService;
import com.yfd.platform.modules.experimentalData.service.ITsTaskService;
import com.yfd.platform.modules.specialDocument.domain.Nodes;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 试验任务节点表 前端控制器
 * </p>
 *
 * @author LiMengNan
 * @since 2025-01-21
 */
@RestController
@RequestMapping("/experimentalData/ts-nodes")
public class TsNodesController {


    //试验任务节点服务类
    @Resource
    private ITsNodesService tsNodesService;


    @Autowired
    private TaskStatusHolder taskStatusHolder;


    /***********************************
     * 用途说明：获取试验任务节点 树形结构
     * 参数说明
     *  nodeName        节点名称
     *  taskId        所属任务ID
     * 返回值说明:  专项文档节点树形结构
     ***********************************/
    @Log(module = "试验数据管理", value = "获取试验任务节点树形结构!")
    @PostMapping("/getTsNodesTree")
    @ApiOperation("获取试验任务节点树形结构")
    @ResponseBody
    @PreAuthorize("@el.check('select:tsnodes')")
    public ResponseResult getTsNodesTree(String nodeName, String taskId) {
        List<Map<String, Object>> list = tsNodesService.getTsNodesTree(nodeName, taskId);
        return ResponseResult.successData(list);
    }

    /**********************************
     * 用途说明: 增加试验任务节点
     * 参数说明  tsnodes  试验任务节点信息
     * 返回值说明: com.yfd.platform.config.ResponseResult 返回增加成功或者失败
     ***********************************/
    @Log(module = "试验数据管理", value = "增加试验任务节点!")
    @PostMapping("/addTsNodes")
    @ApiOperation("增加试验任务节点")
    @PreAuthorize("@el.check('add:tsnodes')")
    public ResponseResult addTsNodes(@RequestBody TsNodes tsnodes) {
        //参数校验 对象    节点名称 所属任务ID
        if (ObjUtil.isEmpty(tsnodes) && StrUtil.isBlank(tsnodes.getNodeName()) && StrUtil.isBlank(tsnodes.getTaskId())) {
            return ResponseResult.error("参数为空");
        }
        return tsNodesService.addTsNodes(tsnodes);
    }


    /**********************************
     * 用途说明: 修改试验任务节点
     * 参数说明  tsnodes  试验任务节点信息
     * 返回值说明: com.yfd.platform.config.ResponseResult 返回修改成功或者失败
     ***********************************/
    @Log(module = "试验数据管理", value = "修改试验任务节点!")
    @PostMapping("/updateTsNodes")
    @ApiOperation("修改试验任务节点")
    @PreAuthorize("@el.check('update:tsnodes')")
    public ResponseResult updateTsNodes(@RequestBody TsNodes tsnodes) {
        //参数校验 对象    节点名称 所属任务ID id
        if (ObjUtil.isEmpty(tsnodes) && StrUtil.isBlank(tsnodes.getNodeName()) && StrUtil.isBlank(tsnodes.getTaskId()) && StrUtil.isBlank(tsnodes.getNodeId())) {
            return ResponseResult.error("参数为空");
        }
        return tsNodesService.updateTsNodes(tsnodes);
    }

    /**********************************
     * 用途说明: 根据ID删除试验任务节点
     * 参数说明  id 试验任务节点ID
     * 参数说明  path 路径
     * 返回值说明: com.yfd.platform.config.ResponseResult 返回删除成功或者失败
     ***********************************/
    @Log(module = "试验数据管理", value = "根据ID删除试验任务节点!")
    @PostMapping("/deleteTsNodesById")
    @ApiOperation("根据ID删除试验任务节点")
    @PreAuthorize("@el.check('del:tsnodes')")
    public ResponseResult deleteTsNodesById(@RequestParam String id, String path) {
        if (StrUtil.isBlank(id)) {
            return ResponseResult.error("参数为空");
        }
        boolean isOk = tsNodesService.deleteTsNodesById(id, path);
        if (isOk) {
            return ResponseResult.success();
        } else {
            return ResponseResult.error();
        }
    }


    /**********************************
     * 用途说明: 试验数据扫描接口
     * 参数说明  id 试验任务ID
     * 返回值说明: com.yfd.platform.config.ResponseResult 返回成功或者失败
     ***********************************/
    @Log(module = "试验数据扫描接口", value = "试验数据扫描接口！")
    @PostMapping("/testDataScanById")
    @ApiOperation("试验数据扫描接口通过试验任务ID")
    public ResponseResult testDataScanByIdAsync(String id) throws Exception {
        if (StrUtil.isEmpty(id)) {
            return ResponseResult.error("参数为空");
        }
        // 生成唯一Key
        String asyncKey = taskStatusHolder.testDatascanKey(id);

        // 检查任务是否已存在
        String existingStatus = taskStatusHolder.getStatus(asyncKey);
        if ("IN_PROGRESS".equals(existingStatus)) {
            return ResponseResult.success("试验数据扫描任务正在处理中!");
        } else if ("COMPLETED".equals(existingStatus)) {
            return ResponseResult.success("验数据扫描任务已完成!");
        }
        // 原子性启动新任务
        if (taskStatusHolder.startTaskIfAbsent(asyncKey)) {
            // 直接异步执行并推送结果
            tsNodesService.testDataScanByIdAsync(id);
            return ResponseResult.success("验数据扫描任务开始处理!");
        } else {
            return ResponseResult.success("验数据扫描任务已由其他请求启动!");
        }
    }

    /**********************************
     * 用途说明: 获取异步信息
     * 参数说明  id 所属项目ID
     * 返回值说明: com.yfd.platform.config.ResponseResult 返回成功或者失败
     ***********************************/
    @Log(module = "获取异步信息", value = "获取异步信息！")
    @PostMapping("/obtaintestData")
    @ApiOperation("获取异步信息")
    public ResponseResult obtaintestData(String id) throws Exception {
        if (StrUtil.isEmpty(id)) {
            return ResponseResult.error("id为空");
        }
        JSONObject jsonObject1 = new JSONObject();

        // 生成唯一Key
        String asyncKey = taskStatusHolder.testDatascanKey(id);

        // 检查任务是否已存在
        String existingStatus = taskStatusHolder.getStatus(asyncKey);
        if ("TASK_NOT_FOUND".equals(existingStatus)) {
            jsonObject1.putOpt("status", "1");
            return ResponseResult.successData(jsonObject1);
        }
        if ("IN_PROGRESS".equals(existingStatus)) {
            jsonObject1.putOpt("status", "0");
            return ResponseResult.successData(jsonObject1);
        } else if ("COMPLETED".equals(existingStatus)) {
            jsonObject1.putOpt("status", "1");
            return ResponseResult.successData(jsonObject1);
        }

        return null;
    }



    /**********************************
     * 用途说明: 查询可不可以初始化试验任务扫描
     * 参数说明  taskId 试验任务ID
     * 返回值说明: com.yfd.platform.config.ResponseResult
     ***********************************/
    @Log(module = "查询可不可以初始化试验任务扫描", value = "查询可不可以初始化试验任务扫描!")
    @PostMapping("/selectTsNodesByTskeId")
    @ApiOperation("查询可不可以初始化试验任务扫描")
    @PreAuthorize("@el.check('del:tsnodes')")
    public ResponseResult selectTsNodesByTskeId( String taskId) {
        if (StrUtil.isBlank(taskId)) {
            return ResponseResult.error("参数为空");
        }
        List<TsNodes> tsNodesList = tsNodesService.list(new QueryWrapper<TsNodes>().eq("task_id", taskId));
        //如果节点不为空 就不能初始化了
        if (tsNodesList.size()>0) {
            return ResponseResult.success("该项目已经初始化完成，局部更新请选择节点上传文件!");
        } else {
            return ResponseResult.success("可以初始化！");
        }
    }

}
