(function () {
  let active = false;
  let initialized = false;

  const API_URL = (() => {
    if (window.API_URL) return window.API_URL;
    try {
      return `${window.location.origin}/api`;
    } catch (error) {
      return 'https://fb.srv.medeba-media.de/api';
    }
  })();
  const LOGIN_PAGE = 'login.html';

  const state = {
    traces: [],
    selectedTraceId: null,
    loading: false
  };

  const tableBody = document.getElementById('aiDebugTableBody');
  const statusEl = document.getElementById('aiDebugStatus');
  const detailMeta = document.getElementById('aiDebugDetailMeta');
  const detailViz = document.getElementById('aiDebugDetailViz');
  const detailJson = document.getElementById('aiDebugDetailJson');
  const refreshBtn = document.getElementById('aiDebugRefreshBtn');
  const statusFilter = document.getElementById('aiDebugStatusFilter');
  const limitFilter = document.getElementById('aiDebugLimitFilter');

  function handleUnauthorized(response) {
    if (response && response.status === 401) {
      if (typeof redirectToLogin === 'function') {
        redirectToLogin();
      } else {
        window.location.href = LOGIN_PAGE;
      }
      return true;
    }
    return false;
  }

  async function apiFetchJSON(path, options = {}) {
    const response = await fetch(`${API_URL}${path}`, {
      credentials: 'include',
      ...options
    });

    if (handleUnauthorized(response)) {
      throw new Error('Nicht angemeldet');
    }

    if (!response.ok) {
      const payload = await response.json().catch(() => ({}));
      throw new Error(payload.error || 'Unbekannter Fehler');
    }

    return response.json();
  }

  function setStatus(message, isError = false) {
    if (!statusEl) return;
    statusEl.textContent = message || '';
    statusEl.classList.toggle('ai-debug-status--error', !!isError);
  }

  function formatDate(value) {
    if (!value) return '—';
    const date = new Date(value);
    if (Number.isNaN(date.getTime())) return '—';
    return date.toLocaleString('de-DE', {
      day: '2-digit',
      month: '2-digit',
      year: 'numeric',
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit'
    });
  }

  function formatMs(value) {
    const numeric = Number(value);
    if (!Number.isFinite(numeric) || numeric < 0) {
      return '—';
    }
    return `${Math.round(numeric)} ms`;
  }

  function compactId(value) {
    if (!value || typeof value !== 'string') return '—';
    if (value.length <= 16) return value;
    return `${value.slice(0, 8)}…${value.slice(-6)}`;
  }

  function toPositiveNumber(value) {
    const numeric = Number(value);
    if (!Number.isFinite(numeric) || numeric < 0) {
      return null;
    }
    return numeric;
  }

  function getBackendTotalMs(item) {
    return item
      && item.backend_timings
      && typeof item.backend_timings === 'object'
      ? item.backend_timings.totalMs
      : null;
  }

  function getAiRequestMs(item) {
    return item
      && item.frontend_timings
      && typeof item.frontend_timings === 'object'
      ? item.frontend_timings.aiRequestMs
      : null;
  }

  function renderTable() {
    if (!tableBody) return;
    tableBody.innerHTML = '';

    if (!state.traces.length) {
      const tr = document.createElement('tr');
      tr.innerHTML = '<td colspan="6" class="ai-debug-empty">Keine Debug-Läufe gefunden.</td>';
      tableBody.appendChild(tr);
      return;
    }

    const totals = state.traces
      .map((item) => toPositiveNumber(item.total_duration_ms))
      .filter((value) => value !== null);
    const maxTotal = totals.length ? Math.max(...totals) : 0;

    state.traces.forEach((item) => {
      const tr = document.createElement('tr');
      tr.dataset.traceId = item.trace_id;
      if (item.trace_id === state.selectedTraceId) {
        tr.classList.add('is-selected');
      }

      const totalMs = toPositiveNumber(item.total_duration_ms);
      const totalBarPercent = maxTotal > 0 && totalMs !== null
        ? Math.max(4, Math.round((totalMs / maxTotal) * 100))
        : 0;

      tr.innerHTML = `
        <td>${formatDate(item.created_at)}</td>
        <td><span class="ai-debug-badge ai-debug-badge--${(item.status || 'unknown').replace(/[^a-z0-9_-]/gi, '')}">${item.status || '—'}</span></td>
        <td>
          <div class="ai-debug-inline-metric">
            <span>${formatMs(item.total_duration_ms)}</span>
            <span class="ai-debug-inline-bar" aria-hidden="true"><span style="width: ${totalBarPercent}%"></span></span>
          </div>
        </td>
        <td>${formatMs(getBackendTotalMs(item))}</td>
        <td>${formatMs(getAiRequestMs(item))}</td>
        <td><code>${compactId(item.flow_id)}</code> / <code>${compactId(item.trace_id)}</code></td>
      `;

      tableBody.appendChild(tr);
    });
  }

  function collectFrontendBars(trace) {
    const front = trace && trace.frontend_timings && typeof trace.frontend_timings === 'object'
      ? trace.frontend_timings
      : {};

    const mapping = [
      ['extractPostTextMs', 'Text-Extraktion'],
      ['profileLookupMs', 'Profil-Lookup'],
      ['aiRequestMs', 'AI-Request'],
      ['waitForCommentInputMs', 'Wartezeit Kommentarfeld'],
      ['setCommentTextMs', 'Kommentar einfügen'],
      ['confirmParticipationMs', 'Auto-Bestätigung'],
      ['clipboardWriteMs', 'Clipboard-Fallback'],
      ['totalMs', 'Frontend Total']
    ];

    return mapping
      .map(([key, label]) => ({
        key,
        label,
        value: toPositiveNumber(front[key])
      }))
      .filter((entry) => entry.value !== null);
  }

  function collectBackendBars(trace) {
    const back = trace && trace.backend_timings && typeof trace.backend_timings === 'object'
      ? trace.backend_timings
      : {};

    const mapping = [
      ['loadSettingsMs', 'Settings laden'],
      ['reactivateCredentialsMs', 'Credentials reaktivieren'],
      ['loadCredentialsMs', 'Credentials laden'],
      ['buildPromptMs', 'Prompt bauen'],
      ['credentialLoopMs', 'Provider-/Credential-Loop'],
      ['totalMs', 'Backend Total']
    ];

    return mapping
      .map(([key, label]) => ({
        key,
        label,
        value: toPositiveNumber(back[key])
      }))
      .filter((entry) => entry.value !== null);
  }

  function collectCredentialBars(trace) {
    const attempts = trace && Array.isArray(trace.backend_attempts)
      ? trace.backend_attempts
      : [];

    return attempts
      .map((attempt, index) => {
        const credential = attempt && attempt.credentialName ? attempt.credentialName : `Credential ${index + 1}`;
        const status = attempt && attempt.status ? attempt.status : 'unknown';
        return {
          key: `credential_${index + 1}`,
          label: `${credential} (${status})`,
          value: toPositiveNumber(attempt && attempt.duration_ms)
        };
      })
      .filter((entry) => entry.value !== null);
  }

  function renderBarGroup(title, rows) {
    if (!Array.isArray(rows) || !rows.length) {
      return '';
    }

    const max = Math.max(...rows.map((entry) => entry.value));
    const sorted = [...rows].sort((a, b) => b.value - a.value);
    const peakKey = sorted[0] ? sorted[0].key : null;

    const items = rows.map((entry) => {
      const width = max > 0
        ? Math.max(4, Math.round((entry.value / max) * 100))
        : 0;
      const peakClass = entry.key === peakKey ? ' ai-debug-bar-row--peak' : '';
      return `
        <li class="ai-debug-bar-row${peakClass}">
          <span class="ai-debug-bar-label">${entry.label}</span>
          <span class="ai-debug-bar-track" aria-hidden="true">
            <span class="ai-debug-bar-fill" style="width: ${width}%"></span>
          </span>
          <span class="ai-debug-bar-value">${formatMs(entry.value)}</span>
        </li>
      `;
    }).join('');

    return `
      <section class="ai-debug-viz-group">
        <h4>${title}</h4>
        <ul class="ai-debug-bars">
          ${items}
        </ul>
      </section>
    `;
  }

  function renderDetailVisualization(trace) {
    if (!detailViz) {
      return;
    }

    if (!trace) {
      detailViz.innerHTML = '';
      return;
    }

    const frontendBars = collectFrontendBars(trace);
    const backendBars = collectBackendBars(trace);
    const credentialBars = collectCredentialBars(trace);

    const sections = [
      renderBarGroup('Frontend-Phasen', frontendBars),
      renderBarGroup('Backend-Phasen', backendBars),
      renderBarGroup('Credential-Attempts', credentialBars)
    ].filter(Boolean);

    if (!sections.length) {
      detailViz.innerHTML = '<div class="ai-debug-viz-empty">Keine Timing-Daten für diesen Lauf verfügbar.</div>';
      return;
    }

    detailViz.innerHTML = sections.join('');
  }

  function renderDetail(trace) {
    if (!detailMeta || !detailJson) {
      return;
    }
    if (!trace) {
      detailMeta.textContent = 'Bitte einen Eintrag auswählen.';
      renderDetailVisualization(null);
      detailJson.textContent = '';
      return;
    }

    detailMeta.textContent = `${trace.status || '—'} · ${formatDate(trace.created_at)} · Trace ${trace.trace_id || '—'}`;
    renderDetailVisualization(trace);
    detailJson.textContent = JSON.stringify(trace, null, 2);
  }

  async function loadTraceDetail(traceId) {
    if (!traceId) {
      renderDetail(null);
      return;
    }
    try {
      const trace = await apiFetchJSON(`/ai/debug-traces/${encodeURIComponent(traceId)}`);
      if (!active) return;
      renderDetail(trace);
    } catch (error) {
      if (!active) return;
      setStatus(`Details konnten nicht geladen werden: ${error.message}`, true);
    }
  }

  async function loadTraces() {
    if (!active || state.loading) {
      return;
    }

    state.loading = true;
    setStatus('Lade Debug-Läufe...');

    try {
      const params = new URLSearchParams();
      const status = statusFilter ? statusFilter.value.trim() : '';
      const limit = limitFilter ? parseInt(limitFilter.value, 10) : 50;
      if (status) {
        params.set('status', status);
      }
      if (Number.isFinite(limit) && limit > 0) {
        params.set('limit', String(limit));
      }

      const data = await apiFetchJSON(`/ai/debug-traces?${params.toString()}`);
      if (!active) return;

      state.traces = Array.isArray(data.items) ? data.items : [];
      if (!state.selectedTraceId || !state.traces.some((item) => item.trace_id === state.selectedTraceId)) {
        state.selectedTraceId = state.traces.length ? state.traces[0].trace_id : null;
      }

      renderTable();
      await loadTraceDetail(state.selectedTraceId);
      setStatus(`${state.traces.length} Lauf/Läufe geladen.`);
    } catch (error) {
      if (!active) return;
      state.traces = [];
      renderTable();
      renderDetail(null);
      setStatus(`Debug-Läufe konnten nicht geladen werden: ${error.message}`, true);
    } finally {
      state.loading = false;
    }
  }

  function setupEvents() {
    if (refreshBtn) {
      refreshBtn.addEventListener('click', () => loadTraces());
    }

    if (statusFilter) {
      statusFilter.addEventListener('change', () => loadTraces());
    }

    if (limitFilter) {
      limitFilter.addEventListener('change', () => loadTraces());
    }

    if (tableBody) {
      tableBody.addEventListener('click', (event) => {
        const row = event.target.closest('tr[data-trace-id]');
        if (!row) return;
        const traceId = row.dataset.traceId;
        if (!traceId) return;
        state.selectedTraceId = traceId;
        renderTable();
        loadTraceDetail(traceId);
      });
    }
  }

  function init() {
    if (initialized) return;
    setupEvents();
    initialized = true;
  }

  function activate() {
    init();
    active = true;
    loadTraces();
  }

  function deactivate() {
    active = false;
  }

  window.AIDebugPage = {
    activate,
    deactivate
  };

  const section = document.querySelector('[data-view="ai-debug"]');
  if (section && section.classList.contains('app-view--active')) {
    activate();
  }
})();
