"use client";

// Client-side widget backing /trahs/[trahId]/relationship-finder (T-509,
// REQ-SRCH-002). Two independent search-and-pick widgets (mirrors the
// pattern from add-relationship-form.tsx, T-508 — search by name, pick a
// person, submitted id is what actually gets used) select Person A and
// Person B, then a submit action calls
// GET /api/trahs/[trahId]/relationship-finder?a=&b= and renders the result:
// either "UNRELATED", or the computed label plus the connecting path as a
// breadcrumb of links to each person's profile page.
//
// The two pickers are implemented as one local PersonPicker component used
// twice (with independent state lifted up here) rather than a cross-file
// shared component — this page is the only place two pickers are needed
// side by side, so a same-file component is enough to avoid duplicating the
// search/select markup without introducing a new shared module.
import { useState, type FormEvent, type KeyboardEvent } from "react";
import Link from "next/link";

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

type KinshipResult =
  | { label: string; path: PersonSummary[] }
  | { label: "UNRELATED" };

function PersonPicker({
  trahId,
  label,
  selected,
  onSelect,
  onClear,
}: {
  trahId: string;
  label: string;
  selected: PersonSummary | null;
  onSelect: (person: PersonSummary) => void;
  onClear: () => void;
}) {
  const [query, setQuery] = useState("");
  const [results, setResults] = useState<PersonSummary[] | null>(null);
  const [searching, setSearching] = useState(false);
  const [error, setError] = useState<string | null>(null);

  async function runSearch() {
    const trimmed = query.trim();
    if (trimmed.length === 0) {
      setError("Enter a name to search.");
      setResults(null);
      return;
    }

    setError(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[] };
        setResults(data.results);
      } else {
        setError("Search failed. Please try again.");
        setResults(null);
      }
    } catch {
      setError("Something went wrong. Please try again.");
      setResults(null);
    } finally {
      setSearching(false);
    }
  }

  function handleKeyDown(event: KeyboardEvent<HTMLInputElement>) {
    if (event.key === "Enter") {
      // Bug fix (post-build browser E2E check): this picker used to be its
      // own <form>, but it's rendered inside RelationshipFinderPanel's
      // outer <form> below — nested <form> elements are invalid HTML, and
      // browsers silently drop/misparse the inner one, which made the
      // "Search" button submit the OUTER form (finding a relationship with
      // nothing selected) instead of running the search. Plain
      // div+button+onKeyDown avoids the nesting entirely; preventDefault
      // here also stops Enter from bubbling up to the outer form.
      event.preventDefault();
      void runSearch();
    }
  }

  return (
    <div>
      <label htmlFor={`picker-${label}`}>{label}</label>
      <br />
      {selected ? (
        <p style={{ margin: "0.25rem 0" }}>
          Selected: <strong>{selected.displayName}</strong>{" "}
          <button type="button" onClick={onClear}>
            Change
          </button>
        </p>
      ) : (
        <>
          <div style={{ display: "flex", gap: "0.5rem" }}>
            <input
              id={`picker-${label}`}
              type="text"
              value={query}
              onChange={(e) => setQuery(e.target.value)}
              onKeyDown={handleKeyDown}
              placeholder="Search by name…"
            />
            <button type="button" disabled={searching} onClick={() => void runSearch()}>
              {searching ? "Searching…" : "Search"}
            </button>
          </div>
          {error && (
            <p role="alert" style={{ color: "crimson" }}>
              {error}
            </p>
          )}
          {results !== null && (
            <ul style={{ listStyle: "none", margin: "0.5rem 0", padding: 0 }}>
              {results.length === 0 ? (
                <li style={{ color: "#999" }}>No matching persons found.</li>
              ) : (
                results.map((person) => (
                  <li key={person.id}>
                    <button
                      type="button"
                      onClick={() => {
                        onSelect(person);
                        setResults(null);
                        setQuery("");
                      }}
                    >
                      {person.displayName}
                    </button>
                  </li>
                ))
              )}
            </ul>
          )}
        </>
      )}
    </div>
  );
}

export default function RelationshipFinderPanel({ trahId }: { trahId: string }) {
  const [personA, setPersonA] = useState<PersonSummary | null>(null);
  const [personB, setPersonB] = useState<PersonSummary | null>(null);
  const [result, setResult] = useState<KinshipResult | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);

  async function handleFind(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setError(null);
    setResult(null);

    if (!personA || !personB) {
      setError("Select both people first.");
      return;
    }

    setBusy(true);
    try {
      const res = await fetch(
        `/api/trahs/${trahId}/relationship-finder?a=${encodeURIComponent(personA.id)}&b=${encodeURIComponent(personB.id)}`,
      );
      if (res.ok) {
        const data = (await res.json()) as { result: KinshipResult };
        setResult(data.result);
        return;
      }

      if (res.status === 401) {
        setError("You need to be signed in to use the relationship finder.");
      } else if (res.status === 403) {
        setError("You don't have permission to do this in this Trah.");
      } else {
        setError("Something went wrong. Please try again.");
      }
    } catch {
      setError("Something went wrong. Please try again.");
    } finally {
      setBusy(false);
    }
  }

  return (
    <div>
      <form onSubmit={handleFind}>
        <PersonPicker
          trahId={trahId}
          label="Person A"
          selected={personA}
          onSelect={setPersonA}
          onClear={() => setPersonA(null)}
        />

        <PersonPicker
          trahId={trahId}
          label="Person B"
          selected={personB}
          onSelect={setPersonB}
          onClear={() => setPersonB(null)}
        />

        <button type="submit" disabled={busy} style={{ marginTop: "1rem" }}>
          {busy ? "Finding…" : "Find relationship"}
        </button>
      </form>

      {error && (
        <p role="alert" style={{ color: "crimson" }}>
          {error}
        </p>
      )}

      {result && (
        <div style={{ marginTop: "1rem" }}>
          {"path" in result ? (
            <>
              <p>
                Relationship: <strong>{result.label}</strong>
              </p>
              <p style={{ fontSize: "0.85rem", color: "#666" }}>Connecting path:</p>
              <nav aria-label="Connecting path">
                <ol
                  style={{
                    listStyle: "none",
                    display: "flex",
                    flexWrap: "wrap",
                    gap: "0.35rem",
                    padding: 0,
                    margin: 0,
                    alignItems: "center",
                  }}
                >
                  {result.path.map((person: PersonSummary, i: number) => (
                    <li key={person.id} style={{ display: "flex", alignItems: "center", gap: "0.35rem" }}>
                      <Link href={`/trahs/${trahId}/persons/${person.id}/profile`}>
                        {person.displayName}
                      </Link>
                      {i < result.path.length - 1 && <span aria-hidden="true">&rarr;</span>}
                    </li>
                  ))}
                </ol>
              </nav>
            </>
          ) : (
            <p>These two people aren't related (no connecting path was found).</p>
          )}
        </div>
      )}
    </div>
  );
}
