"use client";

// Adds a relationship FROM the current person to another Person. The
// "other person" picker is a small search-and-pick widget (T-508,
// backed by GET /api/trahs/[trahId]/search) that replaces the raw
// Person-id text input this form used before T-508 existed — the user
// types a name, picks one of the matching results, and that Person's id
// is what actually gets submitted.
//
// Directionality (see createRelationship.ts's header): *_PARENT_CHILD is
// directed (personA = parent, personB = child) — the "relation" select
// below picks which role the CURRENT person plays, and the request is built
// accordingly. PARTNER/SIBLING are undirected on the wire (the server
// normalizes pair ordering), so personA/personB order doesn't matter for
// those two.
import { useState, type FormEvent } from "react";
import { useRouter } from "next/navigation";

type PersonSummary = {
  id: string;
  displayName: string;
};

const RELATIONS = [
  { value: "PARENT_OF", label: "…is the parent of…", type: "BIOLOGICAL_PARENT_CHILD" },
  { value: "CHILD_OF", label: "…is the child of…", type: "BIOLOGICAL_PARENT_CHILD" },
  {
    value: "ADOPTIVE_PARENT_OF",
    label: "…is the adoptive parent of…",
    type: "ADOPTIVE_PARENT_CHILD",
  },
  {
    value: "ADOPTIVE_CHILD_OF",
    label: "…is the adoptive child of…",
    type: "ADOPTIVE_PARENT_CHILD",
  },
  { value: "STEP_PARENT_OF", label: "…is the step-parent of…", type: "STEP_PARENT_CHILD" },
  { value: "STEP_CHILD_OF", label: "…is the step-child of…", type: "STEP_PARENT_CHILD" },
  { value: "PARTNER", label: "…is the partner of…", type: "PARTNER" },
  { value: "SIBLING", label: "…is the sibling of…", type: "SIBLING" },
] as const;

const PARTNER_STATUSES = ["MARRIED", "DIVORCED", "WIDOWED", "ENDED"] as const;

export default function AddRelationshipForm({
  trahId,
  personId,
}: {
  trahId: string;
  personId: string;
}) {
  const router = useRouter();
  const [relation, setRelation] = useState<(typeof RELATIONS)[number]["value"]>("PARENT_OF");
  const [otherPersonId, setOtherPersonId] = useState("");
  const [otherPersonName, setOtherPersonName] = useState<string | null>(null);
  const [searchQuery, setSearchQuery] = useState("");
  const [searchResults, setSearchResults] = useState<PersonSummary[] | null>(null);
  const [searching, setSearching] = useState(false);
  const [searchError, setSearchError] = useState<string | null>(null);
  const [startDate, setStartDate] = useState("");
  const [endDate, setEndDate] = useState("");
  const [status, setStatus] = useState<(typeof PARTNER_STATUSES)[number] | "">("");
  const [error, setError] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);

  const selected = RELATIONS.find((r) => r.value === relation)!;
  const isPartner = selected.type === "PARTNER";

  async function handleSearch(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const trimmed = searchQuery.trim();
    if (trimmed.length === 0) {
      setSearchError("Enter a name to search.");
      setSearchResults(null);
      return;
    }

    setSearchError(null);
    setSearching(true);
    try {
      const res = await fetch(`/api/trahs/${trahId}/search?q=${encodeURIComponent(trimmed)}`);
      if (res.ok) {
        const data = (await res.json()) as { results: PersonSummary[] };
        setSearchResults(data.results);
      } else {
        setSearchError("Search failed. Please try again.");
        setSearchResults(null);
      }
    } catch {
      setSearchError("Something went wrong. Please try again.");
      setSearchResults(null);
    } finally {
      setSearching(false);
    }
  }

  function pickPerson(person: PersonSummary) {
    setOtherPersonId(person.id);
    setOtherPersonName(person.displayName);
    setSearchResults(null);
    setSearchQuery("");
  }

  async function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setError(null);
    if (!otherPersonId) {
      setError("Search for and select the other person first.");
      return;
    }
    setBusy(true);
    try {
      // *_PARENT_CHILD is directed: personA = parent, personB = child.
      // "…is the parent of…" / "…is the adoptive/step parent of…" means the
      // CURRENT person is personA; the "…child of…" variants mean the
      // current person is personB. PARTNER/SIBLING order doesn't matter —
      // sent in a fixed order, the server normalizes it.
      const currentIsParent = relation.endsWith("_OF") && !relation.includes("CHILD_OF");
      const personAId = currentIsParent ? personId : otherPersonId;
      const personBId = currentIsParent ? otherPersonId : personId;

      const res = await fetch(`/api/trahs/${trahId}/relationships`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          personAId,
          personBId,
          type: selected.type,
          data: isPartner
            ? {
                startDate,
                endDate: endDate ? endDate : undefined,
                status: status ? status : undefined,
              }
            : undefined,
        }),
      });

      if (res.ok) {
        setOtherPersonId("");
        setOtherPersonName(null);
        setStartDate("");
        setEndDate("");
        setStatus("");
        router.refresh();
        return;
      }

      const data = (await res.json().catch(() => null)) as { error?: string } | null;
      if (data?.error === "PERSON_NOT_FOUND") {
        setError("The other person's id could not be found in this Trah.");
      } else if (data?.error === "FORBIDDEN") {
        setError("You don't have permission to edit this person.");
      } else {
        setError("Please check the values and try again.");
      }
    } catch {
      setError("Something went wrong. Please try again.");
    } finally {
      setBusy(false);
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <h3>Add a relationship</h3>
      {error && (
        <p role="alert" style={{ color: "crimson" }}>
          {error}
        </p>
      )}

      <div>
        <label htmlFor="relationship-relation">This person…</label>
        <br />
        <select
          id="relationship-relation"
          value={relation}
          onChange={(e) => setRelation(e.target.value as (typeof RELATIONS)[number]["value"])}
        >
          {RELATIONS.map((r) => (
            <option key={r.value} value={r.value}>
              {r.label}
            </option>
          ))}
        </select>
      </div>

      <div>
        <label htmlFor="relationship-other-person-search">Other person</label>
        <br />
        {otherPersonName ? (
          <p style={{ margin: "0.25rem 0" }}>
            Selected: <strong>{otherPersonName}</strong>{" "}
            <button
              type="button"
              onClick={() => {
                setOtherPersonId("");
                setOtherPersonName(null);
              }}
            >
              Change
            </button>
          </p>
        ) : (
          <>
            <div style={{ display: "flex", gap: "0.5rem" }}>
              <input
                id="relationship-other-person-search"
                type="text"
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}
                placeholder="Search by name…"
                onKeyDown={(e) => {
                  if (e.key === "Enter") {
                    e.preventDefault();
                    handleSearch(e as unknown as FormEvent<HTMLFormElement>);
                  }
                }}
              />
              <button
                type="button"
                disabled={searching}
                onClick={(e) => handleSearch(e as unknown as FormEvent<HTMLFormElement>)}
              >
                {searching ? "Searching…" : "Search"}
              </button>
            </div>
            {searchError && (
              <p role="alert" style={{ color: "crimson" }}>
                {searchError}
              </p>
            )}
            {searchResults !== null && (
              <ul style={{ listStyle: "none", margin: "0.5rem 0", padding: 0 }}>
                {searchResults.length === 0 ? (
                  <li style={{ color: "#999" }}>No matching persons found.</li>
                ) : (
                  searchResults.map((person) => (
                    <li key={person.id}>
                      <button type="button" onClick={() => pickPerson(person)}>
                        {person.displayName}
                      </button>
                    </li>
                  ))
                )}
              </ul>
            )}
          </>
        )}
      </div>

      {isPartner && (
        <>
          <div>
            <label htmlFor="relationship-start">Start date</label>
            <br />
            <input
              id="relationship-start"
              type="date"
              value={startDate}
              onChange={(e) => setStartDate(e.target.value)}
              required
            />
          </div>

          <div>
            <label htmlFor="relationship-end">End date (optional)</label>
            <br />
            <input
              id="relationship-end"
              type="date"
              value={endDate}
              onChange={(e) => setEndDate(e.target.value)}
            />
          </div>

          <div>
            <label htmlFor="relationship-status">Status (optional)</label>
            <br />
            <select
              id="relationship-status"
              value={status}
              onChange={(e) => setStatus(e.target.value as (typeof PARTNER_STATUSES)[number] | "")}
            >
              <option value="">(none)</option>
              {PARTNER_STATUSES.map((s) => (
                <option key={s} value={s}>
                  {s}
                </option>
              ))}
            </select>
          </div>
        </>
      )}

      <button type="submit" disabled={busy}>
        {busy ? "Saving…" : "Add relationship"}
      </button>
    </form>
  );
}
