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

interface Court {
  id: string;
  nameDE: string;
  nameEN: string;
  type: string;
  group: string;
  country: string;
  city: string;
  address?: string;
  phone?: string;
  fax?: string;
  email?: string;
  website?: string;
  languages?: string[];
  filing?: string;
  notesDE?: string;
  notesEN?: string;
  hlContact?: string;
}

interface CourtType {
  key: string;
  labelDE: string;
  labelEN: string;
  group: string;
}

interface ApiResponse {
  courts: Court[];
  types: CourtType[];
}

const COUNTRY_NAMES_DE: Record<string, string> = {
  DE: "Deutschland",
  FR: "Frankreich",
  NL: "Niederlande",
  IT: "Italien",
  LU: "Luxemburg",
  BE: "Belgien",
  AT: "\u00d6sterreich",
  PT: "Portugal",
  FI: "Finnland",
  SE: "Schweden",
  DK: "D\u00e4nemark",
  EE: "Estland",
  LV: "Lettland",
  LT: "Litauen",
  SI: "Slowenien",
  GB: "Vereinigtes K\u00f6nigreich",
};

const COUNTRY_NAMES_EN: Record<string, string> = {
  DE: "Germany",
  FR: "France",
  NL: "Netherlands",
  IT: "Italy",
  LU: "Luxembourg",
  BE: "Belgium",
  AT: "Austria",
  PT: "Portugal",
  FI: "Finland",
  SE: "Sweden",
  DK: "Denmark",
  EE: "Estonia",
  LV: "Latvia",
  LT: "Lithuania",
  SI: "Slovenia",
  GB: "United Kingdom",
};

let allCourts: Court[] = [];
let typeMap: Record<string, CourtType> = {};
let expanded: Set<string> = new Set();
let activeGroup = "all";
let activeCountry = "all";
let searchQuery = "";

const ICON_MAIL = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>';
const ICON_PHONE = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg>';
const ICON_LINK = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>';
const ICON_PIN = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>';

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

function name(court: Court): string {
  return getLang() === "en" ? court.nameEN : court.nameDE;
}

function notes(court: Court): string {
  return getLang() === "en" ? (court.notesEN ?? "") : (court.notesDE ?? "");
}

function typeLabel(key: string): string {
  const ct = typeMap[key];
  if (!ct) return key;
  return getLang() === "en" ? ct.labelEN : ct.labelDE;
}

function countryName(code: string): string {
  const map = getLang() === "en" ? COUNTRY_NAMES_EN : COUNTRY_NAMES_DE;
  return map[code] ?? code;
}

async function loadCourts() {
  const resp = await fetch("/api/courts");
  if (!resp.ok) return;
  const data: ApiResponse = await resp.json();
  allCourts = data.courts;
  typeMap = {};
  for (const ct of data.types) typeMap[ct.key] = ct;
  buildCountryFilters();
  render();
}

function buildCountryFilters() {
  const container = document.getElementById("gerichte-country-filters")!;
  const countries = Array.from(new Set(allCourts.map((c) => c.country))).sort();
  const allBtn = '<button class="filter-pill active" data-country="all" type="button">' + t("gerichte.filter.all") + "</button>";
  const pills = countries
    .map((c) => `<button class="filter-pill" data-country="${c}" type="button">${esc(countryName(c))}</button>`)
    .join("");
  container.innerHTML = allBtn + pills;
}

function matches(court: Court): boolean {
  if (activeGroup !== "all" && court.group !== activeGroup) return false;
  if (activeCountry !== "all" && court.country !== activeCountry) return false;
  if (searchQuery) {
    const q = searchQuery.toLowerCase();
    const hay = [
      court.nameDE,
      court.nameEN,
      court.city,
      court.country,
      countryName(court.country),
      typeLabel(court.type),
      court.address ?? "",
    ]
      .join(" ")
      .toLowerCase();
    if (!hay.includes(q)) return false;
  }
  return true;
}

function render() {
  const list = document.getElementById("gerichte-list")!;
  const empty = document.getElementById("gerichte-empty")!;
  const count = document.getElementById("gerichte-count")!;
  const filtered = allCourts.filter(matches);

  count.textContent = `${filtered.length} / ${allCourts.length}`;

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

  list.innerHTML = filtered.map(renderCard).join("");

  list.querySelectorAll<HTMLElement>(".gericht-summary").forEach((el) => {
    el.addEventListener("click", () => {
      const id = el.dataset.id!;
      if (expanded.has(id)) expanded.delete(id);
      else expanded.add(id);
      render();
    });
  });

  list.querySelectorAll<HTMLButtonElement>(".gericht-feedback-btn").forEach((btn) => {
    btn.addEventListener("click", (e) => {
      e.stopPropagation();
      openFeedbackModal(btn.dataset.id!, btn.dataset.label!);
    });
  });
}

function renderCard(court: Court): string {
  const isOpen = expanded.has(court.id);
  const hasDetails =
    !!(court.address || court.phone || court.fax || court.email || court.website || court.filing || notes(court) || court.hlContact);

  return `
  <article class="gericht-card${isOpen ? " open" : ""}" data-id="${esc(court.id)}">
    <header class="gericht-summary" data-id="${esc(court.id)}">
      <div class="gericht-title">
        <div class="gericht-name">${esc(name(court))}</div>
        <div class="gericht-meta">
          <span class="gericht-type-badge">${esc(typeLabel(court.type))}</span>
          <span class="gericht-city">${ICON_PIN}<span>${esc(court.city)}, ${esc(countryName(court.country))}</span></span>
          ${court.languages && court.languages.length ? `<span class="gericht-langs">${court.languages.map((l) => esc(l)).join(" / ")}</span>` : ""}
        </div>
      </div>
      <div class="gericht-actions">
        <button class="gericht-feedback-btn" type="button" title="${esc(t("gerichte.feedback.btn"))}" data-id="${esc(court.id)}" data-label="${esc(name(court))}">&#9998;</button>
        <button class="gericht-toggle" type="button" aria-label="toggle">${isOpen ? "\u2212" : "+"}</button>
      </div>
    </header>
    ${hasDetails ? renderDetails(court) : ""}
  </article>`;
}

function renderDetails(court: Court): string {
  const parts: string[] = [];

  if (court.address) {
    parts.push(`
      <div class="gericht-field">
        <div class="gericht-field-label">${t("gerichte.field.address")}</div>
        <div class="gericht-field-value">${esc(court.address)}</div>
      </div>`);
  }

  const contactBits: string[] = [];
  if (court.phone) contactBits.push(`<span class="gericht-contact">${ICON_PHONE}<a href="tel:${esc(court.phone.replace(/[^+\d]/g, ""))}">${esc(court.phone)}</a></span>`);
  if (court.fax) contactBits.push(`<span class="gericht-contact">${t("gerichte.field.fax")}: ${esc(court.fax)}</span>`);
  if (court.email) contactBits.push(`<span class="gericht-contact">${ICON_MAIL}<a href="mailto:${esc(court.email)}">${esc(court.email)}</a></span>`);
  if (court.website) contactBits.push(`<span class="gericht-contact">${ICON_LINK}<a href="${esc(court.website)}" target="_blank" rel="noopener noreferrer">${esc(court.website.replace(/^https?:\/\//, ""))}</a></span>`);
  if (contactBits.length) {
    parts.push(`
      <div class="gericht-field">
        <div class="gericht-field-label">${t("gerichte.field.contact")}</div>
        <div class="gericht-field-value gericht-contacts">${contactBits.join("")}</div>
      </div>`);
  }

  if (court.filing) {
    parts.push(`
      <div class="gericht-field">
        <div class="gericht-field-label">${t("gerichte.field.filing")}</div>
        <div class="gericht-field-value">${esc(court.filing)}</div>
      </div>`);
  }

  const note = notes(court);
  if (note) {
    parts.push(`
      <div class="gericht-field">
        <div class="gericht-field-label">${t("gerichte.field.notes")}</div>
        <div class="gericht-field-value">${esc(note)}</div>
      </div>`);
  }

  if (court.hlContact) {
    parts.push(`
      <div class="gericht-field">
        <div class="gericht-field-label">${t("gerichte.field.hlContact")}</div>
        <div class="gericht-field-value">${esc(court.hlContact)}</div>
      </div>`);
  }

  return `<div class="gericht-details">${parts.join("")}</div>`;
}

// --- Filters ---
function initFilters() {
  const groupContainer = document.getElementById("gerichte-group-filters")!;
  groupContainer.addEventListener("click", (e) => {
    const btn = (e.target as HTMLElement).closest<HTMLButtonElement>(".filter-pill");
    if (!btn) return;
    groupContainer.querySelectorAll(".filter-pill").forEach((p) => p.classList.remove("active"));
    btn.classList.add("active");
    activeGroup = btn.dataset.group ?? "all";
    render();
  });

  const countryContainer = document.getElementById("gerichte-country-filters")!;
  countryContainer.addEventListener("click", (e) => {
    const btn = (e.target as HTMLElement).closest<HTMLButtonElement>(".filter-pill");
    if (!btn) return;
    countryContainer.querySelectorAll(".filter-pill").forEach((p) => p.classList.remove("active"));
    btn.classList.add("active");
    activeCountry = btn.dataset.country ?? "all";
    render();
  });
}

// --- Search ---
function initSearch() {
  const input = document.getElementById("gerichte-search") as HTMLInputElement;
  input.addEventListener("input", () => {
    searchQuery = input.value;
    render();
  });
  // Honor `?q=` from the global search-palette deep links. render() runs
  // after loadCourts() resolves and reads the module-level searchQuery.
  const q = new URLSearchParams(location.search).get("q");
  if (q) {
    input.value = q;
    searchQuery = q;
  }
}

// --- Feedback modal ---
function openFeedbackModal(courtId: string, label: string) {
  const modal = document.getElementById("feedback-modal")!;
  (document.getElementById("feedback-court-id") as HTMLInputElement).value = courtId;
  (document.getElementById("feedback-court-label") as HTMLInputElement).value = label;
  (document.getElementById("feedback-message") as HTMLTextAreaElement).value = "";
  (document.getElementById("feedback-type") as HTMLSelectElement).value = "address";
  const msg = document.getElementById("feedback-msg")!;
  msg.textContent = "";
  msg.className = "form-msg";
  modal.style.display = "flex";
  (document.getElementById("feedback-message") as HTMLTextAreaElement).focus();
}

function openGenericFeedbackModal() {
  openFeedbackModal("", "");
  (document.getElementById("feedback-type") as HTMLSelectElement).value = "missing";
}

function closeFeedbackModal() {
  document.getElementById("feedback-modal")!.style.display = "none";
}

async function submitFeedback(e: Event) {
  e.preventDefault();
  const msg = document.getElementById("feedback-msg")!;
  const submitBtn = document.querySelector("#feedback-form .btn-submit") as HTMLButtonElement;

  const payload = {
    court_id: (document.getElementById("feedback-court-id") as HTMLInputElement).value,
    feedback_type: (document.getElementById("feedback-type") as HTMLSelectElement).value,
    message: (document.getElementById("feedback-message") as HTMLTextAreaElement).value.trim(),
  };

  if (!payload.message) {
    msg.textContent = t("gerichte.feedback.error.required");
    msg.className = "form-msg form-msg-error";
    return;
  }

  submitBtn.disabled = true;
  try {
    const resp = await fetch("/api/courts/feedback", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload),
    });
    if (!resp.ok) {
      const data = await resp.json().catch(() => ({}));
      msg.textContent = data.error || t("gerichte.feedback.error.generic");
      msg.className = "form-msg form-msg-error";
      return;
    }
    msg.textContent = t("gerichte.feedback.success");
    msg.className = "form-msg form-msg-success";
    setTimeout(closeFeedbackModal, 1500);
  } catch {
    msg.textContent = t("gerichte.feedback.error.generic");
    msg.className = "form-msg form-msg-error";
  } finally {
    submitBtn.disabled = false;
  }
}

function initModal() {
  document.getElementById("btn-feedback")!.addEventListener("click", openGenericFeedbackModal);
  document.getElementById("feedback-close")!.addEventListener("click", closeFeedbackModal);
  document.getElementById("feedback-cancel")!.addEventListener("click", closeFeedbackModal);
  document.getElementById("feedback-modal")!.addEventListener("click", (e) => {
    if (e.target === e.currentTarget) closeFeedbackModal();
  });
  document.getElementById("feedback-form")!.addEventListener("submit", submitFeedback);
}

document.addEventListener("DOMContentLoaded", () => {
  initI18n();
  initSidebar();
  initSearch();
  initFilters();
  initModal();
  onLangChange(() => {
    buildCountryFilters();
    render();
  });
  loadCourts();
});
