import { apiRequest } from '../../core/api-client.js';

const root = document.getElementById('theme-manager-root');
if (!root) throw new Error('Theme Manager Root fehlt.');

const state = {
  catalog: null,
  me: null,
  selectedThemeId: 'inherit',
  editingId: null,
  draftId: null,
  editorValues: {},
};

const $ = selector => root.querySelector(selector);
const status = (message, tone = 'info') => {
  const node = $('#theme-manager-status');
  node.textContent = message;
  node.dataset.tone = tone;
};

function cssValues(values = {}) {
  const tokens = state.catalog?.contract?.tokens || {};
  return Object.fromEntries(Object.entries(values).flatMap(([name, value]) => tokens[name]?.css ? [[tokens[name].css, value]] : []));
}

function profileById(id) {
  return [...(state.catalog?.builtin || []), ...(state.catalog?.custom || [])].find(theme => theme.id === id) || null;
}

function runtimeState(preference, profile = null) {
  return {
    theme_id: preference.theme_id,
    density: preference.density,
    reduced_motion: preference.reduced_motion,
    custom_theme: profile && !profile.builtin ? {
      id: profile.id,
      base_theme: profile.base_theme,
      css_values: cssValues(profile.resolved_values || profile.values),
    } : null,
  };
}

function applyPreference(preference, { persist = true } = {}) {
  const effective = preference.theme_id === 'inherit' ? state.catalog.system_default : preference;
  const profile = profileById(effective.theme_id);
  window.VendooTheme?.applyState(runtimeState(effective, profile), { persist });
}


function renderChoices() {
  const host = $('#theme-choice-grid');
  const choices = [
    { id: 'inherit', name: 'Systemstandard', base_theme: state.catalog.system_default.theme_id, resolved_values: profileById(state.catalog.system_default.theme_id)?.resolved_values || profileById('light').resolved_values, builtin: true },
    { id: 'system', name: 'Betriebssystem', base_theme: 'system', resolved_values: profileById(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light').resolved_values, builtin: true },
    ...state.catalog.builtin.filter(item => item.id !== 'system'),
    ...state.catalog.custom,
  ];
  host.replaceChildren(...choices.map(profile => {
    const button = document.createElement('button');
    button.type = 'button';
    button.className = 'theme-choice';
    button.dataset.themeId = profile.id;
    button.setAttribute('aria-pressed', String(profile.id === state.selectedThemeId));
    const swatchWrap = document.createElement('span');
    swatchWrap.className = 'theme-choice-swatches';
    swatchWrap.setAttribute('aria-hidden', 'true');
    for (const token of ['color.canvas', 'color.surface', 'color.brand', 'color.ink']) {
      const swatch = document.createElement('i');
      swatch.style.background = profile.resolved_values?.[token] || '#888888';
      swatchWrap.append(swatch);
    }
    const copy = document.createElement('span');
    const title = document.createElement('strong'); title.textContent = profile.name;
    const meta = document.createElement('small'); meta.textContent = profile.builtin ? 'Vendoo Preset' : 'Eigenes Theme';
    copy.append(title, meta); button.append(swatchWrap, copy);
    button.addEventListener('click', () => selectTheme(profile.id));
    return button;
  }));
}

function selectTheme(themeId) {
  state.selectedThemeId = themeId;
  root.querySelectorAll('.theme-choice').forEach(button => button.setAttribute('aria-pressed', String(button.dataset.themeId === themeId)));
  const preference = {
    theme_id: themeId,
    density: $('#theme-density').value,
    reduced_motion: $('#theme-reduced-motion').value,
  };
  applyPreference(preference, { persist: false });
  status('Vorschau aktiv. Mit „Meine Darstellung speichern“ dauerhaft übernehmen.');
}


function renderSystemOptions() {
  const select = $('#theme-system-default');
  const selected = state.catalog.system_default.theme_id;
  [...select.querySelectorAll('option[data-custom="true"]')].forEach(option => option.remove());
  for (const profile of state.catalog.custom) {
    const option = document.createElement('option');
    option.value = profile.id;
    option.textContent = profile.name;
    option.dataset.custom = 'true';
    select.append(option);
  }
  select.value = selected;
}

function renderProfiles() {
  const list = $('#theme-profile-list');
  list.replaceChildren(...state.catalog.custom.map(profile => {
    const row = document.createElement('div');
    row.className = 'theme-profile-row';
    const copy = document.createElement('div');
    const title = document.createElement('strong');
    title.textContent = profile.name;
    const meta = document.createElement('small');
    meta.textContent = `Basis: ${profile.base_theme} · ${Object.keys(profile.values || {}).length} Anpassungen`;
    copy.append(title, document.createElement('br'), meta);
    const actions = document.createElement('div');
    const edit = document.createElement('button'); edit.type = 'button'; edit.className = 'vd-button compact'; edit.textContent = 'Bearbeiten'; edit.addEventListener('click', () => openEditor(profile));
    const exp = document.createElement('button'); exp.type = 'button'; exp.className = 'vd-button compact'; exp.textContent = 'Export'; exp.addEventListener('click', () => exportProfile(profile.id));
    actions.append(edit, exp); row.append(copy, actions); return row;
  }));
  if (!state.catalog.custom.length) {
    const empty = document.createElement('p'); empty.className = 'theme-manager-status'; empty.textContent = 'Noch keine eigenen Themes angelegt.'; list.append(empty);
  }
}

function baseValues(baseTheme) {
  return profileById(baseTheme)?.resolved_values || profileById('light')?.resolved_values || {};
}

function currentEditorDefinition() {
  return {
    id: state.editingId || state.draftId || 'custom-draft',
    name: $('#theme-editor-name').value.trim(),
    base_theme: $('#theme-editor-base').value,
    values: { ...state.editorValues },
  };
}

function renderTokenFields(profile = null) {
  const baseTheme = $('#theme-editor-base').value;
  const defaults = baseValues(baseTheme);
  const contract = state.catalog.contract.tokens;
  const groups = new Map();
  for (const [name, token] of Object.entries(contract)) {
    if (!token.customizable) continue;
    if (!groups.has(token.group)) groups.set(token.group, []);
    groups.get(token.group).push([name, token]);
  }
  const host = $('#theme-token-groups');
  host.replaceChildren(...[...groups.entries()].map(([groupName, entries]) => {
    const section = document.createElement('section'); section.className = 'theme-token-group';
    const heading = document.createElement('h4'); heading.textContent = groupName; section.append(heading);
    const list = document.createElement('div'); list.className = 'theme-token-list';
    for (const [name, token] of entries) {
      const field = document.createElement('div'); field.className = 'theme-token-field';
      const label = document.createElement('label'); label.htmlFor = `theme-token-${name.replace(/[^a-z0-9]/gi, '-')}`; label.textContent = token.label;
      const value = state.editorValues[name] ?? defaults[name] ?? '';
      if (token.type === 'color') {
        const wrap = document.createElement('div'); wrap.className = 'theme-color-control';
        const color = document.createElement('input'); color.type = 'color'; color.value = /^#[0-9a-f]{6}$/i.test(value) ? value : '#000000'; color.tabIndex = -1; color.setAttribute('aria-hidden', 'true');
        const text = document.createElement('input'); text.id = label.htmlFor; text.className = 'vd-input'; text.value = value; text.dataset.token = name;
        color.addEventListener('input', () => { text.value = color.value; updateEditorValue(name, text.value); });
        text.addEventListener('input', () => { if (/^#[0-9a-f]{6}$/i.test(text.value)) color.value = text.value; updateEditorValue(name, text.value); });
        wrap.append(color, text); field.append(label, wrap);
      } else {
        const input = document.createElement('input'); input.id = label.htmlFor; input.className = 'vd-input'; input.value = value; input.dataset.token = name; input.inputMode = 'decimal';
        input.addEventListener('input', () => updateEditorValue(name, input.value)); field.append(label, input);
      }
      list.append(field);
    }
    section.append(list); return section;
  }));
  previewEditor();
}

function updateEditorValue(name, value) {
  const base = baseValues($('#theme-editor-base').value)[name];
  if (String(value).trim() === String(base).trim()) delete state.editorValues[name];
  else state.editorValues[name] = String(value).trim();
  previewEditor();
}

function previewEditor() {
  const definition = currentEditorDefinition();
  const merged = { ...baseValues(definition.base_theme), ...definition.values };
  window.VendooTheme?.previewTheme({ base_theme: definition.base_theme, css_values: cssValues(merged), density: $('#theme-density').value, reduced_motion: $('#theme-reduced-motion').value });
  $('#theme-preview-name').textContent = definition.name || 'Theme-Vorschau';
}


async function validateEditor(showMessage = true) {
  try {
    const result = await apiRequest('/api/themes/validate', { method: 'POST', body: currentEditorDefinition() });
    renderContrast(result.accessibility);
    if (showMessage) status(result.accessibility.ok ? 'Theme ist gültig und erfüllt die geprüften Kontrastziele.' : 'Theme ist gültig, hat aber Kontrastwarnungen.', result.accessibility.ok ? 'success' : 'warning');
    return result;
  } catch (error) {
    renderContrast({ checks: [], ok: false });
    if (showMessage) status(error.message, 'danger');
    return null;
  }
}

function renderContrast(accessibility) {
  const host = $('#theme-contrast-list');
  host.replaceChildren(...(accessibility?.checks || []).map(check => {
    const row = document.createElement('div'); row.className = `theme-contrast-row ${check.ok ? 'is-ok' : 'is-fail'}`;
    const label = document.createElement('span'); label.textContent = check.id.replaceAll('-', ' ');
    const result = document.createElement('strong'); result.textContent = `${check.ratio ?? '–'} : 1`;
    row.append(label, result); return row;
  }));
}

function openEditor(profile = null) {
  state.editingId = profile?.id || null;
  state.draftId = profile?.id || `custom-${Date.now().toString(36)}`;
  state.editorValues = { ...(profile?.values || {}) };
  $('#theme-editor-name').value = profile?.name || '';
  $('#theme-editor-base').value = profile?.base_theme || 'light';
  $('#theme-delete-btn').hidden = !profile;
  $('#theme-editor-title').textContent = profile ? 'Theme bearbeiten' : 'Neues Theme';
  renderTokenFields(profile);
  $('#theme-editor-name').focus();
}

async function savePreference() {
  const payload = { theme_id: state.selectedThemeId, density: $('#theme-density').value, reduced_motion: $('#theme-reduced-motion').value };
  try {
    const saved = await apiRequest('/api/themes/preference', { method: 'PUT', body: payload });
    state.catalog.preference = saved;
    applyPreference(saved, { persist: true });
    status('Deine Darstellung wurde sicher gespeichert.', 'success');
  } catch (error) { status(error.message, 'danger'); }
}

async function saveProfile() {
  const valid = await validateEditor(true); if (!valid) return;
  const definition = currentEditorDefinition();
  try {
    const profile = state.editingId
      ? await apiRequest(`/api/themes/${encodeURIComponent(state.editingId)}`, { method: 'PUT', body: definition })
      : await apiRequest('/api/themes', { method: 'POST', body: definition });
    await reloadCatalog();
    renderSystemOptions();
    state.editingId = profile.id;
    state.selectedThemeId = profile.id;
    renderChoices(); renderProfiles(); openEditor(profile);
    status('Theme gespeichert.', 'success');
  } catch (error) { status(error.message, 'danger'); }
}

async function deleteProfile() {
  if (!state.editingId || !confirm('Dieses Theme wirklich löschen? Benutzer mit diesem Theme fallen auf den Systemstandard zurück.')) return;
  try {
    await apiRequest(`/api/themes/${encodeURIComponent(state.editingId)}`, { method: 'DELETE' });
    await reloadCatalog(); renderSystemOptions(); state.selectedThemeId = state.catalog.preference.theme_id; renderChoices(); renderProfiles(); openEditor();
    status('Theme gelöscht.', 'success');
  } catch (error) { status(error.message, 'danger'); }
}

async function saveSystemDefault() {
  const payload = { theme_id: $('#theme-system-default').value, density: $('#theme-system-density').value, reduced_motion: $('#theme-system-motion').value };
  try { state.catalog.system_default = await apiRequest('/api/themes/system-default', { method: 'PUT', body: payload }); status('Systemstandard gespeichert.', 'success'); renderChoices(); }
  catch (error) { status(error.message, 'danger'); }
}

async function exportProfile(id) {
  try {
    const payload = await apiRequest(`/api/themes/${encodeURIComponent(id)}/export`);
    const blob = new Blob([JSON.stringify(payload, null, 2)], { type: 'application/json' });
    const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = `${id}.vendoo-theme.json`; link.click(); URL.revokeObjectURL(link.href);
  } catch (error) { status(error.message, 'danger'); }
}

function importProfile(file) {
  if (!file) return;
  const reader = new FileReader();
  reader.onload = () => {
    try {
      const payload = JSON.parse(String(reader.result));
      const profile = payload.theme || payload;
      state.editingId = null; state.draftId = `custom-${Date.now().toString(36)}`; state.editorValues = { ...(profile.values || {}) };
      $('#theme-editor-name').value = `${profile.name || 'Importiertes Theme'} Kopie`;
      $('#theme-editor-base').value = profile.base_theme || 'light'; renderTokenFields(); status('Import geladen. Prüfen und anschließend speichern.');
    } catch { status('Die Theme-Datei ist ungültig.', 'danger'); }
  };
  reader.readAsText(file);
}

async function reloadCatalog() {
  state.catalog = await apiRequest('/api/themes');
}

async function init() {
  try {
    [state.catalog, state.me] = await Promise.all([apiRequest('/api/themes'), apiRequest('/api/me')]);
    state.selectedThemeId = state.catalog.preference.theme_id;
    $('#theme-density').value = state.catalog.preference.density;
    $('#theme-reduced-motion').value = state.catalog.preference.reduced_motion;
    $('#theme-system-default').value = state.catalog.system_default.theme_id;
    $('#theme-system-density').value = state.catalog.system_default.density;
    $('#theme-system-motion').value = state.catalog.system_default.reduced_motion;
    renderSystemOptions();
    const canManage = state.me.permissions?.includes('settings.manage');
    root.querySelectorAll('.theme-admin-only').forEach(node => node.classList.toggle('hidden', !canManage));
    renderChoices(); renderProfiles(); openEditor(); applyPreference(state.catalog.effective_preference, { persist: true });
    status('Theme Manager bereit.');
  } catch (error) { status(`Theme Manager konnte nicht geladen werden: ${error.message}`, 'danger'); }
}

$('#theme-preference-save').addEventListener('click', savePreference);
$('#theme-density').addEventListener('change', () => selectTheme(state.selectedThemeId));
$('#theme-reduced-motion').addEventListener('change', () => selectTheme(state.selectedThemeId));
$('#theme-new-btn').addEventListener('click', () => openEditor());
$('#theme-editor-base').addEventListener('change', () => { state.editorValues = {}; renderTokenFields(); });
$('#theme-editor-name').addEventListener('input', previewEditor);
$('#theme-validate-btn').addEventListener('click', () => validateEditor(true));
$('#theme-save-btn').addEventListener('click', saveProfile);
$('#theme-delete-btn').addEventListener('click', deleteProfile);
$('#theme-preview-reset').addEventListener('click', () => applyPreference(state.catalog.preference, { persist: false }));
$('#theme-system-save').addEventListener('click', saveSystemDefault);
$('#theme-import-input').addEventListener('change', event => importProfile(event.target.files?.[0]));

init();
