/* ==============================================
   Sidebar: Project Rail (Cortex pattern)
   ============================================== */
const avatarPalette = [
  '#d44c4c','#c8960c','#3a9a50','#5c9cd4','#8a6cd4',
  '#d46c8a','#4cd4c8','#d4a04c','#6cd44c','#4cd48a',
];

function avatarColor(name) {
  let h = 0;
  for (let i = 0; i < name.length; i++) {
    h = name.charCodeAt(i) + ((h << 5) - h);
  }
  return avatarPalette[Math.abs(h) % avatarPalette.length];
}

function renderSidebar() {
  const list = document.getElementById('sidebar-projects');
  list.innerHTML = '';
  projects.forEach(p => {
    const btn = document.createElement('button');
    btn.type = 'button';
    btn.className = 'sidebar-project' + (p.id === currentProject ? ' is-active' : '');
    btn.title = p.name;
    btn.onclick = () => selectProject(p.id);

    const avatar = document.createElement('div');
    avatar.className = 'sidebar-avatar';
    avatar.style.background = avatarColor(p.name);
    avatar.textContent = p.name.charAt(0).toUpperCase();

    const tooltip = document.createElement('span');
    tooltip.className = 'sidebar-tooltip';
    let tooltipText = p.name;
    if (p.created_at) {
      tooltipText += ' · ' + formatDate(p.created_at).split(' ')[0];
    }
    tooltip.textContent = tooltipText;

    btn.appendChild(avatar);
    btn.appendChild(tooltip);
    list.appendChild(btn);
  });
}

/* ==============================================
   Project CRUD
   ============================================== */
function selectProject(id) {
  currentProject = id;
  savedZoom = null;  // reset zoom — fit new project
  savedPan = null;
  // Close any open panels
  closeCredentials();
  closeSearch();
  document.getElementById('current-project-name').textContent =
    (projects.find(p => p.id === id) || {}).name || '';
  document.getElementById('btn-analysis').disabled = false;
  document.getElementById('btn-credentials').disabled = false;
  document.getElementById('btn-import').disabled = false;
  renderSidebar();
  loadGraph();
}

function loadProjects() {
  return authFetch(API+'/projects')
    .then(r => r.json())
    .then(j => {
      if (!j.success) {
        if (j.error && j.error.includes('API key')) showAuthOverlay(j.error);
        throw new Error(j.error || '加载项目失败');
      }
      projects = j.data || [];
      renderSidebar();
      // If we had a selected project, make sure it's still valid
      if (currentProject && !projects.find(p => p.id === currentProject)) {
        currentProject = null;
        document.getElementById('btn-analysis').disabled = true;
        document.getElementById('btn-credentials').disabled = true;
        document.getElementById('btn-import').disabled = true;
        document.getElementById('current-project-name').textContent = '';
        cy.elements().remove();
        document.getElementById('stat-nodes').textContent = '0';
        document.getElementById('stat-edges').textContent = '0';
        updateEmptyState();
      }
    });
}

function showCreateModal() {
  document.getElementById('modal').classList.add('active');
  document.getElementById('modal-name').focus();
}
function hideCreateModal() {
  document.getElementById('modal').classList.remove('active');
  document.getElementById('modal-name').value='';
}
async function createProject() {
  const name = document.getElementById('modal-name').value.trim();
  if(!name) return;
  const res = await authFetch(API+'/projects',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({name})});
  const j = await res.json();
  if (!j.success) {
    if (res.status === 401) showAuthOverlay(j.error || 'API Key 无效或缺失');
    throw new Error(j.error || '创建项目失败');
  }
  hideCreateModal();
  await loadProjects();
  currentProject = j.data.id;
  document.getElementById('current-project-name').textContent = name;
  renderSidebar();
  loadGraph();
  toast('项目已创建');
}

async function deleteProject() {
  if(!currentProject) return;
  const p = projects.find(p => p.id === currentProject);
  if(!confirm('确定删除项目「'+(p?p.name:currentProject)+'」？所有节点和连线将被清除。')) return;
  await authFetch(API+'/projects/'+currentProject,{method:'DELETE'});
  currentProject = null;
  document.getElementById('btn-analysis').disabled = true;
  document.getElementById('btn-credentials').disabled = true;
  document.getElementById('btn-import').disabled = true;
  document.getElementById('current-project-name').textContent = '';
  cy.elements().remove();
  document.getElementById('stat-nodes').textContent='0';
  document.getElementById('stat-edges').textContent='0';
  await loadProjects();
  updateEmptyState();
  toast('项目已删除');
}

/* ==============================================
   Project Manager
   ============================================== */
let managerSortCol = 'created';
let managerSortAsc = false;
let managerStats = {};
const managerSelected = new Set();

function toggleManageMode() {
  openManager();
}

async function openManager() {
  document.getElementById('manager-modal').classList.add('active');
  await refreshManagerStats();
}

function closeManager() {
  document.getElementById('manager-modal').classList.remove('active');
  managerSelected.clear();
}

async function refreshManagerStats() {
  try {
    const resp = await authFetch(API + '/projects/stats');
    const j = await resp.json();
    if (j.success && j.data) {
      managerStats = j.data;
    }
  } catch (e) {
    managerStats = {};
  }
  renderManagerTable();
}

function sortManager(col) {
  if (managerSortCol === col) {
    managerSortAsc = !managerSortAsc;
  } else {
    managerSortCol = col;
    managerSortAsc = col === 'nodes' || col === 'edges';
  }
  renderManagerTable();
}

function renderManagerTable() {
  const tbody = document.getElementById('manager-tbody');
  const empty = document.getElementById('manager-empty');
  const count = document.getElementById('manager-count');
  const selectAll = document.getElementById('manager-select-all');

  if (!projects || projects.length === 0) {
    tbody.innerHTML = '';
    empty.style.display = 'block';
    count.textContent = '0 个项目';
    selectAll.checked = false;
    selectAll.indeterminate = false;
    return;
  }
  empty.style.display = 'none';

  // Sort
  const sorted = [...projects].sort((a, b) => {
    let va, vb;
    switch (managerSortCol) {
      case 'name':
        va = a.name; vb = b.name;
        break;
      case 'created':
        va = a.created_at || ''; vb = b.created_at || '';
        break;
      case 'nodes':
        va = (managerStats[a.id] && managerStats[a.id].node_count) || 0;
        vb = (managerStats[b.id] && managerStats[b.id].node_count) || 0;
        break;
      case 'edges':
        va = (managerStats[a.id] && managerStats[a.id].edge_count) || 0;
        vb = (managerStats[b.id] && managerStats[b.id].edge_count) || 0;
        break;
      default:
        return 0;
    }
    if (va < vb) return managerSortAsc ? -1 : 1;
    if (va > vb) return managerSortAsc ? 1 : -1;
    return 0;
  });

  // Update sort headers
  document.querySelectorAll('.manager-table th.sortable').forEach(th => {
    const scol = th.dataset.sort;
    th.classList.toggle('active', scol === managerSortCol);
    const arrow = th.querySelector('.sort-arrow');
    if (arrow) {
      arrow.textContent = scol === managerSortCol ? (managerSortAsc ? '▴' : '▾') : '';
    }
  });

  // Check selection state
  const allSelected = sorted.length > 0 && sorted.every(p => managerSelected.has(p.id));
  const someSelected = sorted.some(p => managerSelected.has(p.id));
  selectAll.checked = allSelected;
  selectAll.indeterminate = !allSelected && someSelected;

  count.textContent = projects.length + ' 个项目';
  if (someSelected) {
    document.getElementById('manager-selected-text').textContent = '已选 ' + managerSelected.size + ' 个';
  } else {
    document.getElementById('manager-selected-text').textContent = '';
  }

  let html = '';
  for (const p of sorted) {
    const stats = managerStats[p.id] || {};
    const nodeCount = stats.node_count || 0;
    const edgeCount = stats.edge_count || 0;
    const sel = managerSelected.has(p.id) ? ' selected' : '';
    const date = p.created_at ? formatDate(p.created_at) : '-';
    const isActive = p.id === currentProject;

    html += '<tr class="' + sel + '" onclick="managerRowClick(event, \'' + escHtml(p.id) + '\')">';
    html += '<td><input type="checkbox" onclick="event.stopPropagation();toggleManagerSelect(\'' + escHtml(p.id) + '\')" ' + (managerSelected.has(p.id) ? 'checked' : '') + '></td>';
    html += '<td><span class="manager-name">' + escHtml(p.name) + (isActive ? ' <span style="color:var(--accent);font-size:10px">● 当前</span>' : '') + '</span></td>';
    html += '<td><span class="manager-date">' + escHtml(date) + '</span></td>';
    html += '<td><span class="manager-num' + (nodeCount === 0 ? ' empty' : '') + '">' + nodeCount + '</span></td>';
    html += '<td><span class="manager-num' + (edgeCount === 0 ? ' empty' : '') + '">' + edgeCount + '</span></td>';
    html += '<td><div class="manager-actions" onclick="event.stopPropagation()">';
    html += '<button class="manager-act-btn" onclick="managerOpenProject(\'' + escHtml(p.id) + '\')">打开</button>';
    html += '<button class="manager-act-btn delete" onclick="managerDeleteOne(\'' + escHtml(p.id) + '\',\'' + escHtml(p.name.replace(/'/g, "\\'")) + '\')">删除</button>';
    html += '</div></td>';
    html += '</tr>';
  }
  tbody.innerHTML = html;
}

function managerRowClick(evt, pid) {
  // Ignore clicks on checkboxes and action buttons (handled by stopPropagation)
  if (evt.target.tagName === 'INPUT' || evt.target.tagName === 'BUTTON') return;
  managerOpenProject(pid);
}

function managerOpenProject(pid) {
  closeManager();
  selectProject(pid);
}

function toggleManagerSelectAll() {
  const cb = document.getElementById('manager-select-all');
  const sorted = [...projects];
  if (cb.checked) {
    sorted.forEach(p => { managerSelected.add(p.id); });
  } else {
    sorted.forEach(p => { managerSelected.delete(p.id); });
  }
  renderManagerTable();
}

function toggleManagerSelect(pid) {
  if (managerSelected.has(pid)) {
    managerSelected.delete(pid);
  } else {
    managerSelected.add(pid);
  }
  renderManagerTable();
}

async function managerDeleteOne(pid, name) {
  if (!confirm('确定删除项目「' + name + '」？\n所有节点和连线将被清除。此操作不可撤销。')) return;
  await authFetch(API + '/projects/' + pid, { method: 'DELETE' });
  managerSelected.delete(pid);
  if (currentProject === pid) {
    currentProject = null;
    document.getElementById('btn-analysis').disabled = true;
    document.getElementById('btn-credentials').disabled = true;
    document.getElementById('btn-import').disabled = true;
    document.getElementById('current-project-name').textContent = '';
    cy.elements().remove();
    document.getElementById('stat-nodes').textContent = '0';
    document.getElementById('stat-edges').textContent = '0';
  }
  await loadProjects();
  updateEmptyState();
  if (currentProject === pid) {
    // Load projects removed currentProject, no need to re-render separately
  }
  await refreshManagerStats();
  toast('已删除 ' + name);
}

async function managerBatchDelete() {
  if (managerSelected.size === 0) {
    toast('请先选择要删除的项目');
    return;
  }
  const names = [];
  for (const pid of managerSelected) {
    const p = projects.find(p => p.id === pid);
    if (p) names.push(p.name);
  }
  if (!confirm('确定删除 ' + managerSelected.size + ' 个项目？\n\n' + names.slice(0, 10).join('\n') + (names.length > 10 ? '\n... 等共 ' + names.length + ' 个' : '') + '\n\n所有节点和连线将被清除。此操作不可撤销。')) return;

  let deleted = 0;
  for (const pid of [...managerSelected]) {
    try {
      await authFetch(API + '/projects/' + pid, { method: 'DELETE' });
      managerSelected.delete(pid);
      deleted++;
    } catch (e) { /* continue */ }
  }

  if (currentProject && managerSelected.has(currentProject)) {
    currentProject = null;
    document.getElementById('btn-analysis').disabled = true;
    document.getElementById('btn-credentials').disabled = true;
    document.getElementById('btn-import').disabled = true;
    document.getElementById('current-project-name').textContent = '';
    cy.elements().remove();
    document.getElementById('stat-nodes').textContent = '0';
    document.getElementById('stat-edges').textContent = '0';
  }

  await loadProjects();
  updateEmptyState();
  await refreshManagerStats();
  toast('已删除 ' + deleted + ' 个项目');
}
