/* ═══════════════════════════════════════════════════════════════════
   Timeline View
   ═══════════════════════════════════════════════════════════════════ */
function switchView(view) {
  currentView = view;
  document.getElementById('view-graph-btn').classList.toggle('active', view === 'graph');
  document.getElementById('view-timeline-btn').classList.toggle('active', view === 'timeline');
  const timelineEl = document.getElementById('timeline-view');
  const cyEl = document.getElementById('cy');
  const selBox = document.getElementById('sel-box');
  if (view === 'timeline') {
    timelineEl.classList.add('visible');
    cyEl.style.display = 'none';
    selBox.style.display = 'none';
    loadTimeline();
  } else {
    timelineEl.classList.remove('visible');
    cyEl.style.display = '';
  }
}

async function loadTimeline() {
  if (!currentProject) return;
  const container = document.getElementById('timeline-view');
  try {
    const items = await apiFetch(API + '/projects/' + currentProject + '/timeline');
    if (!items || items.length === 0) {
      container.innerHTML = '<div class="timeline-empty"><div class="timeline-empty-icon">📋</div><div class="timeline-empty-title">暂无节点数据</div><div>添加节点后时间线将在这里显示</div></div>';
      return;
    }
    // Sort by created_at descending
    const sorted = [...items].sort((a, b) => {
      const ta = a.created_at ? new Date(a.created_at).getTime() : 0;
      const tb = b.created_at ? new Date(b.created_at).getTime() : 0;
      return tb - ta;
    });
    const typeIcons = {
      objective: '🎯', vulnerability: '💥', host: '🖥', service: '⚙',
      credential: '🔑', entry_point: '🚪', attack_step: '⚡', exploitation: '🔥',
      exfiltration: '📤', impact: '⚠', privilege_escalation: '🔼',
      reconnaissance: '🔍', note: '📝', asset: '💰', finding: '🔎',
    };
    const typeNames = {objective:'测试目标',vulnerability:'漏洞',exploitation:'漏洞利用',attack_step:'攻击步骤',exfiltration:'数据外传',impact:'影响评估',host:'主机',service:'服务',credential:'凭据',finding:'发现',entry_point:'攻击入口',reconnaissance:'信息收集',privilege_escalation:'提权漏洞',note:'笔记',asset:'资产'};
    let html = '<div class="timeline-container"><div class="timeline-line"></div>';
    sorted.forEach(n => {
      const props = (typeof n.properties === 'object' && n.properties !== null) ? n.properties : {};
      const status = nodeColor(n.node_type, n.properties);
      const icon = typeIcons[n.node_type] || '📌';
      // Build edge label from incoming + outgoing
      const edgeLabels = [];
      if (Array.isArray(n.incoming)) n.incoming.forEach(e => edgeLabels.push('← ' + (e.label || '无标签')));
      if (Array.isArray(n.outgoing)) n.outgoing.forEach(e => edgeLabels.push('→ ' + (e.label || '无标签')));
      const edgeLabel = edgeLabels.join(' · ');
      const time = n.created_at ? formatDate(n.created_at) : '';
      html += '<div class="timeline-item" onclick="selectTimelineNode(\'' + (n.node_id || '') + '\')">' +
        '<div class="timeline-dot ' + status + '"></div>' +
        '<div class="timeline-card">' +
          '<div class="timeline-card-top">' +
            '<div class="timeline-type-icon ' + status + '">' + icon + '</div>' +
            '<span class="timeline-label">' + escHtml(n.node_label || '(无标签)') + '</span>' +
            (time ? '<span class="timeline-time">' + time + '</span>' : '') +
          '</div>' +
          '<div class="timeline-type-label">' + escHtml(typeNames[n.node_type] || n.node_type || '未知') + '</div>' +
          (edgeLabel ? '<div class="timeline-edge-label">' + escHtml(edgeLabel) + '</div>' : '') +
        '</div>' +
      '</div>';
    });
    html += '</div>';
    container.innerHTML = html;
  } catch (e) {
    container.innerHTML = '<div class="timeline-empty"><div class="timeline-empty-icon">⚠</div><div class="timeline-empty-title">加载失败</div><div>' + escHtml(e.message) + '</div></div>';
  }
}

function selectTimelineNode(nodeId) {
  if (!cy) return;
  const node = cy.getElementById(nodeId);
  if (node.length) {
    // Trigger the tap handler on the cy node to open the panel
    node.trigger('tap');
  }
}
