// UI helpers — v2.1.0

(function () {
  const UI = {};

  UI.$ = sel => document.querySelector(sel);
  UI.$$ = sel => document.querySelectorAll(sel);

  UI.setHidden = function (sel, hidden) {
    const el = typeof sel === 'string' ? UI.$(sel) : sel;
    if (!el) return;
    el.classList.toggle('hidden', !!hidden);
  };

  UI.showPane = function (name) {
    UI.setHidden('#connect-pane',  name !== 'connect');
    UI.setHidden('#library-pane',  name !== 'library');
  };

  UI.setStatus = function (sel, text, kind) {
    const el = typeof sel === 'string' ? UI.$(sel) : sel;
    if (!el) return;
    el.textContent = text || '';
    el.classList.remove('error', 'muted');
    if (kind) el.classList.add(kind);
  };

  // Toast — auto-hides after 6s
  UI.toast = function (msg, kind) {
    const el = UI.$('#toast');
    if (!el) return;
    el.textContent = msg;
    el.classList.remove('hidden', 'ok', 'error');
    if (kind) el.classList.add(kind);
    clearTimeout(UI._toastTimer);
    UI._toastTimer = setTimeout(() => el.classList.add('hidden'), 6000);
  };

  UI.showProgress = function (label, pct) {
    UI.setHidden('#progress-row', false);
    const lEl = UI.$('#progress-label');
    if (lEl) lEl.textContent = label;
    const fEl = UI.$('#progress-fill');
    if (fEl) fEl.style.width = Math.max(0, Math.min(100, pct || 0)) + '%';
  };

  UI.hideProgress = function () { UI.setHidden('#progress-row', true); };

  // Slide panels
  UI.openSlide = function (overlayId, panelId) {
    UI.setHidden('#' + overlayId, false);
    UI.setHidden('#' + panelId,   false);
  };

  UI.closeSlide = function (overlayId, panelId) {
    UI.setHidden('#' + overlayId, true);
    UI.setHidden('#' + panelId,   true);
  };

  // Format helpers
  UI.formatBytes = function (n) {
    if (!Number.isFinite(n)) return '';
    const u = ['B', 'KB', 'MB', 'GB', 'TB'];
    let i = 0;
    while (n >= 1024 && i < u.length - 1) { n /= 1024; i++; }
    return n.toFixed(n < 10 && i > 0 ? 1 : 0) + ' ' + u[i];
  };

  UI.formatDuration = function (sec) {
    if (!Number.isFinite(sec)) return '—';
    const h = Math.floor(sec / 3600);
    const m = Math.floor((sec % 3600) / 60);
    const s = Math.floor(sec % 60);
    return h > 0
      ? h + ':' + String(m).padStart(2, '0') + ':' + String(s).padStart(2, '0')
      : m + ':' + String(s).padStart(2, '0');
  };

  UI.sanitizeFilename = function (s) {
    return String(s || 'asset').replace(/[\\/:*?"<>|]/g, '_').slice(0, 120);
  };

  UI.escapeHtml = function (s) {
    return String(s || '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
  };

  UI.escapeXml = function (s) {
    return String(s || '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,'&apos;');
  };

  // FCP timecode / frame rate helpers (used by timeline module)
  UI.timecodeFromFrames = function (frames, fps) {
    const r = Math.round(fps);
    const f = frames % r;
    const totalSec = Math.floor(frames / r);
    const s = totalSec % 60;
    const m = Math.floor(totalSec / 60) % 60;
    const h = Math.floor(totalSec / 3600);
    return h + ':' + String(m).padStart(2,'0') + ':' + String(s).padStart(2,'0') + ':' + String(f).padStart(2,'0');
  };

  UI.formatFrameRate = function (fps) {
    // FCP XML uses rational notation: 1001/30000 for 29.97, 1/25 for 25, etc.
    const known = {
      23.976: '1001/24000', 24: '1/24', 25: '1/25',
      29.97: '1001/30000', 30: '1/30', 50: '1/50',
      59.94: '1001/60000', 60: '1/60',
    };
    // Find closest key
    let best = '1001/30000';
    let bestDist = Infinity;
    for (const k in known) {
      const d = Math.abs(Number(k) - fps);
      if (d < bestDist) { bestDist = d; best = known[k]; }
    }
    return best;
  };

  window.UI = UI;
})();
