/* Link Finder - pick two nodes, trace the shortest connecting chain.
   Exports: LinkFinder.                                               */

function relationLabel(a, b) {
  const D = window.DATA;
  const e = D.edges.find((x) => (x.a === a && x.b === b) || (x.a === b && x.b === a));
  const t = e ? e.type : "linked";
  const m = {
    funded: "funds", unfunded: "tracks", account: "manages", works_at: "works at",
    has_project: "runs", relates: "relates to", contact: "contact for",
    attended: "attended", linked: "linked to",
  };
  return m[t] || "linked to";
}

function EntityPicker({ label, value, onChange, exclude, placeholder }) {
  const D = window.DATA;
  const [open, setOpen] = React.useState(false);
  const [q, setQ] = React.useState("");
  const ref = React.useRef(null);
  React.useEffect(() => {
    const h = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", h);
    return () => document.removeEventListener("mousedown", h);
  }, []);
  const all = [
    { group: "Funder", items: [D.funder] },
    { group: "Organisations", items: D.orgs },
    { group: "People", items: D.people },
    { group: "Projects", items: D.projects },
    { group: "Events", items: D.events },
  ];
  const sel = value ? D.byId[value] : null;
  const kind = value ? D.kindOf(value) : null;
  return (
    <div ref={ref} style={{ position: "relative", flex: 1, minWidth: 0 }}>
      <label className="field-label">{label}</label>
      <button className="input focusable" onClick={() => setOpen(!open)}
        style={{ display: "flex", alignItems: "center", gap: 9, cursor: "pointer", textAlign: "left" }}>
        {sel ? (
          <React.Fragment>
            {kind === "org" ? <span style={{ width: 8, height: 8, borderRadius: 999, background: domainColor(sel.domain), flex: "none" }} />
              : <Icon name={KIND_META[kind].icon} size={14} style={{ color: "var(--text-muted)" }} />}
            <span style={{ flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{sel.name}</span>
          </React.Fragment>
        ) : <span style={{ flex: 1, color: "var(--text-faint)" }}>{placeholder}</span>}
        <Icon name="chevronDown" size={15} style={{ color: "var(--text-faint)" }} />
      </button>
      {open && (
        <div className="card fade-in" style={{ position: "absolute", top: "100%", left: 0, right: 0, marginTop: 6, zIndex: 20, boxShadow: "var(--shadow-lg)", maxHeight: 320, overflow: "auto" }}>
          <div style={{ position: "sticky", top: 0, background: "var(--surface)", padding: 8, borderBottom: "1px solid var(--border)" }}>
            <input autoFocus className="input focusable" placeholder="Search…" value={q} onChange={(e) => setQ(e.target.value)} style={{ fontSize: 13 }} />
          </div>
          {all.map((g) => {
            const items = g.items.filter((it) => it.id !== exclude && (!q || it.name.toLowerCase().includes(q.toLowerCase())));
            if (!items.length) return null;
            return (
              <div key={g.group} style={{ padding: "6px 0" }}>
                <div className="t-eyebrow" style={{ padding: "4px 12px" }}>{g.group}</div>
                {items.map((it) => {
                  const k = D.kindOf(it.id);
                  return (
                    <button key={it.id} className="focusable" onClick={() => { onChange(it.id); setOpen(false); setQ(""); }}
                      style={{ display: "flex", alignItems: "center", gap: 9, width: "100%", padding: "8px 12px", border: "none", background: "none", cursor: "pointer", textAlign: "left", color: "var(--text)", font: "inherit", fontSize: 13.5 }}
                      onMouseEnter={(e) => (e.currentTarget.style.background = "var(--surface-2)")}
                      onMouseLeave={(e) => (e.currentTarget.style.background = "none")}>
                      {k === "org" ? <span style={{ width: 8, height: 8, borderRadius: 999, background: domainColor(it.domain), flex: "none" }} />
                        : <Icon name={KIND_META[k].icon} size={14} style={{ color: "var(--text-muted)" }} />}
                      {it.name}
                    </button>
                  );
                })}
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

function PathNode({ id, onOpen, dim }) {
  const D = window.DATA;
  const e = D.byId[id]; const kind = D.kindOf(id);
  const isFunder = kind === "funder";
  const dc = kind === "org" ? domainColor(e.domain) : "var(--accent)";
  return (
    <button className="focusable" onClick={() => onOpen(id)}
      style={{
        flex: "none", width: 132, padding: "12px 12px", borderRadius: 13, cursor: "pointer",
        background: isFunder ? "var(--accent)" : "var(--surface)", color: isFunder ? "var(--accent-contrast)" : "var(--text)",
        border: isFunder ? "none" : "1.5px solid var(--accent)", boxShadow: "var(--shadow)",
        textAlign: "center", opacity: dim ? 0.4 : 1,
      }}>
      <div style={{ display: "flex", justifyContent: "center", marginBottom: 6 }}>
        <div style={{ width: 30, height: 30, borderRadius: 8, display: "grid", placeItems: "center", background: isFunder ? "rgba(255,255,255,.18)" : (kind === "org" ? domainColor(e.domain, true) : "var(--accent-soft)"), color: isFunder ? "#fff" : dc }}>
          {kind === "person" ? <Avatar name={e.name} size={28} accent /> : <Icon name={KIND_META[kind].icon} size={15} />}
        </div>
      </div>
      <div style={{ fontSize: 12.5, fontWeight: 650, lineHeight: 1.2 }}>{e.name}</div>
      <div style={{ fontSize: 10.5, opacity: 0.7, marginTop: 2, textTransform: "uppercase", letterSpacing: "0.04em" }}>{KIND_META[kind].label}</div>
    </button>
  );
}

function LinkFinder({ onOpen }) {
  const D = window.DATA;
  const [from, setFrom] = React.useState(null);
  const [to, setTo] = React.useState(null);
  const path = (from && to) ? D.shortestPath(from, to) : null;

  const presets = [
    { a: "p-james", b: "funder", label: "James Holloway → Funder" },
    { a: "p-eleanor", b: "p-priya", label: "Eleanor Vance → Priya Nair" },
    { a: "o-quantal", b: "o-dispatch", label: "Quantal Institute → Dispatch" },
  ];

  return (
    <div style={{ position: "absolute", inset: 0, overflow: "auto", background: "var(--bg)" }}>
      <div style={{ maxWidth: 1000, margin: "0 auto", padding: "30px 30px 60px" }}>
        <div style={{ marginBottom: 22 }}>
          <div className="display" style={{ fontSize: 28 }}>Link Finder</div>
          <div style={{ fontSize: 14, color: "var(--text-muted)", marginTop: 3 }}>Pick any two records - we'll trace the shortest path between them through the network.</div>
        </div>

        <div className="card" style={{ padding: 20, marginBottom: 18 }}>
          <div style={{ display: "flex", gap: 14, alignItems: "flex-end", flexWrap: "wrap" }}>
            <EntityPicker label="From" value={from} onChange={setFrom} exclude={to} placeholder="Select a starting record…" />
            <div style={{ paddingBottom: 11, color: "var(--text-faint)" }}><Icon name="arrowRight" size={18} /></div>
            <EntityPicker label="To" value={to} onChange={setTo} exclude={from} placeholder="Select a destination…" />
            {(from || to) && <button className="btn btn-sm" style={{ marginBottom: 1 }} onClick={() => { setFrom(null); setTo(null); }}>Clear</button>}
          </div>
          <div style={{ display: "flex", gap: 7, marginTop: 16, flexWrap: "wrap", alignItems: "center" }}>
            <span style={{ fontSize: 12, color: "var(--text-faint)" }}>Try:</span>
            {presets.map((p) => (
              <button key={p.label} className="chip focusable" onClick={() => { setFrom(p.a); setTo(p.b); }} style={{ fontSize: 12 }}>{p.label}</button>
            ))}
          </div>
        </div>

        {/* result */}
        {!from || !to ? (
          <EmptyState icon="link" title="Select two records" body="Choose a From and a To above, or tap a suggestion, to reveal the connecting chain." />
        ) : !path ? (
          <EmptyState icon="link" title="No connection found" body="These two records aren't linked in the current network." />
        ) : (
          <div className="fade-up">
            <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 16 }}>
              <span className="badge" style={{ background: "var(--accent-soft)", color: "var(--accent)", borderColor: "transparent" }}>
                <Icon name="spark" size={13} /> Shortest path
              </span>
              <span style={{ fontSize: 13, color: "var(--text-muted)" }}><span className="mono">{path.length - 1}</span> {path.length - 1 === 1 ? "hop" : "hops"} · <span className="mono">{path.length}</span> records</span>
            </div>

            {/* horizontal chain */}
            <div className="card grid-texture" style={{ padding: "28px 20px", overflowX: "auto" }}>
              <div style={{ display: "flex", alignItems: "center", gap: 0, minWidth: "min-content", justifyContent: path.length <= 4 ? "center" : "flex-start" }}>
                {path.map((id, i) => (
                  <React.Fragment key={id}>
                    <PathNode id={id} onOpen={onOpen} />
                    {i < path.length - 1 && (
                      <div style={{ flex: "none", display: "flex", flexDirection: "column", alignItems: "center", padding: "0 4px", minWidth: 78 }}>
                        <div style={{ fontSize: 10.5, fontWeight: 600, color: "var(--accent)", textTransform: "uppercase", letterSpacing: "0.04em", marginBottom: 4, textAlign: "center", lineHeight: 1.2 }}>{relationLabel(id, path[i + 1])}</div>
                        <svg width="64" height="14"><defs><marker id="ah" markerWidth="7" markerHeight="7" refX="5" refY="3" orient="auto"><path d="M0 0 L6 3 L0 6 z" fill="var(--accent)" /></marker></defs><line x1="2" y1="7" x2="56" y2="7" stroke="var(--accent)" strokeWidth="1.8" markerEnd="url(#ah)" /></svg>
                      </div>
                    )}
                  </React.Fragment>
                ))}
              </div>
            </div>

            {/* faded full-network hint */}
            <div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 14, fontSize: 12.5, color: "var(--text-faint)" }}>
              <Icon name="map" size={14} /> The rest of the network ({D.orgs.length} orgs) stays faded in the background on the Org Map.
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

window.LinkFinder = LinkFinder;
