{{define "api"}}
<div class="card">
  <div class="crumb">系统设置 / 日志审计 / 高级调试</div>
  <h2>高级调试</h2>
</div>

<div class="card">
  <h2>常用变量</h2>
  <div class="row" style="margin-top:8px">
    <div>
      <div class="muted small">节点标识</div>
      <input id="deviceId" placeholder="..." />
    </div>
    <div>
      <div class="muted small">任务标识</div>
      <input id="taskId" placeholder="..." />
    </div>
    <div>
      <div class="muted small">模板名称</div>
      <input id="tplName" placeholder="..." />
    </div>
  </div>
</div>

<div class="card">
  <h2>发起请求</h2>
  <div class="row" style="margin-top:8px">
    <div style="max-width:160px">
      <div class="muted small">请求方法</div>
      <select id="method">
        <option>GET</option>
        <option>POST</option>
        <option>PUT</option>
        <option>DELETE</option>
      </select>
    </div>
    <div>
      <div class="muted small">接口路径</div>
      <input id="path" value="/api/devices" />
    </div>
    <div style="align-self:end">
      <button type="button" onclick="doCall()">发送</button>
    </div>
  </div>
  <div style="margin-top:10px">
    <div class="muted small">请求体（JSON，GET/DELETE 会忽略）</div>
    <textarea id="body" spellcheck="false">{}</textarea>
  </div>
  <div class="row" style="margin-top:10px">
    <div>
      <div class="muted small">响应状态</div>
      <input id="status" readonly />
    </div>
  </div>
  <pre id="resp"></pre>
</div>

<div class="card">
  <h2>快速预设</h2>
  <div class="actions" style="margin-top:8px">
    <button type="button" onclick="preset('POST','/api/discovery/search', JSON.stringify({timeout_ms:1200}))">扫描节点</button>
    <button type="button" onclick="preset('GET','/api/devices','')">节点列表</button>
    <button type="button" onclick="preset('GET','/api/devices/' + v('deviceId'),'')">节点详情</button>
    <button type="button" onclick="preset('POST','/api/devices/' + v('deviceId') + '/reload','')">重载识别服务</button>
    <button type="button" onclick="preset('POST','/api/devices/' + v('deviceId') + '/rollback','')">回滚识别配置</button>
    <button type="button" onclick="preset('GET','/api/devices/' + v('deviceId') + '/graphs','')">运行指标</button>
    <button type="button" onclick="preset('GET','/api/devices/' + v('deviceId') + '/logs?limit=200','')">诊断日志</button>
    <button type="button" onclick="preset('POST','/api/devices/' + v('deviceId') + '/config/apply', JSON.stringify({config:{}}))">部署配置</button>
    <button type="button" onclick="preset('GET','/api/templates','')">配置模板</button>
    <button type="button" onclick="preset('GET','/api/templates/' + v('tplName'),'')">模板详情</button>
    <button type="button" onclick="preset('GET','/api/tasks','')">任务接口</button>
    <button type="button" onclick="preset('POST','/api/tasks', JSON.stringify({type:'config_apply', device_ids:[v('deviceId')], payload:{config:{}}}))">创建任务</button>
  </div>
</div>

<div class="card">
  <h2>任务实时事件</h2>
  <div class="actions" style="margin-top:8px">
    <button type="button" onclick="connectSSE()">连接</button>
    <button type="button" onclick="disconnectSSE()">断开</button>
    <span class="muted" id="sseState">未连接</span>
  </div>
  <pre id="sseOut" style="margin-top:10px;max-height:320px"></pre>
</div>

<div class="card">
  <h2>模型上传调试</h2>
  <form id="uploadForm" class="row" style="margin-top:8px" onsubmit="return uploadModel()">
    <div>
      <div class="muted small">模型名称</div>
      <input name="name" placeholder="模型名" />
    </div>
    <div>
      <div class="muted small">模型文件</div>
      <input type="file" name="file" />
    </div>
    <div style="align-self:end">
      <button type="submit">上传</button>
    </div>
  </form>
  <pre id="uploadResp"></pre>
</div>

<script>
let es;
function v(id){ return (document.getElementById(id).value || '').trim(); }
function preset(m,p,b){
  document.getElementById('method').value = m;
  document.getElementById('path').value = p;
  document.getElementById('body').value = b || '';
}
async function doCall(){
  const method = document.getElementById('method').value;
  const path = document.getElementById('path').value;
  const body = document.getElementById('body').value;
  const opts = { method, headers: {} };
  if(method !== 'GET' && method !== 'DELETE'){
    opts.headers['Content-Type'] = 'application/json';
    opts.body = body || '{}';
  }
  const respBox = document.getElementById('resp');
  respBox.textContent = '...';
  try{
    const res = await fetch(path, opts);
    document.getElementById('status').value = res.status;
    const txt = await res.text();
    respBox.textContent = pretty(txt);
  }catch(e){
    document.getElementById('status').value = 'ERR';
    respBox.textContent = String(e);
  }
}
function pretty(txt){
  try{ return JSON.stringify(JSON.parse(txt), null, 2); }catch(e){ return txt; }
}
function connectSSE(){
  disconnectSSE();
  const id = v('taskId');
  if(!id){ alert('请先填写任务标识'); return; }
  const url = `/api/tasks/${id}/events`;
  es = new EventSource(url);
  document.getElementById('sseState').textContent = '连接中...';
  es.onopen = () => document.getElementById('sseState').textContent = '已连接';
  es.onerror = () => document.getElementById('sseState').textContent = '连接异常（自动重试）';
  es.addEventListener('device_update', (ev) => {
    const out = document.getElementById('sseOut');
    out.textContent += ev.data + "\n";
    out.scrollTop = out.scrollHeight;
  });
}
function disconnectSSE(){
  if(es){ es.close(); es = null; }
  document.getElementById('sseState').textContent = '未连接';
}
async function uploadModel(){
  const did = v('deviceId');
  if(!did){ alert('请先填写节点标识'); return false; }
  const form = document.getElementById('uploadForm');
  const fd = new FormData(form);
  const box = document.getElementById('uploadResp');
  box.textContent = '...';
  try{
    const res = await fetch(`/api/devices/${did}/models/upload`, { method: 'POST', body: fd });
    const txt = await res.text();
    box.textContent = `status ${res.status}\n` + pretty(txt);
  }catch(e){
    box.textContent = String(e);
  }
  return false;
}
</script>
{{end}}
