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

interface ChecklistItem {
  labelDE: string;
  labelEN: string;
  noteDE?: string;
  noteEN?: string;
  rule?: string;
}

interface ChecklistGroup {
  titleDE: string;
  titleEN: string;
  items: ChecklistItem[];
}

interface Checklist {
  slug: string;
  titleDE: string;
  titleEN: string;
  descriptionDE: string;
  descriptionEN: string;
  regime: string;
  courtDE: string;
  courtEN: string;
  deadlineDE?: string;
  deadlineEN?: string;
  referenceDE?: string;
  referenceEN?: string;
  groups: ChecklistGroup[];
}

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

let template: Checklist | null = null;
let instance: Instance | null = null;

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

function itemKey(groupIdx: number, itemIdx: number): string {
  return `g${groupIdx}-i${itemIdx}`;
}

function instanceID(): string {
  // /checklisten/instances/{id}
  const parts = window.location.pathname.split("/").filter(Boolean);
  return parts[2] ?? "";
}

function totalItems(): number {
  if (!template) return 0;
  return template.groups.reduce((n, g) => n + g.items.length, 0);
}

function doneItems(): number {
  if (!instance) return 0;
  return Object.values(instance.state || {}).filter(Boolean).length;
}

async function loadInstance(): Promise<boolean> {
  const id = instanceID();
  if (!id) return false;
  const resp = await fetch(`/api/checklist-instances/${encodeURIComponent(id)}`);
  if (!resp.ok) return false;
  instance = await resp.json();
  if (instance && typeof instance.state !== "object") instance.state = {};
  return true;
}

async function loadTemplate(slug: string): Promise<boolean> {
  const resp = await fetch(`/api/checklists/${encodeURIComponent(slug)}`);
  if (!resp.ok) return false;
  template = await resp.json();
  return true;
}

async function bootstrap() {
  const loading = document.getElementById("instance-loading")!;
  const notfound = document.getElementById("instance-notfound")!;
  const body = document.getElementById("instance-body")!;

  const okInst = await loadInstance();
  if (!okInst || !instance) {
    loading.style.display = "none";
    notfound.style.display = "";
    document.title = t("checklisten.instance.notfound");
    return;
  }
  const okTpl = await loadTemplate(instance.template_slug);
  if (!okTpl || !template) {
    loading.style.display = "none";
    notfound.style.display = "";
    return;
  }
  loading.style.display = "none";
  body.style.display = "";

  // Back link goes to the template page.
  const back = document.getElementById("instance-back") as HTMLAnchorElement;
  back.href = `/checklists/${encodeURIComponent(instance.template_slug)}`;

  renderAll();
}

function renderAll() {
  if (!template || !instance) return;
  renderHeader();
  renderGroups();
  updateProgress();
}

function renderHeader() {
  if (!template || !instance) return;
  const isEN = getLang() === "en";
  const tplTitle = isEN ? template.titleEN : template.titleDE;
  const court = isEN ? template.courtEN : template.courtDE;
  const deadline = isEN ? template.deadlineEN : template.deadlineDE;
  const reference = isEN ? template.referenceEN : template.referenceDE;

  document.title = `${instance.name} — Paliad`;
  (document.getElementById("instance-name-display") as HTMLElement).textContent = instance.name;
  (document.getElementById("instance-name-edit") as HTMLInputElement).value = instance.name;
  (document.getElementById("instance-template-title") as HTMLElement).textContent = tplTitle;

  const courtLabel = isEN ? "Court / Authority" : "Gericht / Behörde";
  const deadlineLabel = isEN ? "Deadline" : "Deadline";
  const refLabel = isEN ? "Reference" : "Rechtsgrundlage";
  const regimeLabel = isEN ? "Regime" : "Bereich";

  const parts: string[] = [];
  parts.push(`<div class="checklist-meta-item"><dt>${regimeLabel}</dt><dd><span class="checklist-regime checklist-regime-${esc(template.regime)}">${esc(template.regime)}</span></dd></div>`);
  parts.push(`<div class="checklist-meta-item"><dt>${courtLabel}</dt><dd>${esc(court)}</dd></div>`);
  if (deadline) {
    parts.push(`<div class="checklist-meta-item"><dt>${deadlineLabel}</dt><dd>${esc(deadline)}</dd></div>`);
  }
  if (reference) {
    parts.push(`<div class="checklist-meta-item"><dt>${refLabel}</dt><dd>${esc(reference)}</dd></div>`);
  }
  if (instance.project_id) {
    const akteLabel = isEN ? "Project" : "Projekt";
    parts.push(`<div class="checklist-meta-item"><dt>${akteLabel}</dt><dd><a href="/projects/${esc(instance.project_id)}">${t("checklisten.instance.akte.open") || "Öffnen"}</a></dd></div>`);
  }
  document.getElementById("instance-meta")!.innerHTML = parts.join("");
}

function renderGroups() {
  if (!template || !instance) return;
  const isEN = getLang() === "en";
  const container = document.getElementById("checklist-groups")!;
  const state = instance.state || {};

  container.innerHTML = template.groups.map((g, gi) => {
    const groupTitle = isEN ? g.titleEN : g.titleDE;
    const items = g.items.map((item, ii) => {
      const key = itemKey(gi, ii);
      const checked = !!state[key];
      const label = isEN ? item.labelEN : item.labelDE;
      const note = isEN ? item.noteEN : item.noteDE;
      const rule = item.rule;

      const noteHTML = note ? `<p class="checklist-item-note">${esc(note)}</p>` : "";
      const ruleHTML = rule ? `<span class="checklist-item-rule">${esc(rule)}</span>` : "";

      return `<li class="checklist-item${checked ? " checked" : ""}" data-key="${key}">
        <label class="checklist-item-label">
          <input type="checkbox" class="checklist-checkbox" data-key="${key}"${checked ? " checked" : ""} />
          <span class="checklist-item-body">
            <span class="checklist-item-row">
              <span class="checklist-item-text">${esc(label)}</span>
              ${ruleHTML}
            </span>
            ${noteHTML}
          </span>
        </label>
      </li>`;
    }).join("");

    return `<section class="checklist-group">
      <h2 class="checklist-group-title">${esc(groupTitle)}</h2>
      <ol class="checklist-list">${items}</ol>
    </section>`;
  }).join("");

  container.querySelectorAll<HTMLInputElement>(".checklist-checkbox").forEach((cb) => {
    cb.addEventListener("change", () => {
      if (!instance) return;
      const key = cb.dataset.key!;
      instance.state[key] = cb.checked;
      const li = cb.closest(".checklist-item");
      if (li) li.classList.toggle("checked", cb.checked);
      updateProgress();
      void patchState({ [key]: cb.checked });
    });
  });
}

function updateProgress() {
  const total = totalItems();
  const done = doneItems();
  const pct = total === 0 ? 0 : Math.round((done / total) * 100);
  const fill = document.getElementById("progress-fill");
  if (fill) (fill as HTMLElement).style.width = `${pct}%`;
  const label = document.getElementById("progress-label");
  if (label) {
    const doneLabel = getLang() === "en" ? "done" : "erledigt";
    label.textContent = `${done} / ${total} ${doneLabel}`;
  }
}

async function patchState(patch: Record<string, boolean>) {
  if (!instance) return;
  try {
    const resp = await fetch(`/api/checklist-instances/${encodeURIComponent(instance.id)}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ state: patch }),
    });
    if (!resp.ok) {
      console.warn("patchState failed", resp.status);
      // Revert local state on server failure.
      for (const k of Object.keys(patch)) instance.state[k] = !patch[k];
      renderGroups();
      updateProgress();
    }
  } catch (e) {
    console.warn("patchState error", e);
  }
}

function initReset() {
  const btn = document.getElementById("btn-reset");
  if (!btn) return;
  btn.addEventListener("click", async () => {
    if (!instance) return;
    const ok = confirm(t("checklisten.reset.confirm"));
    if (!ok) return;
    try {
      const resp = await fetch(`/api/checklist-instances/${encodeURIComponent(instance.id)}/reset`, {
        method: "POST",
      });
      if (!resp.ok) {
        alert(t("checklisten.reset.error"));
        return;
      }
      const updated = await resp.json() as Instance;
      instance = updated;
      if (typeof instance.state !== "object" || instance.state === null) instance.state = {};
      renderGroups();
      updateProgress();
    } catch {
      alert(t("checklisten.reset.error"));
    }
  });
}

function initPrint() {
  const btn = document.getElementById("btn-print");
  if (!btn) return;
  btn.addEventListener("click", () => window.print());
}

function initRename() {
  const display = document.getElementById("instance-name-display") as HTMLElement;
  const editInput = document.getElementById("instance-name-edit") as HTMLInputElement;
  const editBtn = document.getElementById("instance-rename-btn") as HTMLButtonElement;
  const saveBtn = document.getElementById("instance-name-save") as HTMLButtonElement;
  if (!display || !editInput || !editBtn || !saveBtn) return;

  const enterEdit = () => {
    if (!instance) return;
    editInput.value = instance.name;
    display.style.display = "none";
    editBtn.style.display = "none";
    editInput.style.display = "";
    saveBtn.style.display = "";
    editInput.focus();
    editInput.select();
  };
  const exitEdit = () => {
    display.style.display = "";
    editBtn.style.display = "";
    editInput.style.display = "none";
    saveBtn.style.display = "none";
  };

  editBtn.addEventListener("click", enterEdit);
  saveBtn.addEventListener("click", async () => {
    if (!instance) return;
    const newName = editInput.value.trim();
    if (!newName || newName === instance.name) {
      exitEdit();
      return;
    }
    try {
      const resp = await fetch(`/api/checklist-instances/${encodeURIComponent(instance.id)}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ name: newName }),
      });
      if (!resp.ok) {
        alert(t("checklisten.instance.rename.error"));
        return;
      }
      instance = await resp.json();
      renderHeader();
      exitEdit();
    } catch {
      alert(t("checklisten.instance.rename.error"));
    }
  });
  editInput.addEventListener("keydown", (e) => {
    if (e.key === "Enter") { e.preventDefault(); saveBtn.click(); }
    if (e.key === "Escape") { e.preventDefault(); exitEdit(); }
  });
}

function initFeedback() {
  const modal = document.getElementById("feedback-modal")!;
  const form = document.getElementById("feedback-form")!;
  const msg = document.getElementById("feedback-msg")!;

  document.getElementById("btn-feedback")!.addEventListener("click", () => {
    msg.textContent = "";
    msg.className = "form-msg";
    modal.style.display = "flex";
  });

  document.getElementById("modal-close")!.addEventListener("click", () => { modal.style.display = "none"; });
  document.getElementById("modal-cancel")!.addEventListener("click", () => { modal.style.display = "none"; });
  modal.addEventListener("click", (e) => { if (e.target === e.currentTarget) modal.style.display = "none"; });

  form.addEventListener("submit", async (e) => {
    e.preventDefault();
    if (!template) return;
    const submitBtn = form.querySelector(".btn-submit") as HTMLButtonElement;
    const payload = {
      feedback_type: (document.getElementById("feedback-type") as HTMLSelectElement).value,
      checklist: template.slug,
      message: (document.getElementById("feedback-message") as HTMLTextAreaElement).value.trim(),
    };
    if (!payload.message) {
      msg.textContent = t("checklisten.feedback.error.required");
      msg.className = "form-msg form-msg-error";
      return;
    }
    submitBtn.disabled = true;
    try {
      const resp = await fetch("/api/checklists/feedback", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload),
      });
      if (!resp.ok) {
        msg.textContent = t("checklisten.feedback.error.generic");
        msg.className = "form-msg form-msg-error";
        return;
      }
      msg.textContent = t("checklisten.feedback.success");
      msg.className = "form-msg form-msg-success";
      (document.getElementById("feedback-message") as HTMLTextAreaElement).value = "";
      setTimeout(() => { modal.style.display = "none"; }, 1500);
    } catch {
      msg.textContent = t("checklisten.feedback.error.generic");
      msg.className = "form-msg form-msg-error";
    } finally {
      submitBtn.disabled = false;
    }
  });
}

document.addEventListener("DOMContentLoaded", () => {
  initI18n();
  initSidebar();
  initReset();
  initPrint();
  initRename();
  initFeedback();
  onLangChange(renderAll);
  void bootstrap();
});
