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


import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
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.component.WebSocketServer;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.modules.experimentalData.domain.TsNodes;
import com.yfd.platform.modules.specialDocument.domain.Nodes;
import com.yfd.platform.modules.specialDocument.service.INodesService;
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.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 专项文档节点表 前端控制器
 * </p>
 *
 * @author LiMengNan
 * @since 2025-01-20
 */
@RestController
@RequestMapping("/specialDocument/sd_nodes")
public class NodesController {

    //专项文档节点服务类
    @Resource
    private INodesService nodesService;

    @Autowired
    private TaskStatusHolder taskStatusHolder;

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

    /**********************************
     * 用途说明: 增加专项文档节点
     * 参数说明  nodes 专项文档节点信息
     * 返回值说明: com.yfd.platform.config.ResponseResult 返回增加成功或者失败
     ***********************************/
    @Log(module = "专项文档管理", value = "增加专项文档节点")
    @PostMapping("/addNodes")
    @ApiOperation("增加专项文档节点")
    @PreAuthorize("@el.check('add:nodes')")
    public ResponseResult addNodes(@RequestBody Nodes nodes) {
        //参数校验 对象    节点名称 所属项目ID
        if (ObjUtil.isEmpty(nodes) && StrUtil.isBlank(nodes.getNodeName()) && StrUtil.isBlank(nodes.getProjectId())) {
            return ResponseResult.error("参数为空");
        }
        return nodesService.addNodes(nodes);
    }

    /**********************************
     * 用途说明: 修改专项文档节点
     * 参数说明  nodes 专项文档节点信息
     * 返回值说明: com.yfd.platform.config.ResponseResult 返回修改成功或者失败
     ***********************************/
    @Log(module = "专项文档管理", value = "修改专项文档节点")
    @PostMapping("/updateNodes")
    @ApiOperation("修改专项文档节点")
    @PreAuthorize("@el.check('update:nodes')")
    public ResponseResult updateNodes(@RequestBody Nodes nodes) {
        //参数校验 对象    节点名称 所属项目ID id
        if (ObjUtil.isEmpty(nodes) && StrUtil.isBlank(nodes.getNodeName()) && StrUtil.isBlank(nodes.getProjectId()) && StrUtil.isBlank(nodes.getId())) {
            return ResponseResult.error("参数为空");
        }
        return nodesService.updateNodes(nodes);
    }

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


    /**********************************
     * 用途说明: 专项文档管理扫描接口
     * 参数说明  id 所属项目ID
     * 返回值说明: com.yfd.platform.config.ResponseResult 返回成功或者失败
     ***********************************/
    @Log(module = "专项文档管理扫描接口", value = "专项文档管理扫描接口！")
    @PostMapping("/specialScanById")
    @ApiOperation("专项文档管理扫描接口通过所属项目ID")
    public ResponseResult specialScanByIdAsync(String id) throws Exception {
        if (StrUtil.isEmpty(id)) {
            return ResponseResult.error("参数为空");
        }
        // 生成唯一Key
        String asyncKey = taskStatusHolder.specialGenerateKey(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)) {
            // 直接异步执行并推送结果
            nodesService.specialScanByIdAsync(id);
            return ResponseResult.success("专项文档扫描任务开始处理!");
        } else {
            return ResponseResult.success("专项文档扫描任务已由其他请求启动!");
        }
    }


    /**********************************
     * 用途说明: 获取异步信息
     * 参数说明  id 所属项目ID
     * 参数说明  type 要查询的信息类型 0扫描  1上传扫描
     * 返回值说明: com.yfd.platform.config.ResponseResult 返回成功或者失败
     * 没有 1
     * 有  0
     ***********************************/
    @Log(module = "获取异步信息", value = "获取异步信息！")
    @PostMapping("/obtainInformationAsync")
    @ApiOperation("获取异步信息")
    public ResponseResult obtainInformationAsync(String id) throws Exception {
        if (StrUtil.isEmpty(id)) {
            return ResponseResult.error("id为空");
        }
        JSONObject jsonObject1 = new JSONObject();
        // 生成唯一Key
        String asyncKey = taskStatusHolder.specialGenerateKey(id);
        // 检查任务是否已存在
        String existingStatus = taskStatusHolder.getStatus(asyncKey);
        if ("TASK_NOT_FOUND".equals(existingStatus)) {

            jsonObject1.putOpt("status", "1");
            jsonObject1.putOpt("name", "扫描");
            return ResponseResult.successData(jsonObject1);
        }
        if ("IN_PROGRESS".equals(existingStatus)) {
            jsonObject1.putOpt("status", "0");
            jsonObject1.putOpt("name", "扫描");
            return ResponseResult.successData(jsonObject1);
        } else if ("COMPLETED".equals(existingStatus)) {
            jsonObject1.putOpt("status", "1");
            jsonObject1.putOpt("name", "扫描");
            return ResponseResult.successData(jsonObject1);
        }

        // 上传生成唯一Key
        String asyncKeySc = taskStatusHolder.documentUploadKey(id);
        // 检查任务是否已存在
        String existingStatusSc = taskStatusHolder.getStatus(asyncKeySc);
        if ("TASK_NOT_FOUND".equals(existingStatusSc)) {

            jsonObject1.putOpt("status", "1");
            jsonObject1.putOpt("name", "上传");
            return ResponseResult.successData(jsonObject1);
        }
        if ("IN_PROGRESS".equals(existingStatusSc)) {
            jsonObject1.putOpt("status", "0");
            jsonObject1.putOpt("name", "上传");
            return ResponseResult.successData(jsonObject1);
        } else if ("COMPLETED".equals(existingStatusSc)) {
            jsonObject1.putOpt("status", "1");
            jsonObject1.putOpt("name", "上传");
            return ResponseResult.successData(jsonObject1);
        }
        return null;
    }


    /**********************************
     * 用途说明: 专项文档管理文档上传接口
     * 参数说明  id 所属项目ID
     * 返回值说明: com.yfd.platform.config.ResponseResult 返回成功或者失败
     ***********************************/
    @Log(module = "专项文档管理文档上传", value = "专项文档管理文档上传接口！")
    @PostMapping("/documentUploadById")
    @ApiOperation("专项文档管理文档上传接口通过所属项目ID")
    public ResponseResult documentUploadByIdAsync(String id, String fileName) throws Exception {
        if (StrUtil.isEmpty(id)) {
            return ResponseResult.error("参数为空");
        }

        if (StrUtil.isEmpty(fileName)) {
            return ResponseResult.error("参数为空");
        }


        // 生成唯一Key
        String asyncKey = taskStatusHolder.documentUploadKey(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)) {
            // 直接异步执行并推送结果
            nodesService.documentUploadByIdAsync(id, fileName);
            return ResponseResult.success("专项文档上传任务开始处理!");
        } else {
            return ResponseResult.success("专项文档上传任务已由其他请求启动");
        }
    }


    /**********************************
     * 用途说明: 查询可不可以初始化专项文档扫描
     * 参数说明  projectId 所属项目ID
     * 返回值说明: com.yfd.platform.config.ResponseResult
     ***********************************/
    @Log(module = "查询可不可以初始化专项文档扫描", value = "查询可不可以初始化专项文档扫描!")
    @PostMapping("/selectNodesByProjectId")
    @ApiOperation("查询可不可以初始化专项文档扫描")
    public ResponseResult selectNodesByProjectId( String projectId) {
        if (StrUtil.isBlank(projectId)) {
            return ResponseResult.error("参数为空");
        }
        List<Nodes> nodesList = nodesService.list(new QueryWrapper<Nodes>().eq("project_id", projectId));
        //如果节点不为空 就不能初始化了
        if (nodesList.size()>0) {
            return ResponseResult.success("该项目已经初始化完成，局部更新请选择节点上传文件!");
        } else {
            return ResponseResult.success("可以初始化！");
        }
    }

}
