{% extends 'base.html' %}

{% block title %}ZFSAFE{% endblock %}

<!-- 在此处可添加样式文件 -->
{% block style_link %}
<link href="{{ url_for('main.static', filename='css/node_tree.css') }}" rel="stylesheet">
{% endblock %}

<!-- 页面样式块 -->
{% block style %}

    /* 查询条件区域:使用 row 分布,输入框占满所在列 */
    .search-section .form-control,
    .search-section .form-select {
      width: 100%;
    }
    /* 查询条件区域,每个条件统一高度且左右间隔均等 */
    .search-section .col {
      padding: 0 5px;
    }

    /* 表格样式:统一垂直居中 */
    .table thead th, .table tbody td {
      vertical-align: middle;
      text-align: center;
    }

    /* 分页区域右对齐 */
    .pagination-section {
      text-align: right;
      padding-right: 15px;
    }

    /* 固定行高,比如 45px,每页 10 行 */
    .fixed-row-height {
      height: 45px;
      overflow: hidden;
    }

    .tab-wrapper {
      max-height: calc(100vh - 60px - 56px - 66px - 14px);
      overflow: hidden; /* 防止溢出 */
    }

    .tab-content {
      max-height: calc(100vh - 60px - 56px - 66px  - 14px - 42px);
      overflow: hidden; /* 防止溢出 */
    }
    .tab-pane {
      max-height: calc(100vh - 60px - 56px - 66px  - 14px - 42px);
      overflow-x: hidden;
      overflow-y: auto;

    .row {
      max-height: calc(100vh - 60px - 56px - 66px  - 14px - 42px - 35px);
      overflow: hidden; /* 防止溢出 */
    }

    .his-node-tree-area {
      width: 100%;
      max-height: calc(100vh - 60px - 56px - 66px  - 14px - 42px - 35px);
      border: 1px solid #ddd;
      /* overflow: hidden; 超出时出现滚动条 */
      overflow-x: auto;
      overflow-y: hidden;
      background-color: #f8f9fa;
      text-align: center; /* 内部 inline-block 居中 */
      position: relative;
    }

    /* 树节点内容区域,不包含刷新按钮 */
    .his-tree-content {
      max-height: calc(100vh - 60px - 56px - 66px  - 14px - 42px - 35px);
      overflow-x: auto;
      overflow-y: auto;
      padding-top: 5px; /* 留出顶部刷新按钮位置 */
      /* 关键一行:至少宽度撑满其内部内容 */
      min-width: max-content;
    }

    /* 这里设置页码按钮样式(可根据需要调整) */
    .pagination {
      margin: 0;
    }
    .disabled-btn {
      /* 禁用状态样式 */
      background-color: #cccccc;  /* 灰色背景 */
      color: #666666;             /* 文字颜色变浅 */
      cursor: not-allowed;        /* 鼠标显示禁用图标 */
      opacity: 0.7;               /* 可选:降低透明度 */

      /* 禁用点击事件(通过 disabled 属性已实现,此样式仅增强视觉效果) */
      pointer-events: none;       /* 可选:彻底阻止鼠标事件 */
    }

    .offcanvas-backdrop.show {
      z-index: 1055;
    }

    /* 再把 offcanvas 本身提到更高,超过 modal(modal 是 1055) */
    .offcanvas.show {
      z-index: 1060;
    }
    /* 让所有右侧 offcanvas-end 都变成 60% 宽 */
    .offcanvas.offcanvas-end {
      width: 60% !important;
      max-width: none;    /* 取消默认 max-width */
    }
{% endblock %}

<!-- 页面内容块 -->
{% block content %}

  <div class="container">
    <!-- 查询条件区域 -->
    <div class="search-section mb-3">
      <form class="row g-3 align-items-center">
        <!-- 每个输入框直接使用 placeholder 显示标题,水平分布 -->
        <div class="col-3">
          <input type="text" class="form-control" id="testTarget" name="target" placeholder="检测目标">
        </div>
        <div class="col-2">
          <select class="form-select" id="riskLevel" name="risk_level">
            <option value="">风险级别</option>
            <option value="0">0</option>
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
            <option value="4">4</option>
            <option value="5">5</option>
            <option value="6">6</option>
            <option value="7">7</option>
            <option value="8">8</option>
            <option value="9">9</option>
          </select>
        </div>
        <div class="col-2">
          <select class="form-select" id="useModel" name="model">
            <option value="">使用模型</option>
            <option value="1">DeepSeek</option>
            <option value="2">GPT-O3</option>
            <option value="4">Qwen3</option>
          </select>
        </div>
        <div class="col-2" >
          <input type="date" id="startTime" class="form-control" name="start_time" placeholder="开始时间">
        </div>
        <div class="col-2">
          <input type="date" id="endTime" class="form-control" name="end_time" placeholder="结束时间">
        </div>
        <div class="col-auto">
          <button type="button" class="btn btn-primary" id="btnQuery">查询</button>
        </div>
      </form>
    </div>

    <!-- 表格区域 -->
    <div class="table-section mb-3">
      <table class="table table-bordered table-hover" id="histasksTable" style="width: 100%; table-layout: fixed;">
        <thead class="table-light">
          <tr>
            <th style="width: 5%;">ID</th>
            <th style="width: 20%;">检测目标</th>
            <th style="width: 15%;">开始时间</th>
            <th style="width: 15%;">结束时间</th>
            <th style="width: 10%;">风险等级</th>
            <th style="width: 15%;">使用模型</th>
            <th style="width: 20%;">操作</th>
          </tr>
        </thead>
        <tbody id="histasksTbody">
          <!-- 数据由JS动态填充,固定10行一页 -->
        </tbody>
      </table>
    </div>

    <!-- 分页控件区域 -->
    <div class="pagination-section mb-3">
      <nav>
        <ul class="pagination pagination-sm justify-content-end" id="histasksPagination">
          <li class="page-item">
            <a class="page-link" href="#" id="prevPage">上一页</a>
          </li>
          <!-- 页码动态生成 -->
          <li class="page-item">
            <a class="page-link" href="#" id="nextPage">下一页</a>
          </li>
        </ul>
      </nav>
    </div>
  </div>

  <!-- 模态框:显示 task_manager.html 中的中间 tab 页内容 -->
  <!-- 这里只显示节点树、测试指令、漏洞数据三个 tab 页 -->
  <div class="modal fade" id="viewModal" tabindex="-1" aria-labelledby="viewModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-xl">
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title" id="viewModalLabel">任务详情</h5>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="关闭"></button>
        </div>
        <div class="modal-body p-0">
          <!-- 这里仅嵌入中间 tab 页部分 -->
          <div class="tab-wrapper">
            <ul class="nav nav-tabs" id="myTab" role="tablist">
              <li class="nav-item" role="presentation">
                <button class="nav-link active" id="nodeTreeTab" data-bs-toggle="tab" data-bs-target="#nodeTree" type="button" role="tab" aria-controls="nodeTree" aria-selected="true">
                  节点树
                </button>
              </li>
              <li class="nav-item" role="presentation">
                <button class="nav-link" id="testInstructionsTab" data-bs-toggle="tab" data-bs-target="#testInstructions" type="button" role="tab" aria-controls="testInstructions" aria-selected="false">
                  测试指令
                </button>
              </li>
              <li class="nav-item" role="presentation">
                <button class="nav-link" id="vulnerabilitiesTab" data-bs-toggle="tab" data-bs-target="#vulnerabilities" type="button" role="tab" aria-controls="vulnerabilities" aria-selected="false">
                  漏洞数据
                </button>
              </li>
            </ul>
            <div class="tab-content" id="myTabContent">
              <!-- 节点树 -->
              <div class="tab-pane fade show active p-3" id="nodeTree" role="tabpanel" aria-labelledby="nodeTreeTab">
                <div class="row">
                  <!-- 左侧:节点树区域 -->
                  <div class="col-8 h-100">
                    <div class="his-node-tree-area" id="nodeTreeContainer">
                      <!-- 节点树内容 -->
                      <div id="treeContent" class="his-tree-content">
                        <p id="treeLoadingMsg" style="text-align:center;">加载中...</p>
                      </div>
                    </div>
                  </div>
                  <!-- 右侧:节点信息与操作 -->
                  <div class="col-4 h-100">
                    <div class="node-info-area mb-2" style="padding: 10px;">
<!--                      <h5>节点信息</h5>-->
                      <p><strong>节点名称:</strong> <span id="nodeName">-</span></p>
                      <p><strong>测试状态:</strong> <span id="testStatus">-</span></p>
                      <p><strong>漏洞类型:</strong> <span id="node_vulType">-</span></p>
                      <p><strong>漏洞级别:</strong> <span id="node_vulLevel">-</span></p>
                      <p><strong>漏洞说明:</strong> <span id="node_vulInfo">-</span></p>
                      <p><strong>工作状态:</strong> <span id="node_bwork">-</span></p>
                      <p><strong>执行状态:</strong> <span id="node_workstatus">-</span></p>
                    </div>
                    <div class="node-actions" style="padding: 0 10px 10px;">
                      <div class="row mb-2">
                        <div class="col-12">
                          <button class="btn btn-primary w-100" id="btnViewInstr">查看指令</button>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
              <!-- 测试指令 -->
              <div class="tab-pane fade p-3" id="testInstructions" role="tabpanel" aria-labelledby="testInstructionsTab">
                <div class="row search-area mb-2">
                  <div class="col-4">
                    <input type="text" class="form-control" id="instrNodeName" placeholder="节点名称">
                  </div>
                  <div class="col-2">
                    <button class="btn btn-primary" id="instrSearchBtn">查询</button>
                    <button class="btn btn-primary" id="instrExportBtn">导出</button>
                  </div>
                </div>
                <table class="table table-bordered table-hover" id="instrTable" style="width: 100%; table-layout: fixed;">
                  <colgroup>
                    <col style="width: 5%;">
                    <col style="width: 15%;">
                    <col style="width: 5%;">
                    <col style="width: 30%;" class="wrap-cell">
                    <col style="width: auto;">
                  </colgroup>
                  <thead>
                    <tr>
                      <th>序号</th>
                      <th>节点路径</th>
                      <th>指序</th>
                      <th>执行指令</th>
                      <th>执行结果</th>
                    </tr>
                  </thead>
                  <tbody>
                    <!-- 默认显示10行 -->
                  </tbody>
                </table>
                <!-- 分页控件 -->
                <nav>
                  <ul class="pagination" id="instrPagination">
                    <li class="page-item">
                      <a class="page-link" href="#" id="instrPrev">上一页</a>
                    </li>
                    <li class="page-item">
                      <a class="page-link" href="#" id="instrNext">下一页</a>
                    </li>
                  </ul>
                </nav>
              </div>
              <!-- 漏洞数据 -->
              <div class="tab-pane fade p-3" id="vulnerabilities" role="tabpanel" aria-labelledby="vulnerabilitiesTab">
                <div class="row search-area mb-2">
                  <div class="col-3">
                    <input type="text" class="form-control" id="vulNodeName" placeholder="节点名称">
                  </div>
                  <div class="col-3">
                    <input type="text" class="form-control" id="vulType" placeholder="漏洞类型">
                  </div>
                  <div class="col-3">
                    <select class="form-select" id="vulLevel">
                      <option value="">漏洞级别</option>
                      <option value="低危">低危</option>
                      <option value="中危">中危</option>
                      <option value="高危">高危</option>
                    </select>
                  </div>
                  <div class="col-2">
                    <button class="btn btn-primary" id="vulSearchBtn">查询</button>
                    <button class="btn btn-primary" id="vulExportBtn">导出</button>
                  </div>
                </div>
                <table class="table table-bordered table-hover" id="vulTable">
                  <thead>
                    <tr>
                      <th class="seq-col">序号</th>
                      <th>节点路径</th>
                      <th>漏洞类型</th>
                      <th>漏洞级别</th>
                      <th>漏洞说明</th>
                    </tr>
                  </thead>
                  <tbody>
                    <!-- 默认显示10行 -->
                  </tbody>
                </table>
                <!-- 分页控件 -->
                <nav>
                  <ul class="pagination" id="vulPagination">
                    <li class="page-item">
                      <a class="page-link" href="#" id="vulPrev">上一页</a>
                    </li>
                    <li class="page-item">
                      <a class="page-link" href="#" id="vulNext">下一页</a>
                    </li>
                  </ul>
                </nav>
              </div>
            </div>
          </div>
        </div>
        <!-- 模态框 footer -->
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
        </div>
      </div>
    </div>
  </div>

  <!-- 查看节点执行指令offcanvas --modal 改--->
  <div class="offcanvas offcanvas-end" tabindex="-1" id="instrCanvas" aria-labelledby="instrCanvasLabel">
    <div class="offcanvas-header">
      <!-- 返回按钮 -->
<!--      <button type="button" class="btn btn-outline-secondary btn-sm" data-bs-dismiss="offcanvas">-->
<!--          ←-->
<!--      </button>-->
      <h5 class="offcanvas-title" id="instrOffcanvasLabel">测试指令</h5>
      <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
    </div>
    <div class="offcanvas-body">
      <!-- 返回按钮 -->
      <div class="mb-3">
        <button type="button" class="btn btn-outline-secondary btn-sm" data-bs-dismiss="offcanvas">
          ← 返回
        </button>
      </div>
      <!-- 新增一个提示容器 -->
<!--      <div id="loadingMsg" style="text-align: center; padding: 10px;">请稍后,数据获取中...</div>-->
      <div id="loadingMsg" class="text-center mb-3">请稍后,数据获取中...</div>
      <!-- 页签(已执行、待执行) -->
      <ul class="nav nav-tabs" id="instrTab" role="tablist">
        <li class="nav-item" role="presentation">
          <button
            class="nav-link active"
            id="doneInstrTab"
            data-bs-toggle="tab"
            data-bs-target="#doneInstr"
            type="button"
            role="tab"
            aria-controls="doneInstr"
            aria-selected="true"
          >
            已执行
          </button>
        </li>
        <li class="nav-item" role="presentation">
          <button
            class="nav-link"
            id="todoInstrTab"
            data-bs-toggle="tab"
            data-bs-target="#todoInstr"
            type="button"
            role="tab"
            aria-controls="todoInstr"
            aria-selected="false"
          >
            待执行
          </button>
        </li>
      </ul>
      <div class="tab-content pt-3" id="instrTabContent">
        <!-- 已执行指令表格 -->
        <div
          class="tab-pane fade show active"
          id="doneInstr"
          role="tabpanel"
          aria-labelledby="doneInstrTab"
        >
          <table class="table table-bordered table-hover">
            <thead>
              <tr>
                <th style="width: 50px;">序号</th>
                <th>执行指令</th>
                <th>执行时间</th>
                <th>执行结果</th>
              </tr>
            </thead>
            <tbody id="doneInstrTbody">
              <!-- 动态生成,固定 10 行 -->
            </tbody>
          </table>
          <!-- 分页控件 -->
          <nav>
            <ul class="pagination justify-content-end" id="doneInstrPagination">
              <li class="page-item">
                <a class="page-link" href="#" id="doneInstrPrev">上一页</a>
              </li>
              <li class="page-item">
                <a class="page-link" href="#" id="doneInstrNext">下一页</a>
              </li>
            </ul>
          </nav>
        </div>
        <!-- 待执行指令表格 -->
        <div
          class="tab-pane fade"
          id="todoInstr"
          role="tabpanel"
          aria-labelledby="todoInstrTab"
        >
          <table class="table table-bordered table-hover">
            <thead>
              <tr>
                <th style="width: 50px;">序号</th>
                <th>待执行指令</th>
                <th style="width: 80px;">操作</th>
              </tr>
            </thead>
            <tbody id="todoInstrTbody">
              <!-- 动态生成,固定 10 行 -->
            </tbody>
          </table>
          <!-- 分页控件 -->
          <nav>
            <ul class="pagination justify-content-end" id="todoInstrPagination">
              <li class="page-item">
                <a class="page-link" href="#" id="todoInstrPrev">上一页</a>
              </li>
              <li class="page-item">
                <a class="page-link" href="#" id="todoInstrNext">下一页</a>
              </li>
            </ul>
          </nav>
        </div>
      </div>
      <!-- 操作按钮 -->
      <div class="mt-4 d-flex justify-content-end">
        <button type="button" class="btn btn-primary" id="btnExport">导出</button>
      </div>
    </div>
  </div>

{% endblock %}

<!-- 页面脚本块 -->
{% block script %}
<script src="{{ url_for('main.static', filename='scripts/his_task_modal.js') }}"></script>
<script>
    // 全局变量
    let cur_task_id = 0;
    let allHistasks = [];
    let currentPage = 1;
    const pageSize = 10;

    // 分页渲染函数
    function renderHistasksTable(page) {
      currentPage = page;
      const tbody = document.getElementById("histasksTbody");
      const startIndex = (page - 1) * pageSize;
      const endIndex = startIndex + pageSize;
      const pageData = allHistasks.slice(startIndex, endIndex);
      //select ID,task_target,safe_rank,llm_type,start_time,end_time from task
      tbody.innerHTML = "";
      pageData.forEach((task, i) => {
        const tr = document.createElement("tr");
        // 每个单元格创建时使用 textContent,确保固定行高,如有需要也可增加 class "fixed-row-height"
        const tdId = document.createElement("td");
        tdId.textContent = task[0];
        tr.appendChild(tdId);

        const tdTarget = document.createElement("td");
        tdTarget.textContent = task[1];
        tr.appendChild(tdTarget);

        const tdStart = document.createElement("td");
        tdStart.textContent = task[4] || "";
        tr.appendChild(tdStart);

        const tdEnd = document.createElement("td");
        tdEnd.textContent = task[5] || "";
        tr.appendChild(tdEnd);

        const tdRisk = document.createElement("td");
        tdRisk.textContent = (task[2] === 0) ? "安全" : "存在风险";
        tr.appendChild(tdRisk);

        const tdModel = document.createElement("td");
        model_test = ""
        if(task[3]===1){
          model_test="DeepSeek";
        }
        else if(task[3]===2){
          model_test="GPT-O3";
        }
        else if(task[3]===4){
          model_test="Qwen3";
        }
        else{
          model_test="其他模型";
        }
        tdModel.textContent = model_test;
        tr.appendChild(tdModel);

        const tdAction = document.createElement("td");
        //报告按钮
        const btnReport = document.createElement("button");
        btnReport.className = "btn btn-outline-info btn-sm ms-2";
        btnReport.textContent = "报告";
        btnReport.onclick = () => createReport(task[0]);
        tdAction.appendChild(btnReport);
        // 查看按钮(点击后弹出 modal)
        const btnView = document.createElement("button");
        btnView.className = "btn btn-outline-info btn-sm ms-2";
        btnView.textContent = "查看";
        btnView.onclick = () => openViewModal(task[0]);
        tdAction.appendChild(btnView);
        // 删除按钮
        const btnDel = document.createElement("button");
        btnDel.className = "btn btn-outline-danger btn-sm ms-2";
        btnDel.textContent = "删除";
        btnDel.onclick = () => confirmDeleteTask(task[0]);
        tdAction.appendChild(btnDel);

        tr.appendChild(tdAction);
        tbody.appendChild(tr);
      });

      // 补空行
      for (let i = pageData.length; i < pageSize; i++) {
        const tr = document.createElement("tr");
        for (let j = 0; j < 7; j++) {
          const td = document.createElement("td");
          td.textContent = "\u00A0";
          tr.appendChild(td);
        }
        tbody.appendChild(tr);
      }
      updatePagination();
    }

    function createReport(task_id){
      alert("导出报告的功能实现中--"+task_id)
    }

    // 更新分页按钮
    function updatePagination() {
      const totalPages = Math.ceil(allHistasks.length / pageSize);
      document.getElementById("prevPage").dataset.page = currentPage > 1 ? currentPage - 1 : 1;
      document.getElementById("nextPage").dataset.page = currentPage < totalPages ? currentPage + 1 : totalPages;
    }

    // 分页按钮点击事件
    document.getElementById("prevPage").addEventListener("click", function(e) {
      e.preventDefault();
      const page = parseInt(this.dataset.page, 10);
      renderHistasksTable(page);
    });
    document.getElementById("nextPage").addEventListener("click", function(e) {
      e.preventDefault();
      const page = parseInt(this.dataset.page, 10);
      renderHistasksTable(page);
    });

    // 查询按钮事件,调用 /api/task/histasks 接口获取数据(示例)
    document.getElementById("btnQuery").addEventListener("click", async function() {
      // 此处可拼接获取表单数据条件,示例直接调用接口
      /*
      target_name = data.get("target_name")
    safe_rank = data.get("safe_rank")
    llm_type = data.get("llm_type")
    start_time= data.get("start_time")
    end_time= data.get("end_time")
      * */
      const target_name = document.getElementById("testTarget").value.trim();
      const safe_rank  = document.getElementById("riskLevel").value;
      const llm_type   = document.getElementById("useModel").value;
      const start_time  = document.getElementById("startTime").value;
      const end_time    = document.getElementById("endTime").value;

      try {
        const res = await fetch("/api/task/histasks", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({target_name,safe_rank,llm_type,start_time,end_time})
        });
        if (!res.ok) {
          const errorData = await res.json();
          throw new Error(errorData.error || `HTTP错误 ${res.status}`);
        }
        const data = await res.json();
        allHistasks = data.his_tasks || [];
        renderHistasksTable(1);
      } catch (error) {
        console.error("查询任务记录出错:", error);
        alert("查询失败!");
      }
    });

    // “查看详情”按钮事件(统一使用模态框显示 task_manager.html)
    async function openViewModal(task_id) {
      cur_task_id = task_id;
      const viewModal = new bootstrap.Modal(document.getElementById("viewModal"), { keyboard: false });
      viewModal.show();
      //查询节点树数据
      his_loadNodeTree(task_id);
      //查询指令数据
      searchInstructions(1);
      //查询漏洞数据
      searchVulnerabilities(1);
    }

    // 删除任务的示例函数
    async function confirmDeleteTask(task_id) {
      if (confirm("确认删除任务 " + task_id + " 吗?")) {
        // 发送删除请求...
        try {
          const res = await fetch("/api/task/deltask", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({task_id}),
          });
          if (!res.ok) {
            const errorData = await res.json();
            throw new Error(errorData.error || `HTTP错误 ${res.status}`);
          }
          const data = await res.json();
          bsuccess = data.bsuccess;
          if(bsuccess){
             // 1. 从前端缓存里删除这条任务
            allHistasks = allHistasks.filter(t => t[0] !== task_id);

            // 2. 重新渲染当前页
            //    注意:如果删除后当前页已经没有任何数据了,可以让 currentPage--
            const totalPages = Math.ceil(allHistasks.length / pageSize) || 1;
            if (currentPage > totalPages) {
              currentPage = totalPages;
            }
            renderHistasksTable(currentPage);

            // (可选)如果你想做局部删除,而不重画整表,也可以直接:
            // btnEl.closest("tr").remove();
            alert("删除成功")
          }
          else{
            alert("删除失败:"+data.error)
            return false;
          }
        } catch (error) {
          console.error("删除任务数据异常:", error);
          return false;
        }
      }
    }

    // 页面加载时可以自动调用查询接口加载数据
    document.addEventListener("DOMContentLoaded", () => {
      // 可自动加载数据,或者等待用户点击查询
      document.getElementById("btnQuery").click();
      //renderHistasksTable(1);
    });
  </script>

{% endblock %}