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

interface PartnerUnit {
  id: string;
  name: string;
  lead_user_id?: string | null;
  office: string;
  created_at: string;
  updated_at: string;
}

interface Member {
  user_id: string;
  email: string;
  display_name: string;
  office: string;
  job_title: string | null;
  unit_role: string;
}

const UNIT_ROLES = ["lead", "attorney", "senior_pa", "pa", "paralegal"] as const;

interface PartnerUnitWithMembers extends PartnerUnit {
  lead_display_name?: string;
  lead_email?: string;
  members: Member[];
}

interface Office {
  key: string;
  label_de: string;
  label_en: string;
}

interface UserOption {
  id: string;
  display_name: string;
  email: string;
}

let units: PartnerUnitWithMembers[] = [];
let offices: Office[] = [];
let userOptions: UserOption[] = [];
let activeUnitID: string | null = null;

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 officeLabel(key: string): string {
  const o = offices.find((x) => x.key === key);
  if (!o) return key;
  return getLang() === "de" ? o.label_de : o.label_en;
}

async function loadAll(): Promise<void> {
  await Promise.all([loadOffices(), loadUnits(), loadUsers()]);
  render();
}

async function loadOffices(): Promise<void> {
  const resp = await fetch("/api/offices");
  if (resp.ok) offices = (await resp.json()) as Office[];
}

async function loadUnits(): Promise<void> {
  const resp = await fetch("/api/partner-units?include=members");
  if (resp.ok) units = (await resp.json()) as PartnerUnitWithMembers[];
}

async function loadUsers(): Promise<void> {
  const resp = await fetch("/api/users");
  if (resp.ok) userOptions = (await resp.json()) as UserOption[];
}

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

function render(): void {
  const tbody = document.getElementById("pu-tbody")!;
  const empty = document.getElementById("pu-empty")!;
  if (!units.length) {
    tbody.innerHTML = "";
    empty.style.display = "block";
    return;
  }
  empty.style.display = "none";
  tbody.innerHTML = units
    .map((u) => {
      const lead = u.lead_display_name ?? "&mdash;";
      const memberCount = u.members.length;
      return `<tr data-id="${esc(u.id)}">
        <td class="entity-col-title">${esc(u.name)}</td>
        <td><span class="office-chip office-${esc(u.office)}">${esc(officeLabel(u.office))}</span></td>
        <td>${esc(lead)}</td>
        <td>${memberCount}</td>
        <td class="admin-team-actions-cell">
          <button type="button" class="btn-link pu-members-btn" data-id="${esc(u.id)}" data-i18n="admin.partner_units.action.members">Mitglieder</button>
          <button type="button" class="btn-link pu-edit-btn" data-id="${esc(u.id)}" data-i18n="admin.partner_units.action.edit">Bearbeiten</button>
          <button type="button" class="btn-link pu-delete-btn" data-id="${esc(u.id)}" data-i18n="admin.partner_units.action.delete">L&ouml;schen</button>
        </td>
      </tr>`;
    })
    .join("");

  tbody.querySelectorAll<HTMLButtonElement>(".pu-members-btn").forEach((b) =>
    b.addEventListener("click", () => openMembersModal(b.dataset.id!)),
  );
  tbody.querySelectorAll<HTMLButtonElement>(".pu-edit-btn").forEach((b) =>
    b.addEventListener("click", () => openEditModal(b.dataset.id!)),
  );
  tbody.querySelectorAll<HTMLButtonElement>(".pu-delete-btn").forEach((b) =>
    b.addEventListener("click", () => deleteUnit(b.dataset.id!)),
  );
}

// ---- Edit modal -----------------------------------------------------------

function openEditModal(id: string | null): void {
  const modal = document.getElementById("pu-edit-modal")!;
  const titleEl = document.getElementById("pu-edit-title")!;
  const idField = document.getElementById("pu-edit-id") as HTMLInputElement;
  const nameField = document.getElementById("pu-edit-name") as HTMLInputElement;
  const officeSel = document.getElementById("pu-edit-office") as HTMLSelectElement;
  const leadSel = document.getElementById("pu-edit-lead") as HTMLSelectElement;
  const msg = document.getElementById("pu-edit-msg")!;

  msg.textContent = "";
  msg.className = "form-msg";

  // Populate office options.
  officeSel.innerHTML = offices
    .map((o) => `<option value="${esc(o.key)}">${esc(officeLabel(o.key))}</option>`)
    .join("");

  // Populate lead options (sorted).
  const leadEntries = userOptions
    .slice()
    .sort((a, b) => (a.display_name || a.email).localeCompare(b.display_name || b.email));
  leadSel.innerHTML =
    `<option value="">&mdash;</option>` +
    leadEntries
      .map((u) => {
        const label = u.display_name ? `${u.display_name} (${u.email})` : u.email;
        return `<option value="${esc(u.id)}">${esc(label)}</option>`;
      })
      .join("");

  if (id) {
    const u = units.find((x) => x.id === id);
    if (!u) return;
    titleEl.setAttribute("data-i18n", "admin.partner_units.edit.heading");
    titleEl.textContent = t("admin.partner_units.edit.heading") || "Partner Unit bearbeiten";
    idField.value = u.id;
    nameField.value = u.name;
    officeSel.value = u.office;
    leadSel.value = u.lead_user_id ?? "";
  } else {
    titleEl.setAttribute("data-i18n", "admin.partner_units.new.heading");
    titleEl.textContent = t("admin.partner_units.new.heading") || "Partner Unit anlegen";
    idField.value = "";
    nameField.value = "";
    officeSel.value = offices[0]?.key ?? "munich";
    leadSel.value = "";
  }

  modal.style.display = "flex";
  nameField.focus();
}

function closeEditModal(): void {
  document.getElementById("pu-edit-modal")!.style.display = "none";
}

async function submitEdit(e: Event): Promise<void> {
  e.preventDefault();
  const idField = document.getElementById("pu-edit-id") as HTMLInputElement;
  const nameField = document.getElementById("pu-edit-name") as HTMLInputElement;
  const officeSel = document.getElementById("pu-edit-office") as HTMLSelectElement;
  const leadSel = document.getElementById("pu-edit-lead") as HTMLSelectElement;
  const msg = document.getElementById("pu-edit-msg")!;

  const name = nameField.value.trim();
  if (!name) {
    msg.textContent = t("admin.partner_units.error.name_required") || "Name erforderlich";
    msg.className = "form-msg form-msg-error";
    return;
  }

  const isEdit = !!idField.value;
  // Server treats missing keys as "no change". For lead clearing we send the
  // nil UUID — service code interprets that as "explicit clear".
  const NIL_UUID = "00000000-0000-0000-0000-000000000000";
  const payload: Record<string, unknown> = {
    name,
    office: officeSel.value,
    lead_user_id: leadSel.value || NIL_UUID,
  };
  const url = isEdit ? `/api/partner-units/${idField.value}` : "/api/partner-units";
  const method = isEdit ? "PATCH" : "POST";

  const resp = await fetch(url, {
    method,
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(payload),
  });
  if (!resp.ok) {
    const body = await resp.json().catch(() => ({ error: resp.statusText }));
    msg.textContent = body.error || "Fehler.";
    msg.className = "form-msg form-msg-error";
    return;
  }
  closeEditModal();
  await loadUnits();
  render();
  showFeedback(
    isEdit
      ? t("admin.partner_units.feedback.updated") || "Aktualisiert."
      : t("admin.partner_units.feedback.created") || "Angelegt.",
    false,
  );
}

async function deleteUnit(id: string): Promise<void> {
  const u = units.find((x) => x.id === id);
  if (!u) return;
  const confirmMsg = (t("admin.partner_units.confirm_delete") || "Partner Unit \"{name}\" wirklich löschen?")
    .replace("{name}", u.name);
  if (!window.confirm(confirmMsg)) return;
  const resp = await fetch(`/api/partner-units/${id}`, { method: "DELETE" });
  if (!resp.ok && resp.status !== 204) {
    const body = await resp.json().catch(() => ({ error: resp.statusText }));
    showFeedback(body.error || "Löschen fehlgeschlagen.", true);
    return;
  }
  await loadUnits();
  render();
  showFeedback(t("admin.partner_units.feedback.deleted") || "Gelöscht.", false);
}

// ---- Members modal --------------------------------------------------------

function openMembersModal(id: string): void {
  activeUnitID = id;
  const u = units.find((x) => x.id === id);
  if (!u) return;
  const titleEl = document.getElementById("pu-members-title")!;
  titleEl.textContent =
    (t("admin.partner_units.member.heading") || "Mitglieder verwalten") + " — " + u.name;
  renderMemberList();

  // Reset add form
  (document.getElementById("pu-add-input") as HTMLInputElement).value = "";
  (document.getElementById("pu-add-user-id") as HTMLInputElement).value = "";
  document.getElementById("pu-add-suggestions")!.innerHTML = "";
  const msg = document.getElementById("pu-add-msg")!;
  msg.textContent = "";
  msg.className = "form-msg";

  document.getElementById("pu-members-modal")!.style.display = "flex";
}

function closeMembersModal(): void {
  document.getElementById("pu-members-modal")!.style.display = "none";
  activeUnitID = null;
}

function renderMemberList(): void {
  if (!activeUnitID) return;
  const u = units.find((x) => x.id === activeUnitID);
  if (!u) return;
  const list = document.getElementById("pu-members-list")!;
  if (!u.members.length) {
    list.innerHTML = `<li class="form-hint">${esc(t("admin.partner_units.member.empty") || "Noch keine Mitglieder.")}</li>`;
    return;
  }
  list.innerHTML = u.members
    .map((m) => {
      const roleOptions = UNIT_ROLES.map((r) => {
        const label = tDyn(`unit_role.${r}`) || r;
        const sel = m.unit_role === r ? " selected" : "";
        return `<option value="${esc(r)}"${sel}>${esc(label)}</option>`;
      }).join("");
      return `<li class="partner-unit-member-item">
        <span>${esc(m.display_name || m.email)} <span class="form-hint">(${esc(m.email)})</span></span>
        <span class="partner-unit-member-actions">
          <select class="pu-role-select" data-user="${esc(m.user_id)}" aria-label="${escAttr(tDyn("admin.partner_units.member.role") || "Rolle")}">${roleOptions}</select>
          <button type="button" class="btn-ghost btn-small pu-remove-btn" data-user="${esc(m.user_id)}">${esc(t("admin.partner_units.member.remove") || "Entfernen")}</button>
        </span>
      </li>`;
    })
    .join("");
  list.querySelectorAll<HTMLButtonElement>(".pu-remove-btn").forEach((b) =>
    b.addEventListener("click", () => removeMember(b.dataset.user!)),
  );
  list.querySelectorAll<HTMLSelectElement>(".pu-role-select").forEach((s) =>
    s.addEventListener("change", () => setMemberRole(s.dataset.user!, s.value, s)),
  );
}

async function setMemberRole(userID: string, role: string, sel: HTMLSelectElement): Promise<void> {
  if (!activeUnitID) return;
  // Snapshot the prior selection so we can roll back on failure.
  const u = units.find((x) => x.id === activeUnitID);
  const prior = u?.members.find((m) => m.user_id === userID)?.unit_role;
  sel.disabled = true;
  const resp = await fetch(
    `/api/partner-units/${activeUnitID}/members/${userID}/role`,
    {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ unit_role: role }),
    },
  );
  sel.disabled = false;
  if (!resp.ok) {
    if (prior !== undefined) sel.value = prior;
    const body = await resp.json().catch(() => ({ error: resp.statusText }));
    showFeedback(body.error || "Rolle konnte nicht gespeichert werden.", true);
    return;
  }
  await loadUnits();
  renderMemberList();
  render();
  showFeedback(tDyn("admin.partner_units.feedback.role_updated") || "Rolle aktualisiert.", false);
}

function wireSuggestions(): void {
  const input = document.getElementById("pu-add-input") as HTMLInputElement;
  const hidden = document.getElementById("pu-add-user-id") as HTMLInputElement;
  const sugs = document.getElementById("pu-add-suggestions")!;

  input.addEventListener("input", () => {
    const q = input.value.trim().toLowerCase();
    hidden.value = "";
    if (!q) {
      sugs.innerHTML = "";
      return;
    }
    const matches = userOptions
      .filter((u) => (u.display_name + " " + u.email).toLowerCase().includes(q))
      .slice(0, 8);
    sugs.innerHTML = matches
      .map(
        (u) => `<div class="collab-suggestion" data-id="${esc(u.id)}" data-label="${escAttr(u.display_name || u.email)}">
          <strong>${esc(u.display_name || u.email)}</strong>
          <span class="form-hint">${esc(u.email)}</span>
        </div>`,
      )
      .join("");
    sugs.querySelectorAll<HTMLDivElement>(".collab-suggestion").forEach((el) => {
      el.addEventListener("click", () => {
        hidden.value = el.dataset.id!;
        input.value = el.dataset.label!;
        sugs.innerHTML = "";
      });
    });
  });
}

async function submitAddMember(e: Event): Promise<void> {
  e.preventDefault();
  if (!activeUnitID) return;
  const hidden = document.getElementById("pu-add-user-id") as HTMLInputElement;
  const msg = document.getElementById("pu-add-msg")!;
  if (!hidden.value) {
    msg.textContent = t("admin.partner_units.error.user_required") || "Benutzer auswählen";
    msg.className = "form-msg form-msg-error";
    return;
  }
  const resp = await fetch(`/api/partner-units/${activeUnitID}/members`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ user_id: hidden.value }),
  });
  if (!resp.ok && resp.status !== 204) {
    const body = await resp.json().catch(() => ({ error: resp.statusText }));
    msg.textContent = body.error || "Fehler.";
    msg.className = "form-msg form-msg-error";
    return;
  }
  (document.getElementById("pu-add-input") as HTMLInputElement).value = "";
  hidden.value = "";
  document.getElementById("pu-add-suggestions")!.innerHTML = "";
  msg.textContent = "";
  await loadUnits();
  renderMemberList();
  render();
}

async function removeMember(userID: string): Promise<void> {
  if (!activeUnitID) return;
  const confirmMsg = t("admin.partner_units.member.confirm_remove") || "Mitglied entfernen?";
  if (!window.confirm(confirmMsg)) return;
  const resp = await fetch(
    `/api/partner-units/${activeUnitID}/members/${userID}`,
    { method: "DELETE" },
  );
  if (!resp.ok && resp.status !== 204) {
    const body = await resp.json().catch(() => ({ error: resp.statusText }));
    showFeedback(body.error || "Entfernen fehlgeschlagen.", true);
    return;
  }
  await loadUnits();
  renderMemberList();
  render();
}

// ---- Init -----------------------------------------------------------------

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

  document.getElementById("pu-new-btn")!.addEventListener("click", () => openEditModal(null));
  document.getElementById("pu-edit-close")!.addEventListener("click", closeEditModal);
  document.getElementById("pu-edit-cancel")!.addEventListener("click", closeEditModal);
  document.getElementById("pu-edit-form")!.addEventListener("submit", submitEdit);
  document.getElementById("pu-edit-modal")!.addEventListener("click", (e) => {
    if (e.target === e.currentTarget) closeEditModal();
  });

  document.getElementById("pu-members-close")!.addEventListener("click", closeMembersModal);
  document.getElementById("pu-add-form")!.addEventListener("submit", submitAddMember);
  document.getElementById("pu-members-modal")!.addEventListener("click", (e) => {
    if (e.target === e.currentTarget) closeMembersModal();
  });
  wireSuggestions();

  onLangChange(() => render());
  void loadAll();
});
