import { initI18n, onLangChange, t, tDyn } from "./i18n";
import { initSidebar } from "./sidebar";

// /admin/email-templates/{key}?lang=de — editor client.
//
// Wires the static SPA shell to the API: fetches active row + variables +
// version log on load, debounces a preview request on every input change,
// posts saves and resets, and offers per-version restore.
//
// Render-only HTML is built with createElement (not innerHTML on user data)
// so a malicious template body can't escape the editor chrome — the
// preview iframe sandboxes the rendered HTML separately.

interface ActiveRow {
  key: string;
  lang: string;
  subject: string;
  body: string;
  updated_at?: string | null;
  is_default: boolean;
}

interface VariableContract {
  name: string;
  type: string;
  description: string;
  sample_de: string;
  sample_en: string;
}

interface VersionRow {
  id: string;
  saved_at: string;
  saved_by?: string | null;
  note: string;
  subject: string;
  body: string;
}

const PREVIEW_DEBOUNCE_MS = 500;

let currentKey = "";
let currentLang: "de" | "en" = "de";
let activeRow: ActiveRow | null = null;
let variables: VariableContract[] = [];
let dirty = false;
let previewTimer: number | null = null;

function readKeyFromPath(): string {
  const m = location.pathname.match(/^\/admin\/email-templates\/([^/]+)/);
  return m ? decodeURIComponent(m[1]) : "";
}

function readLangFromQuery(): "de" | "en" {
  const params = new URLSearchParams(location.search);
  const v = params.get("lang");
  return v === "en" ? "en" : "de";
}

function setLangInURL(lang: "de" | "en") {
  const url = new URL(location.href);
  url.searchParams.set("lang", lang);
  history.replaceState(null, "", url.toString());
}

function showFeedback(msg: string, isError: boolean) {
  const el = document.getElementById("admin-et-feedback");
  if (!el) return;
  el.textContent = msg;
  el.className = "form-msg " + (isError ? "form-msg-error" : "form-msg-success");
  el.style.display = "block";
  if (!isError) {
    setTimeout(() => {
      if (el.textContent === msg) el.style.display = "none";
    }, 3000);
  }
}

function clearFeedback() {
  const el = document.getElementById("admin-et-feedback");
  if (el) el.style.display = "none";
}

function setDirty(d: boolean) {
  dirty = d;
  const saveBtn = document.getElementById("admin-et-save") as HTMLButtonElement | null;
  if (saveBtn) saveBtn.disabled = !d;
}

function fmtDate(iso?: string | null): string {
  if (!iso) return "";
  const d = new Date(iso);
  if (Number.isNaN(d.getTime())) return iso;
  return d.toLocaleString();
}

function applyToInputs(row: ActiveRow) {
  const subj = document.getElementById("admin-et-subject") as HTMLInputElement | null;
  const body = document.getElementById("admin-et-body") as HTMLTextAreaElement | null;
  const subjWrap = document.getElementById("admin-et-subject-wrap");
  if (subj) subj.value = row.subject;
  if (body) body.value = row.body;
  if (subjWrap) {
    // base templates have no subject of their own — hide the field.
    subjWrap.style.display = row.key === "base" ? "none" : "";
  }
  const slot = document.getElementById("admin-et-slot") as HTMLSelectElement | null;
  if (slot) {
    slot.style.display = row.key === "deadline_digest" ? "" : "none";
  }
  setDirty(false);

  const sub = document.getElementById("admin-et-subtitle");
  if (sub) {
    if (row.is_default) {
      sub.textContent = t("admin.email_templates.editor.is_default") || "Aktuell wird der Standard verwendet.";
    } else {
      const tpl = t("admin.email_templates.editor.last_modified") || "Zuletzt geändert: {date}";
      sub.textContent = tpl.replace("{date}", fmtDate(row.updated_at));
    }
  }
}

function applyTitle(key: string, lang: string) {
  const title = document.getElementById("admin-et-title");
  if (!title) return;
  const tpl = t("admin.email_templates.editor.heading_for") ||
    "{title} — {lang}";
  const langName = lang === "en"
    ? (t("admin.email_templates.lang.en") || "Englisch")
    : (t("admin.email_templates.lang.de") || "Deutsch");
  title.textContent = tpl
    .replace("{title}", tDyn(`admin.email_templates.card.${key}.title`) || key)
    .replace("{lang}", langName);
}

function applyLangToggle(lang: "de" | "en") {
  document.querySelectorAll(".admin-et-lang-btn").forEach((el) => {
    const btn = el as HTMLButtonElement;
    const isActive = btn.dataset.lang === lang;
    btn.setAttribute("aria-pressed", isActive ? "true" : "false");
    btn.classList.toggle("active", isActive);
  });
}

function renderVariables() {
  const list = document.getElementById("admin-et-variables-list");
  if (!list) return;
  list.innerHTML = "";
  for (const v of variables) {
    const row = document.createElement("div");
    row.className = "admin-et-variable-row";
    const name = document.createElement("code");
    name.className = "admin-et-variable-name";
    name.textContent = v.name;
    const type = document.createElement("span");
    type.className = "admin-et-variable-type";
    type.textContent = v.type;
    const desc = document.createElement("span");
    desc.className = "admin-et-variable-desc";
    desc.textContent = v.description;
    const sample = document.createElement("span");
    sample.className = "admin-et-variable-sample";
    sample.textContent = "→ " + (currentLang === "en" ? v.sample_en : v.sample_de);
    row.appendChild(name);
    row.appendChild(type);
    row.appendChild(desc);
    row.appendChild(sample);
    list.appendChild(row);
  }
}

function renderVersions(rows: VersionRow[]) {
  const list = document.getElementById("admin-et-versions-list");
  if (!list) return;
  list.innerHTML = "";
  if (rows.length === 0) {
    const empty = document.createElement("li");
    empty.className = "admin-et-version-empty";
    empty.textContent = t("admin.email_templates.editor.versions_empty") || "Keine Versionen.";
    list.appendChild(empty);
    return;
  }
  for (const v of rows) {
    const li = document.createElement("li");
    li.className = "admin-et-version-row";
    const date = document.createElement("span");
    date.className = "admin-et-version-date";
    date.textContent = fmtDate(v.saved_at);
    const note = document.createElement("span");
    note.className = "admin-et-version-note";
    note.textContent = v.note || "";
    const restore = document.createElement("button");
    restore.type = "button";
    restore.className = "btn-tertiary admin-et-version-restore";
    restore.textContent = t("admin.email_templates.editor.restore") || "Wiederherstellen";
    restore.dataset.versionId = v.id;
    restore.addEventListener("click", () => onRestoreClick(v.id));
    li.appendChild(date);
    li.appendChild(note);
    li.appendChild(restore);
    list.appendChild(li);
  }
}

async function loadActive() {
  applyTitle(currentKey, currentLang);
  applyLangToggle(currentLang);
  const resp = await fetch(`/api/admin/email-templates/${currentKey}/${currentLang}`);
  if (resp.status === 403) {
    showFeedback(t("admin.team.error.forbidden") || "Nur Admins.", true);
    return;
  }
  if (!resp.ok) {
    showFeedback(t("admin.email_templates.load_error") || "Fehler beim Laden.", true);
    return;
  }
  activeRow = (await resp.json()) as ActiveRow;
  applyToInputs(activeRow);
  void schedulePreview();
}

async function loadVariables() {
  const resp = await fetch(`/api/admin/email-templates/${currentKey}/variables`);
  if (!resp.ok) {
    variables = [];
    renderVariables();
    return;
  }
  variables = (await resp.json()) as VariableContract[];
  renderVariables();
}

async function loadVersions() {
  const resp = await fetch(`/api/admin/email-templates/${currentKey}/${currentLang}/versions`);
  if (!resp.ok) {
    renderVersions([]);
    return;
  }
  const rows = (await resp.json()) as VersionRow[];
  renderVersions(rows);
}

async function refreshPreview() {
  const subj = (document.getElementById("admin-et-subject") as HTMLInputElement | null)?.value || "";
  const body = (document.getElementById("admin-et-body") as HTMLTextAreaElement | null)?.value || "";
  const slotEl = document.getElementById("admin-et-slot") as HTMLSelectElement | null;
  const slot = currentKey === "deadline_digest" && slotEl ? slotEl.value : "";

  const resp = await fetch(
    `/api/admin/email-templates/${currentKey}/${currentLang}/preview`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ subject: subj, body, slot }),
    },
  );

  const subjEl = document.getElementById("admin-et-preview-subject");
  const frame = document.getElementById("admin-et-preview-frame") as HTMLIFrameElement | null;

  if (resp.status === 422) {
    const err = (await resp.json().catch(() => ({ error: "" }))) as { error?: string };
    if (subjEl) subjEl.textContent = "";
    if (frame) frame.srcdoc = "";
    showFeedback(
      (t("admin.email_templates.editor.parse_error") || "Template-Fehler:") + " " + (err.error || ""),
      true,
    );
    return;
  }
  if (!resp.ok) {
    showFeedback(t("admin.email_templates.editor.preview_error") || "Vorschau fehlgeschlagen.", true);
    return;
  }
  clearFeedback();
  const data = (await resp.json()) as { subject_rendered: string; html_rendered: string };
  if (subjEl) subjEl.textContent = data.subject_rendered;
  if (frame) frame.srcdoc = data.html_rendered;
}

function schedulePreview() {
  if (previewTimer !== null) {
    clearTimeout(previewTimer);
  }
  previewTimer = window.setTimeout(() => {
    previewTimer = null;
    void refreshPreview();
  }, PREVIEW_DEBOUNCE_MS);
}

async function onSaveClick() {
  if (!activeRow) return;
  const subj = (document.getElementById("admin-et-subject") as HTMLInputElement | null)?.value || "";
  const body = (document.getElementById("admin-et-body") as HTMLTextAreaElement | null)?.value || "";
  const note = (document.getElementById("admin-et-note") as HTMLInputElement | null)?.value || "";
  const resp = await fetch(`/api/admin/email-templates/${currentKey}/${currentLang}`, {
    method: "PUT",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ subject: subj, body, note }),
  });
  if (resp.status === 422) {
    const err = (await resp.json().catch(() => ({ error: "" }))) as { error?: string };
    showFeedback(
      (t("admin.email_templates.editor.parse_error") || "Template-Fehler:") + " " + (err.error || ""),
      true,
    );
    return;
  }
  if (!resp.ok) {
    const err = (await resp.json().catch(() => ({ error: resp.statusText }))) as { error?: string };
    showFeedback((t("admin.email_templates.editor.save_error") || "Speichern fehlgeschlagen.") + " " + (err.error || ""), true);
    return;
  }
  showFeedback(t("admin.email_templates.editor.save_ok") || "Gespeichert.", false);
  const noteEl = document.getElementById("admin-et-note") as HTMLInputElement | null;
  if (noteEl) noteEl.value = "";
  void loadActive();
  void loadVersions();
}

async function onResetClick() {
  if (!confirm(t("admin.email_templates.editor.reset_confirm") || "Wirklich auf den Standard zurücksetzen?")) {
    return;
  }
  const resp = await fetch(`/api/admin/email-templates/${currentKey}/${currentLang}/reset`, {
    method: "POST",
  });
  if (!resp.ok) {
    showFeedback(t("admin.email_templates.editor.reset_error") || "Zurücksetzen fehlgeschlagen.", true);
    return;
  }
  showFeedback(t("admin.email_templates.editor.reset_ok") || "Auf Standard zurückgesetzt.", false);
  void loadActive();
  void loadVersions();
}

async function onRestoreClick(versionID: string) {
  if (!confirm(t("admin.email_templates.editor.restore_confirm") || "Diese Version wiederherstellen?")) {
    return;
  }
  const resp = await fetch(
    `/api/admin/email-templates/${currentKey}/${currentLang}/restore/${versionID}`,
    { method: "POST" },
  );
  if (!resp.ok) {
    showFeedback(t("admin.email_templates.editor.restore_error") || "Wiederherstellen fehlgeschlagen.", true);
    return;
  }
  showFeedback(t("admin.email_templates.editor.restore_ok") || "Version wiederhergestellt.", false);
  void loadActive();
  void loadVersions();
}

function onLangButton(lang: "de" | "en") {
  if (lang === currentLang) return;
  if (dirty && !confirm(t("admin.email_templates.editor.dirty_warn") || "Ungespeicherte Änderungen verwerfen?")) {
    return;
  }
  currentLang = lang;
  setLangInURL(lang);
  applyTitle(currentKey, lang);
  applyLangToggle(lang);
  renderVariables();
  void loadActive();
  void loadVersions();
}

function wireInputs() {
  const onAnyChange = () => {
    setDirty(true);
    schedulePreview();
  };
  document.getElementById("admin-et-subject")?.addEventListener("input", onAnyChange);
  document.getElementById("admin-et-body")?.addEventListener("input", onAnyChange);
  document.getElementById("admin-et-slot")?.addEventListener("change", () => {
    void refreshPreview();
  });
  document.getElementById("admin-et-save")?.addEventListener("click", () => {
    void onSaveClick();
  });
  document.getElementById("admin-et-reset")?.addEventListener("click", () => {
    void onResetClick();
  });
  document.getElementById("admin-et-preview-refresh")?.addEventListener("click", () => {
    void refreshPreview();
  });
  document.querySelectorAll(".admin-et-lang-btn").forEach((el) => {
    const btn = el as HTMLButtonElement;
    btn.addEventListener("click", () => {
      const lang = btn.dataset.lang as "de" | "en";
      onLangButton(lang);
    });
  });
}

document.addEventListener("DOMContentLoaded", () => {
  initI18n();
  initSidebar();

  currentKey = readKeyFromPath();
  currentLang = readLangFromQuery();
  if (!currentKey) {
    showFeedback(t("admin.email_templates.editor.unknown_key") || "Unbekannter Template-Schlüssel.", true);
    return;
  }

  wireInputs();
  applyTitle(currentKey, currentLang);
  applyLangToggle(currentLang);

  void loadActive();
  void loadVariables();
  void loadVersions();

  onLangChange(() => {
    applyTitle(currentKey, currentLang);
    renderVariables();
  });
});
