/* ═══════════════════════════════════════════════════════════════════
   API Helpers + Utilities
   ═══════════════════════════════════════════════════════════════════ */
function toast(msg) {
  const t = document.getElementById('toast');
  t.textContent = msg;
  t.classList.add('show');
  setTimeout(() => t.classList.remove('show'), 2200);
}

function getApiKey() {
  return localStorage.getItem('theseus.apiKey') || '';
}

function setApiKey(value) {
  const key = (value || '').trim();
  if (key) localStorage.setItem('theseus.apiKey', key);
  else localStorage.removeItem('theseus.apiKey');
}

function authHeaders(extra) {
  const headers = new Headers(extra || {});
  const key = getApiKey();
  if (key) headers.set('X-API-Key', key);
  return headers;
}

function authFetch(url, options) {
  const opts = options ? { ...options } : {};
  opts.headers = authHeaders(opts.headers);
  return fetch(url, opts);
}

function showAuthOverlay(message) {
  const overlay = document.getElementById('auth-overlay');
  if (!overlay) return;
  if (message) document.getElementById('auth-error').textContent = message;
  document.getElementById('auth-key').value = getApiKey();
  overlay.classList.add('active');
  setTimeout(() => document.getElementById('auth-key').focus(), 0);
}

function hideAuthOverlay() {
  const overlay = document.getElementById('auth-overlay');
  if (overlay) overlay.classList.remove('active');
  const error = document.getElementById('auth-error');
  if (error) error.textContent = '';
}

async function saveApiKeyFromLogin() {
  const key = document.getElementById('auth-key').value.trim();
  if (!key) {
    document.getElementById('auth-error').textContent = '请输入 API Key';
    return;
  }
  setApiKey(key);
  try {
    await loadProjects();
    hideAuthOverlay();
    connectWs();
    toast('API Key 已保存');
  } catch (e) {
    document.getElementById('auth-error').textContent = e.message;
  }
}

function clearApiKey() {
  setApiKey('');
  showAuthOverlay('API Key 已清除，请重新输入');
}

async function apiFetch(url, options) {
  try {
    const res = await authFetch(url, options);
    const j = await res.json();
    if (res.status === 401) {
      showAuthOverlay(j.error || 'API Key 无效或缺失');
      throw new Error(j.error || 'API Key 无效或缺失');
    }
    if (!j.success) throw new Error(j.error || '请求失败');
    return j.data;
  } catch (e) {
    toast('错误: ' + e.message);
    throw e;
  }
}

function formatDate(dateStr) {
  if (!dateStr) return '';
  const d = new Date(dateStr);
  return d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0') +
    ' ' + String(d.getHours()).padStart(2, '0') + ':' + String(d.getMinutes()).padStart(2, '0');
}

function formatFileSize(bytes) {
  if (bytes < 1024) return bytes + ' B';
  if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB';
  return (bytes / 1048576).toFixed(1) + ' MB';
}

function escHtml(s) { const d = document.createElement('div'); d.textContent = s; return d.innerHTML; }

function escRegex(s) {
  return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
