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

interface ChecklistSummary {
  slug: string;
  titleDE: string;
  titleEN: string;
  descriptionDE: string;
  descriptionEN: string;
  regime: string;
  courtDE: string;
  courtEN: string;
  itemCount: number;
  origin?: "static" | "authored";
  visibility?: string;
  owner_email?: string;
  owner_display_name?: string;
}

interface MyChecklist {
  id: string;
  slug: string;
  owner_id: string;
  title: string;
  description: string;
  regime: string;
  court: string;
  reference: string;
  deadline: string;
  lang: string;
  visibility: string;
  created_at: string;
  updated_at: string;
}

interface ChecklistInstance {
  id: string;
  template_slug: string;
  name: string;
  project_id?: string | null;
  state: Record<string, boolean>;
  created_by: string;
  created_at: string;
  updated_at: string;
  project_reference?: string | null;
  project_title?: string | null;
}

type TabId = "templates" | "mine" | "gallery" | "instances";

const VALID_TABS: TabId[] = ["templates", "mine", "gallery", "instances"];

let allChecklists: ChecklistSummary[] = [];
let activeRegime = "all";
let galleryRegime = "all";
let allInstances: ChecklistInstance[] = [];
let templatesBySlug: Record<string, ChecklistSummary> = {};
let instancesLoaded = false;
let myTemplates: MyChecklist[] = [];
let myTemplatesLoaded = false;
let galleryLoaded = false;
let me: { id: string; email: string } | null = null;
let activeTab: TabId = "templates";

function esc(s: string): string {
  const d = document.createElement("div");
  d.textContent = s;
  return d.innerHTML;
}

function escAttr(s: string): string {
  return s.replace(/&/g, "&amp;").replace(/"/g, "&quot;");
}

function parseTab(): TabId {
  const params = new URLSearchParams(window.location.search);
  const candidate = params.get("tab");
  if (candidate && (VALID_TABS as string[]).includes(candidate)) {
    return candidate as TabId;
  }
  return "templates";
}

async function loadTemplates() {
  const resp = await fetch("/api/checklists");
  if (!resp.ok) return;
  allChecklists = await resp.json();
  templatesBySlug = {};
  for (const tpl of allChecklists) templatesBySlug[tpl.slug] = tpl;
  renderTemplates();
}

function renderTemplates() {
  const grid = document.getElementById("checklist-grid")!;
  const isEN = getLang() === "en";

  const filtered = activeRegime === "all"
    ? allChecklists
    : allChecklists.filter((c) => c.regime === activeRegime);

  if (filtered.length === 0) {
    grid.innerHTML = `<p class="checklist-empty" data-i18n="checklisten.empty">${esc(t("checklisten.empty"))}</p>`;
    return;
  }

  grid.innerHTML = filtered.map((c) => {
    const title = isEN ? c.titleEN : c.titleDE;
    const desc = isEN ? c.descriptionEN : c.descriptionDE;
    const court = isEN ? c.courtEN : c.courtDE;
    const itemsLabel = isEN ? "items" : "Punkte";
    return `<a href="/checklists/${esc(c.slug)}" class="checklist-card">
      <div class="checklist-card-top">
        <span class="checklist-regime checklist-regime-${esc(c.regime)}">${esc(c.regime)}</span>
        <span class="checklist-card-count">${c.itemCount} ${itemsLabel}</span>
      </div>
      <h2 class="checklist-card-title">${esc(title)}</h2>
      <p class="checklist-card-desc">${esc(desc)}</p>
      <p class="checklist-card-court">${esc(court)}</p>
    </a>`;
  }).join("");
}

function initFilters() {
  const container = document.getElementById("checklist-filters")!;
  container.addEventListener("click", (e) => {
    const btn = (e.target as HTMLElement).closest<HTMLButtonElement>(".filter-pill");
    if (!btn) return;
    container.querySelectorAll(".filter-pill").forEach((p) => p.classList.remove("active"));
    btn.classList.add("active");
    activeRegime = btn.dataset.regime ?? "all";
    renderTemplates();
  });
}

async function loadInstances() {
  if (instancesLoaded) return;
  instancesLoaded = true;
  // Templates may not be loaded yet if the user lands directly on
  // ?tab=instances — fetch in parallel so the join below has names.
  const [instResp, tplResp] = await Promise.all([
    fetch("/api/checklist-instances"),
    allChecklists.length === 0 ? fetch("/api/checklists") : Promise.resolve(null),
  ]);
  if (instResp.ok) {
    allInstances = (await instResp.json()) ?? [];
  } else {
    allInstances = [];
  }
  if (tplResp && tplResp.ok) {
    allChecklists = (await tplResp.json()) ?? [];
    templatesBySlug = {};
    for (const tpl of allChecklists) templatesBySlug[tpl.slug] = tpl;
  }
  renderInstances();
}

function renderInstances() {
  const loading = document.getElementById("checklists-instances-loading")!;
  const empty = document.getElementById("checklists-instances-empty")!;
  const wrap = document.getElementById("checklists-instances-tablewrap")!;
  const body = document.getElementById("checklists-instances-body")!;

  loading.style.display = "none";

  if (allInstances.length === 0) {
    empty.style.display = "";
    wrap.style.display = "none";
    return;
  }
  empty.style.display = "none";
  wrap.style.display = "";

  const isEN = getLang() === "en";
  const fmtDate = (iso: string) => {
    const d = new Date(iso);
    if (isNaN(d.getTime())) return "";
    return d.toLocaleDateString(isEN ? "en-GB" : "de-DE", {
      year: "numeric", month: "2-digit", day: "2-digit",
    });
  };

  body.innerHTML = allInstances.map((inst) => {
    const tpl = templatesBySlug[inst.template_slug];
    const tplName = tpl
      ? (isEN ? tpl.titleEN : tpl.titleDE)
      : inst.template_slug;
    const total = tpl ? tpl.itemCount : 0;
    const done = Object.values(inst.state || {}).filter(Boolean).length;
    const pct = total === 0 ? 0 : Math.round((done / total) * 100);

    let projectCell: string;
    if (inst.project_id && inst.project_title) {
      const ref = inst.project_reference ? esc(inst.project_reference) : "";
      const title = esc(inst.project_title);
      const refPart = ref ? `<span class="entity-ref">${ref}</span> ` : "";
      projectCell = `<a href="/projects/${esc(inst.project_id)}" class="checklist-instance-project">${refPart}${title}</a>`;
    } else {
      projectCell = `<span class="form-hint" data-i18n="checklisten.instances.all.personal">Pers&ouml;nlich</span>`;
    }

    return `<tr class="checklist-instance-row" data-id="${esc(inst.id)}">
      <td>${esc(tplName)}</td>
      <td><a href="/checklists/instances/${esc(inst.id)}" class="checklist-instance-name">${esc(inst.name)}</a></td>
      <td>${projectCell}</td>
      <td>
        <div class="checklist-progress-inline">
          <div class="checklist-progress-bar">
            <div class="checklist-progress-fill" style="width:${pct}%"></div>
          </div>
          <span class="checklist-progress-label">${done} / ${total}</span>
        </div>
      </td>
      <td>${esc(fmtDate(inst.created_at))}</td>
    </tr>`;
  }).join("");

  body.querySelectorAll<HTMLTableRowElement>(".checklist-instance-row").forEach((row) => {
    const id = row.dataset.id!;
    row.addEventListener("click", (e) => {
      // Let inner links (project, instance name) handle their own navigation.
      if ((e.target as HTMLElement).closest("a")) return;
      window.location.href = `/checklists/instances/${id}`;
    });
  });
}

function showTab(tab: TabId, opts: { pushHistory?: boolean } = {}) {
  activeTab = tab;
  document.querySelectorAll<HTMLElement>("#checklists-tabs .entity-tab").forEach((el) => {
    el.classList.toggle("active", el.dataset.tab === tab);
  });
  document.querySelectorAll<HTMLElement>(".entity-tab-panel").forEach((el) => {
    el.style.display = el.id === `tab-${tab}` ? "" : "none";
  });
  if (opts.pushHistory ?? true) {
    let newURL = "/checklists";
    if (tab === "instances") newURL = "/checklists?tab=instances";
    if (tab === "mine") newURL = "/checklists?tab=mine";
    if (tab === "gallery") newURL = "/checklists?tab=gallery";
    if (window.location.pathname + window.location.search !== newURL) {
      window.history.replaceState({}, "", newURL);
    }
  }
  if (tab === "instances") {
    void loadInstances();
  }
  if (tab === "mine") {
    void loadMyTemplates();
  }
  if (tab === "gallery") {
    void loadGallery();
  }
}

async function loadGallery(force = false) {
  if (galleryLoaded && !force) return;
  galleryLoaded = true;
  // /api/checklists already returns the merged catalog; the gallery
  // filter just narrows to non-static + non-owned + non-private.
  if (allChecklists.length === 0) {
    await loadTemplates();
  }
  renderGallery();
}

function renderGallery() {
  const loading = document.getElementById("checklists-gallery-loading")!;
  const empty = document.getElementById("checklists-gallery-empty")!;
  const grid = document.getElementById("checklists-gallery-grid") as HTMLElement;

  loading.style.display = "none";

  const visible = allChecklists.filter((c) => {
    if (c.origin !== "authored") return false;
    if (me && c.owner_email && me.email.toLowerCase() === c.owner_email.toLowerCase()) return false;
    if (galleryRegime !== "all" && c.regime !== galleryRegime) return false;
    return true;
  });

  if (visible.length === 0) {
    empty.style.display = "";
    grid.style.display = "none";
    return;
  }
  empty.style.display = "none";
  grid.style.display = "";

  const isEN = getLang() === "en";
  grid.innerHTML = visible.map((c) => {
    const title = isEN ? c.titleEN : c.titleDE;
    const desc = isEN ? c.descriptionEN : c.descriptionDE;
    const court = isEN ? c.courtEN : c.courtDE;
    const itemsLabel = isEN ? "items" : "Punkte";
    const visKey = `checklisten.mine.visibility.${c.visibility || ""}`;
    const visLabel = c.visibility ? esc(t(visKey as never) || c.visibility) : "";
    const authorLine = c.owner_display_name
      ? `<p class="checklist-card-author">${esc(t("checklisten.detail.authored.by").replace("{author}", c.owner_display_name))}</p>`
      : "";
    return `<a href="/checklists/${esc(c.slug)}" class="checklist-card">
      <div class="checklist-card-top">
        <span class="checklist-regime checklist-regime-${esc(c.regime)}">${esc(c.regime)}</span>
        <span class="checklist-card-count">${c.itemCount} ${itemsLabel}</span>
      </div>
      <h2 class="checklist-card-title">${esc(title)}</h2>
      <p class="checklist-card-desc">${esc(desc)}</p>
      <p class="checklist-card-court">${esc(court)}</p>
      ${authorLine}
      ${visLabel ? `<span class="visibility-chip visibility-chip-${esc(c.visibility || "")}">${visLabel}</span>` : ""}
    </a>`;
  }).join("");
}

function initGalleryFilters() {
  const container = document.getElementById("checklist-gallery-filters");
  if (!container) return;
  container.addEventListener("click", (e) => {
    const btn = (e.target as HTMLElement).closest<HTMLButtonElement>(".filter-pill");
    if (!btn) return;
    container.querySelectorAll(".filter-pill").forEach((p) => p.classList.remove("active"));
    btn.classList.add("active");
    galleryRegime = btn.dataset.regime ?? "all";
    renderGallery();
  });
}

async function loadMe() {
  try {
    const resp = await fetch("/api/me");
    if (resp.ok) me = await resp.json();
  } catch { /* leave me=null */ }
}

async function loadMyTemplates(force = false) {
  if (myTemplatesLoaded && !force) return;
  myTemplatesLoaded = true;
  const resp = await fetch("/api/checklists/templates/mine");
  if (!resp.ok) {
    myTemplates = [];
  } else {
    myTemplates = (await resp.json()) ?? [];
  }
  renderMyTemplates();
}

function renderMyTemplates() {
  const loading = document.getElementById("checklists-mine-loading")!;
  const empty = document.getElementById("checklists-mine-empty")!;
  const grid = document.getElementById("checklists-mine-grid") as HTMLElement;

  loading.style.display = "none";

  if (myTemplates.length === 0) {
    empty.style.display = "";
    grid.style.display = "none";
    return;
  }
  empty.style.display = "none";
  grid.style.display = "";

  grid.innerHTML = myTemplates.map((tpl) => {
    const visKey = `checklisten.mine.visibility.${tpl.visibility}`;
    const visLabel = esc(t(visKey as never) || tpl.visibility);
    const titleSafe = esc(tpl.title);
    return `<article class="checklist-card checklist-card-mine" data-slug="${esc(tpl.slug)}" data-title="${escAttr(tpl.title)}">
      <div class="checklist-card-top">
        <span class="checklist-regime checklist-regime-${esc(tpl.regime)}">${esc(tpl.regime)}</span>
        <span class="checklist-card-count visibility-chip visibility-chip-${esc(tpl.visibility)}">${visLabel}</span>
      </div>
      <h2 class="checklist-card-title">
        <a href="/checklists/${esc(tpl.slug)}">${titleSafe}</a>
      </h2>
      <p class="checklist-card-desc">${esc(tpl.description || "")}</p>
      <p class="checklist-card-court">${esc(tpl.court || "")}</p>
      <div class="checklist-card-actions">
        <a class="btn btn-small" href="/checklists/templates/${esc(tpl.slug)}/edit" data-i18n="checklisten.mine.edit">Bearbeiten</a>
        <button class="btn btn-small btn-danger" data-action="delete" data-slug="${esc(tpl.slug)}" data-title="${escAttr(tpl.title)}" data-i18n="checklisten.mine.delete">L&ouml;schen</button>
      </div>
    </article>`;
  }).join("");

  grid.querySelectorAll<HTMLButtonElement>("button[data-action=delete]").forEach((btn) => {
    btn.addEventListener("click", async (e) => {
      e.preventDefault();
      const slug = btn.dataset.slug!;
      const title = btn.dataset.title || slug;
      const msg = t("checklisten.mine.delete.confirm").replace("{title}", title);
      if (!window.confirm(msg)) return;
      const resp = await fetch(`/api/checklists/templates/${encodeURIComponent(slug)}`, { method: "DELETE" });
      if (!resp.ok) {
        window.alert(t("checklisten.mine.delete.error"));
        return;
      }
      await loadMyTemplates(true);
    });
  });
}

function initTabs() {
  document.querySelectorAll<HTMLAnchorElement>("#checklists-tabs .entity-tab").forEach((tab) => {
    tab.addEventListener("click", (e) => {
      // Let middle-click / cmd-click open in new tab via the real href.
      if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
      e.preventDefault();
      const id = tab.dataset.tab as TabId;
      if (VALID_TABS.includes(id)) showTab(id);
    });
  });
}

document.addEventListener("DOMContentLoaded", () => {
  initI18n();
  initSidebar();
  initFilters();
  initGalleryFilters();
  initTabs();
  onLangChange(() => {
    renderTemplates();
    if (instancesLoaded) renderInstances();
    if (myTemplatesLoaded) renderMyTemplates();
    if (galleryLoaded) renderGallery();
  });
  void loadMe();
  void loadTemplates();
  showTab(parseTab(), { pushHistory: false });
});
