const state = { data: null, filter: '', busy: false };

function csrfToken() {
  const match = document.cookie.match(/(?:^|;\s*)csrf_token=([^;]+)/);
  return match ? decodeURIComponent(match[1]) : '';
}

async function request(method, url, body, { multipart = false } = {}) {
  const headers = { 'X-Vendoo-Request-ID': globalThis.crypto?.randomUUID?.() || `modules-${Date.now()}` };
  const options = { method, credentials: 'same-origin', headers };
  if (!['GET', 'HEAD'].includes(method)) headers['X-CSRF-Token'] = csrfToken();
  if (body !== undefined) {
    if (multipart) options.body = body;
    else { headers['Content-Type'] = 'application/json'; options.body = JSON.stringify(body); }
  }
  const response = await fetch(url, options);
  if (response.status === 401) { location.href = '/login.html'; return null; }
  const type = response.headers.get('content-type') || '';
  const payload = type.includes('json') ? await response.json().catch(() => ({})) : await response.text();
  if (!response.ok) throw new Error(payload?.error || payload?.message || payload || `HTTP ${response.status}`);
  return payload;
}

function el(tag, className, text) {
  const node = document.createElement(tag);
  if (className) node.className = className;
  if (text !== undefined) node.textContent = text;
  return node;
}

function button(label, action, id, { danger = false, disabled = false } = {}) {
  const node = el('button', danger ? 'secondary-btn danger' : 'secondary-btn', label);
  node.type = 'button';
  node.dataset.moduleAction = action;
  node.dataset.moduleId = id;
  node.disabled = disabled;
  return node;
}

function renderSummary(data) {
  const root = document.getElementById('module-manager-summary');
  if (!root) return;
  root.replaceChildren();
  const items = [
    ['Module gesamt', data.summary.total], ['Aktiv', data.summary.enabled], ['Deaktiviert', data.summary.disabled],
    ['Nativ', data.summary.native], ['Installiert', data.summary.external],
  ];
  for (const [label, value] of items) {
    const card = el('article', 'module-summary-card');
    card.append(el('span', '', label), el('strong', '', String(value)));
    root.append(card);
  }
  const safety = document.getElementById('module-manager-safety');
  if (safety) {
    safety.className = `module-safety-card${data.safety.isolatedHostAvailable ? '' : ' is-warning'}`;
    safety.replaceChildren();
    const text = el('div');
    text.append(el('strong', '', 'Sicherheitsmodus'), el('p', '', data.safety.isolatedHostAvailable
      ? 'Signierte Fremdmodule laufen ausschließlich im isolierten Extension-Host.'
      : 'Deklarative Module sind aktivierbar. Ausführbarer Fremdcode bleibt bis zum isolierten Extension-Host quarantänisiert.'));
    safety.append(text);
  }
}

function renderModules() {
  const root = document.getElementById('module-manager-list');
  if (!root) return;
  root.replaceChildren();
  const query = state.filter.trim().toLowerCase();
  const modules = (state.data?.modules || []).filter(item => !query || [item.id, item.name, item.description, item.status, item.installSource].join(' ').toLowerCase().includes(query));
  if (!modules.length) { root.append(el('div', 'module-empty', 'Keine passenden Module gefunden.')); return; }

  for (const item of modules) {
    const card = el('article', `module-card ${item.enabled ? '' : 'is-disabled'} ${item.state === 'invalid' ? 'is-invalid' : ''}`.trim());
    const head = el('header', 'module-card-head');
    const titleWrap = el('div', 'module-card-title');
    titleWrap.append(el('span', `module-state-dot is-${item.state || (item.enabled ? 'running' : 'disabled')}`));
    const title = el('div');
    title.append(el('h4', '', item.name || item.id), el('code', '', item.id));
    titleWrap.append(title);
    const version = el('strong', '', item.version ? `v${item.version}` : '—');
    head.append(titleWrap, version);
    card.append(head);

    const badges = el('div', 'module-badges');
    badges.append(el('span', 'module-badge', item.enabled ? 'Aktiv' : 'Deaktiviert'));
    badges.append(el('span', 'module-badge', item.status === 'legacy-bridge' ? 'Legacy Bridge' : item.status === 'native' ? 'Nativ' : item.status));
    badges.append(el('span', 'module-badge', item.installSource === 'builtin' ? 'Vendoo' : 'Installiert'));
    if (item.protected) badges.append(el('span', 'module-badge', 'Geschützt'));
    if (item.package?.trust?.signed) badges.append(el('span', 'module-badge', item.package.trust.trusted ? 'Signatur vertraut' : 'Signatur unbekannt'));
    card.append(badges);
    card.append(el('p', 'module-description', item.description || 'Keine Beschreibung vorhanden.'));
    if (item.requires?.length) {
      const deps = el('div', 'module-dependencies');
      deps.append(el('strong', '', 'Benötigt: '), document.createTextNode(item.requires.join(', ')));
      card.append(deps);
    }
    if (item.dependents?.length) {
      const deps = el('div', 'module-dependencies');
      deps.append(el('strong', '', 'Wird benötigt von: '), document.createTextNode(item.dependents.join(', ')));
      card.append(deps);
    }
    if (item.package?.error || item.error) card.append(el('div', 'module-error', item.package?.error || item.error));

    const actions = el('div', 'module-card-actions');
    if (item.actions?.enable) actions.append(button('Aktivieren', 'enable', item.id));
    if (item.actions?.disable) actions.append(button('Deaktivieren', 'disable', item.id, { danger: true }));
    if (item.actions?.export) {
      const link = el('a', 'secondary-btn', 'Exportieren');
      link.href = `/api/admin/modules/${encodeURIComponent(item.id)}/export`;
      link.download = `${item.id}.vmod`;
      actions.append(link);
    }
    if (item.actions?.remove) actions.append(button('Löschen', 'remove', item.id, { danger: true }));
    if (item.protected && !actions.childNodes.length) actions.append(el('span', 'module-dependencies', 'Kernmodul – Änderungen gesperrt'));
    card.append(actions);
    root.append(card);
  }
}

async function load() {
  const list = document.getElementById('module-manager-list');
  if (!list) return;
  list.replaceChildren(el('div', 'module-empty', 'Module werden geladen …'));
  try {
    state.data = await request('GET', '/api/admin/modules');
    renderSummary(state.data);
    renderModules();
  } catch (error) {
    list.replaceChildren(el('div', 'module-error', error.message));
  }
}

async function perform(action, id) {
  if (state.busy) return;
  state.busy = true;
  try {
    if (action === 'enable') await request('POST', `/api/admin/modules/${encodeURIComponent(id)}/enable`, {});
    if (action === 'disable') {
      const item = state.data?.modules?.find(module => module.id === id);
      const hasDependents = Boolean(item?.dependents?.length);
      const message = hasDependents
        ? `Dieses Modul wird von ${item.dependents.join(', ')} benötigt. Abhängige optionale Module ebenfalls deaktivieren?`
        : 'Modul wirklich deaktivieren? Die zugehörigen API-Funktionen stehen danach bis zur Reaktivierung nicht zur Verfügung.';
      if (!confirm(message)) return;
      await request('POST', `/api/admin/modules/${encodeURIComponent(id)}/disable`, { cascade: hasDependents });
    }
    if (action === 'remove') {
      if (!confirm('Installiertes Modul dauerhaft löschen? Die exportierte .vmod-Datei sollte vorher gesichert werden.')) return;
      await request('DELETE', `/api/admin/modules/${encodeURIComponent(id)}`);
    }
    await load();
    globalThis.toast?.(action === 'enable' ? 'Modul aktiviert.' : action === 'disable' ? 'Modul deaktiviert.' : 'Modul gelöscht.');
  } catch (error) {
    globalThis.toast?.(error.message);
    if (!globalThis.toast) alert(error.message);
  } finally { state.busy = false; }
}

async function install() {
  const input = document.getElementById('module-manager-file');
  const file = input?.files?.[0];
  if (!file) { globalThis.toast?.('Bitte zuerst eine .vmod-Datei auswählen.'); return; }
  if (!file.name.toLowerCase().endsWith('.vmod')) { globalThis.toast?.('Nur .vmod-Pakete werden akzeptiert.'); return; }
  const form = new FormData();
  form.append('module', file, file.name);
  try {
    await request('POST', '/api/admin/modules/install', form, { multipart: true });
    input.value = '';
    await load();
    globalThis.toast?.('Modulpaket geprüft und installiert.');
  } catch (error) {
    globalThis.toast?.(error.message);
    if (!globalThis.toast) alert(error.message);
  }
}

function setup() {
  document.getElementById('module-manager-refresh')?.addEventListener('click', load);
  document.getElementById('module-manager-install')?.addEventListener('click', install);
  document.getElementById('module-manager-search')?.addEventListener('input', event => { state.filter = event.target.value; renderModules(); });
  document.getElementById('module-manager-list')?.addEventListener('click', event => {
    const target = event.target.closest('[data-module-action]');
    if (target) perform(target.dataset.moduleAction, target.dataset.moduleId);
  });
}

document.addEventListener('DOMContentLoaded', setup, { once: true });
globalThis.VendooModuleManager = Object.freeze({ load });
