import { useEffect, useId, useRef, Fragment } from "react";
import type { GraphNode, SuggestHit } from "./types";

export type DefinitionSense = { pos: string; glosses: string[] };

export type DefinitionPayload = {
  term: string;
  lang?: string;
  matched_code?: string | null;
  senses?: DefinitionSense[];
  fallback?: boolean;
  url?: string;
  error?: string | null;
};

type Detail = Record<string, unknown> | null;

type CognateSet = {
  id: number;
  language_count: number;
  word_count: number;
  words: { term?: string; lang?: string }[];
};

type WalsRow = { feature_id: string; feature_name: string; value_label: string };
type PhonemeRow = { phoneme: string; tone?: number };

export function WordModal({
  open,
  node,
  detail,
  definition,
  definitionLoading,
  onClose,
  onDescend,
  onLeafLang,
  onPickEtymon,
}: {
  open: boolean;
  node: GraphNode | null;
  detail: Detail;
  definition: DefinitionPayload | null;
  definitionLoading: boolean;
  onClose: () => void;
  onDescend: () => void;
  onLeafLang: () => void;
  onPickEtymon: (term: string, lang: string) => void;
}) {
  const titleId = useId();
  const closeRef = useRef<HTMLButtonElement>(null);

  useEffect(() => {
    if (!open) return;
    const prev = document.activeElement as HTMLElement | null;
    closeRef.current?.focus();
    const onKey = (e: KeyboardEvent) => {
      if (e.key === "Escape") onClose();
    };
    document.addEventListener("keydown", onKey);
    const overflow = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => {
      document.removeEventListener("keydown", onKey);
      document.body.style.overflow = overflow;
      prev?.focus?.();
    };
  }, [open, onClose]);

  if (!open || !node) return null;

  const etymons = ((detail?.etymons as SuggestHit[]) || []).slice(0, 8);
  const cognates = ((detail?.cognate_sets as CognateSet[]) || []).slice(0, 3);
  const childRels = (detail?.child_relations as Record<string, number>) || {};
  const wals = ((detail?.wals as WalsRow[]) || []).slice(0, 6);
  const phonemes = (detail?.phonemes as PhonemeRow[]) || [];
  const wiki = (detail?.wiktionary as string) || definition?.url;
  const senses = definition?.senses || [];

  return (
    <div className="modal-root" role="presentation">
      <button type="button" className="modal-backdrop" aria-label="Close word details" onClick={onClose} />
      <div className="modal-dialog" role="dialog" aria-modal="true" aria-labelledby={titleId}>
        <header className="modal-head">
          <div>
            <h2 id={titleId}>{node.term}</h2>
            <p>
              {node.lang_display || node.lang}
              {node.family_name ? ` · ${node.family_name}` : ""}
              {node.relation ? ` · ${node.relation}` : node.depth === 0 ? " · root" : ""}
              {node.confidence != null ? ` · ${Number(node.confidence).toFixed(2)}` : ""}
            </p>
          </div>
          <button ref={closeRef} type="button" className="ghost sheet-close" onClick={onClose}>
            Close
          </button>
        </header>

        <div className="modal-body">
          <section>
            <h3>Definition</h3>
            {definitionLoading ? (
              <p className="modal-muted">Looking up Wiktionary…</p>
            ) : senses.length ? (
              <>
                {definition?.fallback ? (
                  <p className="modal-muted">
                    No exact language match — showing Wiktionary glosses for [{definition.matched_code}].
                  </p>
                ) : null}
                <div className="modal-senses">
                  {senses.map((s) => (
                    <div key={s.pos} className="modal-sense">
                      <div className="modal-pos">{s.pos}</div>
                      <ol>
                        {s.glosses.map((g) => (
                          <li key={g}>{g}</li>
                        ))}
                      </ol>
                    </div>
                  ))}
                </div>
              </>
            ) : (
              <p className="modal-muted">
                No Wiktionary gloss found for this spelling
                {definition?.error ? ` (${definition.error})` : ""}.
                {wiki ? (
                  <>
                    {" "}
                    <a href={wiki} target="_blank" rel="noreferrer">
                      Open Wiktionary
                    </a>
                  </>
                ) : null}
              </p>
            )}
          </section>

          <section>
            <h3>In this graph</h3>
            <dl className="kv">
              <dt>Depth</dt>
              <dd>{node.depth}</dd>
              <dt>Children</dt>
              <dd>{node.child_count ?? "—"}</dd>
              <dt>Area</dt>
              <dd>{node.macroarea || "—"}</dd>
              <dt>Status</dt>
              <dd>{node.status || "—"}</dd>
              <dt>Glottocode</dt>
              <dd>{node.glottocode || "—"}</dd>
              <dt>ISO 639-3</dt>
              <dd>{node.iso_639_3 || "—"}</dd>
            </dl>
            {!!Object.keys(childRels).length && (
              <p className="modal-chips">
                {Object.entries(childRels).map(([k, v]) => (
                  <span key={k} className="chip">
                    {k.replace("_", " ")} {v}
                  </span>
                ))}
              </p>
            )}
          </section>

          {!!etymons.length && (
            <section>
              <h3>Comes from</h3>
              <div className="path-list">
                {etymons.map((e, i) => (
                  <button key={`${e.term}-${e.lang}-${i}`} type="button" onClick={() => onPickEtymon(e.term, e.lang)}>
                    {e.term} · {e.lang_display || e.lang}
                    {(e as unknown as { relation?: string }).relation
                      ? ` · ${(e as unknown as { relation?: string }).relation}`
                      : ""}
                  </button>
                ))}
              </div>
            </section>
          )}

          {!!cognates.length && (
            <section>
              <h3>Cognate sets</h3>
              {cognates.map((c) => (
                <p key={c.id} className="modal-muted">
                  {c.language_count} languages · {(c.words || []).slice(0, 8).map((w) => w.term).filter(Boolean).join(", ")}
                  {(c.words || []).length > 8 ? "…" : ""}
                </p>
              ))}
            </section>
          )}

          {!!wals.length && (
            <section>
              <h3>Typology (WALS sample)</h3>
              <dl className="kv">
                {wals.map((w) => (
                  <Fragment key={w.feature_id}>
                    <dt title={w.feature_name}>{w.feature_id}</dt>
                    <dd>{w.value_label}</dd>
                  </Fragment>
                ))}
              </dl>
            </section>
          )}

          {!!phonemes.length && (
            <section>
              <h3>Phonemes</h3>
              <p className="modal-muted">
                {phonemes.length} segments
                {phonemes.some((p) => p.tone) ? " · has tone" : ""}
                {" · "}
                {phonemes
                  .slice(0, 24)
                  .map((p) => p.phoneme)
                  .join(" ")}
                {phonemes.length > 24 ? " …" : ""}
              </p>
            </section>
          )}
        </div>

        <footer className="modal-foot">
          {node.kind === "word" && (
            <>
              <button type="button" className="ghost primary" onClick={onDescend}>
                Descend from here
              </button>
              <button type="button" className="ghost" onClick={onLeafLang}>
                Leaf = this language
              </button>
            </>
          )}
          {wiki && (
            <a className="ghost" href={wiki} target="_blank" rel="noreferrer">
              Wiktionary
            </a>
          )}
        </footer>
      </div>
    </div>
  );
}
