import { initI18n } from "./i18n";
import { initSidebar } from "./sidebar";
import {
  loadParentCandidates,
  initParentPicker,
  wireTypeChange,
  showFieldsForType,
  readPayload,
} from "./project-form";

// /projects/new client. Posts v2 CreateProjectInput shape using the shared
// project-form helpers.

function $(id: string): HTMLElement {
  const el = document.getElementById(id);
  if (!el) throw new Error("missing element: " + id);
  return el;
}

// sanitizeReturnUrl restricts the post-create bounce-back to same-origin
// paths. Any value that could escape to a different origin (protocol-
// relative `//foo`, absolute `https://...`, or non-rooted relative
// paths) is rejected and the form falls back to /projects/{id}. m's
// 2026-05-08 Determinator Slice 2: the /tools/fristenrechner Step 1
// "Neue Akte anlegen" link sends ?return=/tools/fristenrechner so the
// new project preselects itself when control bounces back.
function sanitizeReturnUrl(raw: string | null): string | null {
  if (!raw) return null;
  if (raw.startsWith("//")) return null;
  if (raw.includes("://")) return null;
  if (!raw.startsWith("/")) return null;
  return raw;
}

function submitForm() {
  const form = $("project-new-form") as HTMLFormElement;
  const msg = $("project-new-msg") as HTMLParagraphElement;
  form.addEventListener("submit", async (e) => {
    e.preventDefault();
    msg.textContent = "";
    msg.className = "form-msg";

    const payload = readPayload(msg, { omitEmpty: true, mode: "create" });
    if (!payload) return;

    try {
      const resp = await fetch("/api/projects", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload),
      });
      if (!resp.ok) {
        const errBody = await resp.json().catch(() => ({ error: "unknown" }));
        msg.textContent = errBody.error || "Fehler beim Anlegen";
        msg.className = "form-msg form-msg-error";
        return;
      }
      const p = (await resp.json()) as { id: string };

      // Honour ?return=<path> if it's a same-origin rooted path. The
      // caller is responsible for ensuring the destination knows what
      // to do with the appended ?project= param; see Slice 1's Step 1
      // hydration.
      const qs = new URLSearchParams(window.location.search);
      const returnUrl = sanitizeReturnUrl(qs.get("return"));
      if (returnUrl) {
        const dest = new URL(returnUrl, window.location.origin);
        dest.searchParams.set("project", p.id);
        window.location.href = dest.pathname + dest.search + dest.hash;
        return;
      }

      window.location.href = `/projects/${p.id}`;
    } catch (e) {
      msg.textContent = String(e);
      msg.className = "form-msg form-msg-error";
    }
  });
}

async function applyParentFromQueryString() {
  const qs = new URLSearchParams(window.location.search);
  const parentID = qs.get("parent");
  if (!parentID) return;
  try {
    const resp = await fetch(`/api/projects/${encodeURIComponent(parentID)}`);
    if (!resp.ok) return;
    const p = (await resp.json()) as { id: string; title: string };
    ($("projekt-parent-id") as HTMLInputElement).value = p.id;
    ($("projekt-parent-input") as HTMLInputElement).value = p.title;
    // Default to 'case' under a non-root parent; user can override.
    const typeSel = $("project-type") as HTMLSelectElement;
    if (typeSel.value === "client") {
      typeSel.value = "case";
      showFieldsForType(typeSel.value);
    }
  } catch {
    // ignore
  }
}

document.addEventListener("DOMContentLoaded", async () => {
  initI18n();
  initSidebar();
  wireTypeChange();
  await loadParentCandidates();
  initParentPicker();
  await applyParentFromQueryString();
  submitForm();
});
