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

// t-paliad-243 — client for /submissions/new. Fetches the
// cross-proceeding submission catalog, groups it by proceeding, filters
// by text + chip, and offers two start paths per row: with project
// (modal picker) or without (project-less draft → /submissions/draft/{id}).

interface CatalogEntry {
  submission_code: string;
  name: string;
  name_en: string;
  event_type?: string;
  primary_party?: string;
  legal_source?: string;
  has_template: boolean;
  proceeding_code: string;
  proceeding_name: string;
  proceeding_name_en: string;
}

interface CatalogResponse {
  entries: CatalogEntry[];
}

interface ProjectRow {
  id: string;
  title: string;
  reference?: string | null;
}

interface State {
  entries: CatalogEntry[];
  activeProceeding: string | null; // null = all
  searchTerm: string;
  pickerForCode: string | null;
}

const state: State = {
  entries: [],
  activeProceeding: null,
  searchTerm: "",
  pickerForCode: null,
};

function isEN(): boolean {
  return getLang() === "en";
}

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

function partyLabel(role: string | undefined): string {
  switch ((role ?? "").toLowerCase()) {
    case "claimant": return isEN() ? "Claimant" : "Klägerin";
    case "defendant": return isEN() ? "Defendant" : "Beklagte";
    case "both": return isEN() ? "Both" : "Beide";
    case "court": return isEN() ? "Court" : "Gericht";
    default: return "";
  }
}

async function loadCatalog(): Promise<void> {
  const loading = document.getElementById("submissions-new-loading")!;
  const error = document.getElementById("submissions-new-error")!;
  const wrap = document.getElementById("submissions-new-tablewrap")!;

  try {
    const resp = await fetch("/api/submissions/catalog");
    if (!resp.ok) {
      loading.style.display = "none";
      error.style.display = "";
      return;
    }
    const data = (await resp.json()) as CatalogResponse;
    state.entries = data.entries ?? [];
  } catch {
    loading.style.display = "none";
    error.style.display = "";
    return;
  }

  loading.style.display = "none";
  wrap.style.display = "";
  renderChips();
  renderTable();
}

function renderChips(): void {
  const host = document.getElementById("submissions-new-proceeding-chips");
  if (!host) return;
  const seen = new Map<string, string>();
  for (const e of state.entries) {
    if (!seen.has(e.proceeding_code)) {
      seen.set(e.proceeding_code, isEN() && e.proceeding_name_en ? e.proceeding_name_en : e.proceeding_name);
    }
  }
  const chips: string[] = [];
  const allLabel = isEN() ? "All" : "Alle";
  const allActive = state.activeProceeding === null;
  chips.push(`<button type="button" class="submissions-new-chip${allActive ? " submissions-new-chip--active" : ""}" data-code="">${esc(allLabel)}</button>`);
  for (const [code, name] of seen) {
    const active = state.activeProceeding === code;
    chips.push(`<button type="button" class="submissions-new-chip${active ? " submissions-new-chip--active" : ""}" data-code="${esc(code)}">${esc(name)} <span class="submissions-new-chip-code">${esc(code)}</span></button>`);
  }
  host.innerHTML = chips.join("");
  host.querySelectorAll<HTMLButtonElement>(".submissions-new-chip").forEach((btn) => {
    btn.addEventListener("click", () => {
      const code = btn.dataset.code ?? "";
      state.activeProceeding = code === "" ? null : code;
      renderChips();
      renderTable();
    });
  });
}

function filtered(): CatalogEntry[] {
  const term = state.searchTerm.trim().toLowerCase();
  return state.entries.filter((e) => {
    if (state.activeProceeding !== null && e.proceeding_code !== state.activeProceeding) {
      return false;
    }
    if (term === "") return true;
    const name = isEN() && e.name_en ? e.name_en : e.name;
    const hay = [
      name,
      e.submission_code,
      e.legal_source ?? "",
      e.proceeding_code,
      e.proceeding_name,
      e.proceeding_name_en,
    ].join(" ").toLowerCase();
    return hay.includes(term);
  });
}

function renderTable(): void {
  const body = document.getElementById("submissions-new-body");
  const empty = document.getElementById("submissions-new-empty");
  const wrap = document.getElementById("submissions-new-tablewrap");
  if (!body || !empty || !wrap) return;

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

  // Group by proceeding.
  const groups = new Map<string, { name: string; entries: CatalogEntry[] }>();
  for (const e of rows) {
    const gname = isEN() && e.proceeding_name_en ? e.proceeding_name_en : e.proceeding_name;
    const bucket = groups.get(e.proceeding_code);
    if (bucket) {
      bucket.entries.push(e);
    } else {
      groups.set(e.proceeding_code, { name: gname, entries: [e] });
    }
  }

  const colspan = 4;
  const html: string[] = [];
  for (const [code, group] of groups) {
    html.push(`<tr class="entity-table-group-header"><th colspan="${colspan}" scope="colgroup"><span class="entity-table-group-header__name">${esc(group.name)}</span> <span class="entity-table-group-header__code">${esc(code)}</span></th></tr>`);
    for (const entry of group.entries) {
      html.push(renderRow(entry));
    }
  }
  body.innerHTML = html.join("");

  body.querySelectorAll<HTMLButtonElement>(".submissions-new-start-no-project").forEach((btn) => {
    btn.addEventListener("click", () => {
      const code = btn.dataset.code;
      if (code) void startDraft(code, null);
    });
  });
  body.querySelectorAll<HTMLButtonElement>(".submissions-new-start-with-project").forEach((btn) => {
    btn.addEventListener("click", () => {
      const code = btn.dataset.code;
      if (code) openProjectPicker(code);
    });
  });
}

function renderRow(entry: CatalogEntry): string {
  const name = isEN() && entry.name_en ? entry.name_en : entry.name;
  const source = entry.legal_source ?? "";
  const templateBadge = entry.has_template
    ? ""
    : ` <span class="submission-template-badge" title="${esc(isEN() ? "Uses the universal style template" : "Verwendet die universelle Stilvorlage")}">${esc(isEN() ? "universal" : "universell")}</span>`;
  const withProject = isEN() ? "Mit Projekt…" : "Mit Projekt…";
  const noProject = isEN() ? "Ohne Projekt" : "Ohne Projekt";

  return `<tr class="submission-row">
    <td>
      <span class="submission-name">${esc(name)}</span>
      <span class="submission-code">${esc(entry.submission_code)}</span>${templateBadge}
    </td>
    <td>${esc(partyLabel(entry.primary_party))}</td>
    <td>${esc(source)}</td>
    <td class="submission-action-cell">
      <button type="button" class="btn-secondary btn-small submissions-new-start-with-project" data-code="${esc(entry.submission_code)}">${esc(withProject)}</button>
      <button type="button" class="btn-primary btn-cta-lime btn-small submissions-new-start-no-project" data-code="${esc(entry.submission_code)}">${esc(noProject)}</button>
    </td>
  </tr>`;
}

async function startDraft(submissionCode: string, projectID: string | null): Promise<void> {
  try {
    const resp = await fetch("/api/submission-drafts", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ submission_code: submissionCode, project_id: projectID }),
    });
    if (!resp.ok) {
      let detail = "";
      try {
        const data = (await resp.json()) as { error?: string };
        detail = data.error ?? "";
      } catch { /* ignore */ }
      alert((isEN() ? "Failed to create draft." : "Entwurf konnte nicht angelegt werden.") + (detail ? `\n\n${detail}` : ""));
      return;
    }
    const view = await resp.json() as { draft: { id: string; project_id: string | null; submission_code: string } };
    const id = view.draft.id;
    const pid = view.draft.project_id;
    const code = view.draft.submission_code;
    if (pid) {
      window.location.href = `/projects/${pid}/submissions/${encodeURIComponent(code)}/draft/${id}`;
    } else {
      window.location.href = `/submissions/draft/${id}`;
    }
  } catch (err) {
    console.error("submissions-new createDraft:", err);
    alert(isEN() ? "Failed to create draft." : "Entwurf konnte nicht angelegt werden.");
  }
}

// ─────────────────────────────────────────────────────────────────────
// Project picker modal
// ─────────────────────────────────────────────────────────────────────

let pickerProjects: ProjectRow[] = [];
let pickerLoaded = false;

function openProjectPicker(submissionCode: string): void {
  state.pickerForCode = submissionCode;
  const modal = document.getElementById("submissions-new-project-modal");
  if (modal) modal.style.display = "";
  if (!pickerLoaded) {
    void loadPickerProjects();
  } else {
    renderPickerList();
  }
  const searchInput = document.getElementById("submissions-new-project-search") as HTMLInputElement | null;
  if (searchInput) {
    searchInput.value = "";
    setTimeout(() => searchInput.focus(), 50);
  }
}

function closeProjectPicker(): void {
  state.pickerForCode = null;
  const modal = document.getElementById("submissions-new-project-modal");
  if (modal) modal.style.display = "none";
}

async function loadPickerProjects(): Promise<void> {
  const loadingEl = document.getElementById("submissions-new-project-loading");
  if (loadingEl) loadingEl.style.display = "";
  try {
    const resp = await fetch("/api/projects?status=active");
    if (!resp.ok) throw new Error(`projects list ${resp.status}`);
    const rows = (await resp.json()) as ProjectRow[];
    pickerProjects = rows ?? [];
    pickerLoaded = true;
  } catch (err) {
    console.error("submissions-new loadPickerProjects:", err);
    pickerProjects = [];
  } finally {
    if (loadingEl) loadingEl.style.display = "none";
  }
  renderPickerList();
}

function renderPickerList(): void {
  const list = document.getElementById("submissions-new-project-list");
  const empty = document.getElementById("submissions-new-project-empty");
  if (!list || !empty) return;

  const searchInput = document.getElementById("submissions-new-project-search") as HTMLInputElement | null;
  const term = (searchInput?.value ?? "").trim().toLowerCase();

  const matches = pickerProjects.filter((p) => {
    if (term === "") return true;
    const hay = [p.title, p.reference ?? ""].join(" ").toLowerCase();
    return hay.includes(term);
  }).slice(0, 50);

  if (matches.length === 0) {
    list.innerHTML = "";
    empty.style.display = "";
    return;
  }
  empty.style.display = "none";

  list.innerHTML = matches.map((p) => {
    const ref = p.reference ? `<span class="entity-ref">${esc(p.reference)}</span> ` : "";
    return `<li class="submissions-new-project-item" data-id="${esc(p.id)}">${ref}<span class="submissions-new-project-title">${esc(p.title)}</span></li>`;
  }).join("");

  list.querySelectorAll<HTMLLIElement>(".submissions-new-project-item").forEach((li) => {
    li.addEventListener("click", () => {
      const pid = li.dataset.id;
      const code = state.pickerForCode;
      if (pid && code) {
        closeProjectPicker();
        void startDraft(code, pid);
      }
    });
  });
}

// ─────────────────────────────────────────────────────────────────────
// Boot
// ─────────────────────────────────────────────────────────────────────

function wireToolbar(): void {
  const search = document.getElementById("submissions-new-search") as HTMLInputElement | null;
  if (search) {
    search.addEventListener("input", () => {
      state.searchTerm = search.value;
      renderTable();
    });
  }

  const closeBtn = document.getElementById("submissions-new-project-modal-close");
  if (closeBtn) closeBtn.addEventListener("click", () => closeProjectPicker());

  const modal = document.getElementById("submissions-new-project-modal");
  if (modal) {
    modal.addEventListener("click", (e) => {
      if (e.target === modal) closeProjectPicker();
    });
  }

  const pickerSearch = document.getElementById("submissions-new-project-search") as HTMLInputElement | null;
  if (pickerSearch) {
    pickerSearch.addEventListener("input", () => renderPickerList());
  }

  document.addEventListener("keydown", (e) => {
    if (e.key === "Escape" && state.pickerForCode) closeProjectPicker();
  });
}

document.addEventListener("DOMContentLoaded", () => {
  initI18n();
  initSidebar();
  wireToolbar();
  void loadCatalog();
});
