/**
 * Application updates panel (Settings → Software Updates)
 */
(function () {
  const API = '/api/v1/system-health';
  let pollTimer = null;

  function authHeaders() {
    if (window.auth && typeof window.auth.authHeader === 'function') {
      return window.auth.authHeader();
    }
    const token = localStorage.getItem('token');
    return token ? { Authorization: 'Bearer ' + token } : {};
  }

  function isAdmin() {
    const u = window.auth && window.auth.getUser ? window.auth.getUser() : null;
    const role = (u && u.role ? u.role : '').toLowerCase();
    return role === 'super_admin' || role === 'admin';
  }

  function escHtml(s) {
    return String(s || '')
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;');
  }

  function colourLog(line) {
    if (line.includes('[SUCCESS]')) return `<span class="text-success">${escHtml(line)}</span>`;
    if (line.includes('[ERROR]')) return `<span class="text-danger">${escHtml(line)}</span>`;
    if (line.includes('[WARNING]')) return `<span class="text-warning">${escHtml(line)}</span>`;
    return `<span class="text-muted">${escHtml(line)}</span>`;
  }

  function setText(id, text) {
    const el = document.getElementById(id);
    if (el) el.textContent = text;
  }

  function show(el, visible) {
    if (!el) return;
    el.classList.toggle('d-none', !visible);
  }

  async function loadStatus() {
    try {
      const r = await fetch(`${API}/update/status`, { headers: authHeaders() });
      const d = await r.json();
      setText('updCurrentVersion', d.current_version || '—');
      setText('updGitCommit', d.git_commit || '—');
      const logBox = document.getElementById('updLogBox');
      if (logBox) {
        if (!d.has_logs) {
          logBox.innerHTML = '<span class="text-muted">No update log yet.</span>';
        } else {
          logBox.innerHTML = (d.recent_logs || []).map(colourLog).join('<br>');
          logBox.scrollTop = logBox.scrollHeight;
        }
      }
      if (d.in_progress) {
        setText('updStatusBadge', 'Update running…');
        startPolling();
      }
    } catch (e) {
      console.error('update status', e);
    }
  }

  async function checkUpdates() {
    const btn = document.getElementById('updCheckBtn');
    const spin = document.getElementById('updCheckSpinner');
    if (btn) btn.disabled = true;
    if (spin) spin.classList.remove('d-none');

    try {
      const r = await fetch(`${API}/update/check`, { headers: authHeaders() });
      const d = await r.json();
      setText('updCurrentVersion', d.current_version || '—');
      setText('updGitCommit', d.git_commit || '—');
      setText('updDeployMode', (d.deployment_mode || 'cloud').toUpperCase());
      setText('updPlatform', d.platform || '—');

      const card = document.getElementById('updResultCard');
      const upToDate = document.getElementById('updUpToDate');
      const available = document.getElementById('updAvailable');
      const errEl = document.getElementById('updCheckError');
      const applyBtn = document.getElementById('updApplyBtn');

      show(card, true);
      show(upToDate, false);
      show(available, false);
      show(errEl, false);

      if (d.error && !d.update_available) {
        show(errEl, true);
        if (errEl) errEl.textContent = d.error;
      }

      if (!d.update_available) {
        show(upToDate, true);
        if (applyBtn) applyBtn.disabled = true;
      } else {
        show(available, true);
        setText('updLatestVersion', d.latest_version ? `v${d.latest_version}` : 'New commits on GitHub');
        const notes = document.getElementById('updReleaseNotes');
        if (notes) {
          const body = d.release_notes || (d.pending_commits || []).join('\n');
          notes.textContent = body || 'Updates available from origin/main.';
        }
        const commits = document.getElementById('updPendingCommits');
        if (commits && d.pending_commits && d.pending_commits.length) {
          commits.innerHTML = d.pending_commits.map((c) => `<li><code>${escHtml(c)}</code></li>`).join('');
          show(document.getElementById('updPendingWrap'), true);
        }
        const link = document.getElementById('updReleaseLink');
        if (link && d.release_url) {
          link.href = d.release_url;
          show(link, true);
        }
        if (applyBtn) {
          applyBtn.disabled = !isAdmin() || !d.can_trigger_update || d.in_progress || d.update_enabled === false;
        }
      }

      if (!isAdmin()) {
        const warn = document.getElementById('updAdminOnly');
        show(warn, true);
        if (applyBtn) applyBtn.disabled = true;
      }
    } catch (e) {
      show(document.getElementById('updCheckError'), true);
      setText('updCheckError', e.message);
    } finally {
      if (btn) btn.disabled = false;
      if (spin) spin.classList.add('d-none');
    }
  }

  async function applyUpdate(force) {
    const msg = force
      ? 'Force update from GitHub? A backup runs first, then the server restarts.'
      : 'Apply available updates? A backup runs first, then the server restarts.';
    if (!confirm(msg + '\n\nYou may be logged out for 1–3 minutes.')) return;

    const btn = document.getElementById('updApplyBtn');
    const spin = document.getElementById('updApplySpinner');
    if (btn) btn.disabled = true;
    if (spin) spin.classList.remove('d-none');
    setText('updStatusBadge', 'Starting update…');

    try {
      const r = await fetch(`${API}/update/trigger`, { method: 'POST', headers: authHeaders() });
      const d = await r.json().catch(() => ({}));
      if (!r.ok) {
        const detail = d.detail;
        const msg = typeof detail === 'string' ? detail : Array.isArray(detail) ? detail.map((x) => x.msg || x).join(', ') : d.message;
        throw new Error(msg || 'Update failed to start');
      }
      startPolling();
    } catch (e) {
      alert(e.message || 'Could not start update');
      if (btn) btn.disabled = false;
      if (spin) spin.classList.add('d-none');
    }
  }

  function startPolling() {
    if (pollTimer) return;
    pollTimer = setInterval(async () => {
      await loadStatus();
      const box = document.getElementById('updLogBox');
      const text = box ? box.textContent : '';
      if (text.includes('completed successfully') || text.includes('FAILED')) {
        stopPolling();
        const btn = document.getElementById('updApplyBtn');
        const spin = document.getElementById('updApplySpinner');
        if (btn) btn.disabled = false;
        if (spin) spin.classList.add('d-none');
        setText('updStatusBadge', text.includes('FAILED') ? 'Update failed' : 'Update complete');
        await checkUpdates();
      }
    }, 3000);
  }

  function stopPolling() {
    if (pollTimer) {
      clearInterval(pollTimer);
      pollTimer = null;
    }
  }

  function init() {
    const section = document.getElementById('app-updates-settings');
    if (!section) return;

    document.getElementById('updCheckBtn')?.addEventListener('click', checkUpdates);
    document.getElementById('updApplyBtn')?.addEventListener('click', () => applyUpdate(false));
    document.getElementById('updForceBtn')?.addEventListener('click', () => applyUpdate(true));
    document.getElementById('updRefreshLog')?.addEventListener('click', loadStatus);

    if (!isAdmin()) {
      show(document.getElementById('updAdminOnly'), true);
      const apply = document.getElementById('updApplyBtn');
      const force = document.getElementById('updForceBtn');
      if (apply) apply.disabled = true;
      if (force) force.disabled = true;
    }

    loadStatus();
    checkUpdates();
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
  } else {
    init();
  }
})();
