// Entity directory — filter rail + dense data table (API-wired).

// React hooks (Babel-standalone — make hooks visible per-script)
const { useState, useEffect, useRef, useMemo, useCallback, createContext, useContext } = React;

const dirStyles = {
  root: { display: "flex", height: "100%", minHeight: 0 },
  rail: {
    width: 180, flex: "0 0 180px",
    borderRight: "1px solid var(--vk-border-subtle)",
    background: "var(--vk-surface-1)",
    padding: 14, display: "flex", flexDirection: "column", gap: 14, overflowY: "auto",
  },
  filterGroup: { display: "flex", flexDirection: "column", gap: 6 },
  groupLabel: {
    fontSize: 10, letterSpacing: "0.08em", textTransform: "uppercase",
    color: "var(--vk-text-tertiary)", fontWeight: 500,
    display: "flex", alignItems: "center", justifyContent: "space-between", cursor: "pointer",
  },
  check: {
    display: "flex", alignItems: "center", gap: 8, fontSize: 12,
    color: "var(--vk-text-secondary)", cursor: "pointer", padding: "2px 0",
  },
  table: { flex: 1, overflow: "auto", padding: 16 },
  tableInner: {
    width: "100%", borderCollapse: "separate", borderSpacing: 0,
    fontSize: 13, fontFamily: "var(--vk-font-sans)",
  },
  th: {
    fontSize: 11, color: "var(--vk-text-tertiary)", letterSpacing: "0.08em",
    textTransform: "uppercase", fontWeight: 500, textAlign: "left",
    padding: "8px 10px", borderBottom: "1px solid var(--vk-border-emphasis)",
    background: "var(--vk-surface-1)", position: "sticky", top: 0, zIndex: 1,
    cursor: "pointer", userSelect: "none",
  },
  td: {
    padding: "9px 10px",
    borderBottom: "1px solid var(--vk-border-subtle)",
    color: "var(--vk-text-primary)", verticalAlign: "middle",
  },
};

const ENTITY_TYPES = ["person","company","investor","fund","government","nonprofit","university","accelerator","incubator","corporation","event"];

function Checkbox({ checked, onChange, label }) {
  return (
    <div style={dirStyles.check} onClick={() => onChange(!checked)}>
      <span
        style={{
          width: 12, height: 12, flex: "0 0 12px", borderRadius: 2,
          border: "1px solid " + (checked ? "var(--vk-magenta)" : "var(--vk-border-emphasis)"),
          background: checked ? "var(--vk-gradient)" : "transparent",
          display: "flex", alignItems: "center", justifyContent: "center",
        }}
      >
        {checked && <Icon name="Check" size={10} color="#fff" />}
      </span>
      <span style={{ flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
        {label}
      </span>
    </div>
  );
}

function FilterGroup({ label, open: openInit = true, children }) {
  const [open, setOpen] = useState(openInit);
  return (
    <div style={dirStyles.filterGroup}>
      <div style={dirStyles.groupLabel} onClick={() => setOpen((o) => !o)}>
        <span>{label}</span>
        <Icon name={open ? "ChevronDown" : "ChevronRight"} size={12} />
      </div>
      {open && <div style={{ display: "flex", flexDirection: "column", gap: 4, paddingTop: 4 }}>{children}</div>}
    </div>
  );
}

function EntityDirectory({ openEntity, listFlag, title }) {
  const app = useAppState();
  const [types, setTypes] = useState(new Set());
  const [minInf, setMinInf] = useState(0);
  const [needsReview, setNeedsReview] = useState(false);
  const [sortKey, setSortKey] = useState(listFlag ? "relevance_score" : "influence_score");
  const [sortDir, setSortDir] = useState("desc");
  const [offset, setOffset] = useState(0);
  const LIMIT = 50;

  const query = useMemo(() => ({
    city: app.city,
    run_id: app.runId,
    entity_type: types.size === 1 ? [...types][0] : undefined,
    candidate_flag: listFlag || undefined,
    candidate_value: listFlag ? "yes" : undefined,
    min_influence: minInf || undefined,
    needs_review: needsReview || undefined,
    search: app.search || undefined,
    sort: sortKey,
    direction: sortDir,
    limit: LIMIT,
    offset,
  }), [app.city, app.runId, types, listFlag, minInf, needsReview, app.search, sortKey, sortDir, offset]);

  const { data, loading } = useApi("/entities", query, [JSON.stringify(query)]);
  let rows = Array.isArray(data) ? data : [];

  // Client-side multi-type filter (server takes only one)
  if (types.size > 1) rows = rows.filter((e) => types.has(e.entity_type));

  const toggleType = (t) =>
    setTypes((prev) => {
      const next = new Set(prev);
      next.has(t) ? next.delete(t) : next.add(t);
      return next;
    });
  function setSort(k) {
    if (sortKey === k) setSortDir((d) => (d === "asc" ? "desc" : "asc"));
    else { setSortKey(k); setSortDir("desc"); }
  }

  return (
    <div style={dirStyles.root}>
      <aside style={dirStyles.rail}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          <MicroCap>Filters</MicroCap>
          <button
            className="vk-btn vk-btn--ghost"
            style={{ height: 22, padding: "0 6px", fontSize: 11 }}
            onClick={() => { setTypes(new Set()); setMinInf(0); setNeedsReview(false); }}
          >
            reset
          </button>
        </div>

        <FilterGroup label="Entity type">
          {ENTITY_TYPES.map((t) => (
            <Checkbox key={t} checked={types.has(t)} onChange={() => toggleType(t)} label={t} />
          ))}
        </FilterGroup>

        <FilterGroup label="Min influence" open>
          <input
            type="range" min="0" max="100" step="5" value={minInf}
            onChange={(e) => setMinInf(+e.target.value)}
            style={{ width: "100%", accentColor: "#E91E63" }}
          />
          <div style={{ fontSize: 11, color: "var(--vk-text-tertiary)", fontFamily: "var(--vk-font-mono)" }}>
            ≥ {minInf}
          </div>
        </FilterGroup>

        <FilterGroup label="Flags" open>
          <Checkbox checked={needsReview} onChange={setNeedsReview} label="Needs review" />
        </FilterGroup>
      </aside>

      <div style={dirStyles.table}>
        <div style={{ display: "flex", alignItems: "baseline", marginBottom: 12, gap: 12 }}>
          <h2 style={{ margin: 0, fontSize: 18, fontWeight: 500 }}>{title || "Entity directory"}</h2>
          <span style={{ fontSize: 11, color: "var(--vk-text-tertiary)" }}>
            {loading ? "loading…" : `${rows.length} entities`}
          </span>
          <div style={{ flex: 1 }} />
          <button className="vk-btn"><Icon name="Download" size={14} /> Export</button>
        </div>

        {loading ? <SkeletonBlock rows={8} /> : rows.length === 0 ? (
          <EmptyState icon="SearchX" title="No entities match these filters." hint="Try resetting filters or switching run." />
        ) : (
          <table style={dirStyles.tableInner}>
            <thead>
              <tr>
                {[
                  ["canonical_name", "Name", "left"],
                  ["entity_type", "Type", "left"],
                  ["sector_or_focus", "Sector", "left"],
                  ["influence_score", "Infl.", "right"],
                  ["relevance_score", "Relev.", "right"],
                  ["risk_score", "Risk", "right"],
                  ["confidence_score", "Conf.", "right"],
                  ["source_count", "Sources", "right"],
                ].map(([k, lbl, align]) => (
                  <th key={k} style={{ ...dirStyles.th, textAlign: align }} onClick={() => setSort(k)}>
                    {lbl}
                    {sortKey === k && <Icon name={sortDir === "asc" ? "ArrowUp" : "ArrowDown"} size={12} style={{ marginLeft: 4 }} />}
                  </th>
                ))}
              </tr>
            </thead>
            <tbody>
              {rows.map((e) => (
                <tr
                  key={e.entity_id}
                  onClick={() => openEntity(e)}
                  style={{ cursor: "pointer" }}
                  onMouseEnter={(ev) => (ev.currentTarget.style.background = "var(--vk-surface-2)")}
                  onMouseLeave={(ev) => (ev.currentTarget.style.background = "transparent")}
                >
                  <td style={dirStyles.td}>
                    <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                      {e.entity_type === "person" && <Avatar name={e.canonical_name} size={22} />}
                      <span style={{ fontWeight: 500 }}>{e.canonical_name}</span>
                      {e.needs_review && <Icon name="Flag" size={13} color="var(--vk-warning)" />}
                    </div>
                  </td>
                  <td style={{ ...dirStyles.td, color: "var(--vk-text-secondary)" }}>{e.entity_type}</td>
                  <td style={{ ...dirStyles.td, color: "var(--vk-text-secondary)" }}>{e.sector_or_focus}</td>
                  <td style={{ ...dirStyles.td, textAlign: "right" }}><Score value={e.influence_score} /></td>
                  <td style={{ ...dirStyles.td, textAlign: "right" }}><Score value={e.relevance_score} /></td>
                  <td style={{ ...dirStyles.td, textAlign: "right" }}><Score value={e.risk_score} riskScale /></td>
                  <td style={{ ...dirStyles.td, textAlign: "right" }}><Score value={e.confidence_score} /></td>
                  <td style={{ ...dirStyles.td, textAlign: "right", color: "var(--vk-text-secondary)" }} className="vk-mono">{e.source_count}</td>
                </tr>
              ))}
            </tbody>
          </table>
        )}

        {rows.length >= LIMIT && (
          <div style={{ display: "flex", justifyContent: "center", alignItems: "center", gap: 10, padding: 14, fontSize: 11, color: "var(--vk-text-tertiary)" }}>
            <button className="vk-btn" disabled={offset === 0} onClick={() => setOffset(Math.max(0, offset - LIMIT))}>Prev</button>
            <span>{offset + 1}–{offset + rows.length}</span>
            <button className="vk-btn" onClick={() => setOffset(offset + LIMIT)}>Next 50</button>
          </div>
        )}
      </div>
    </div>
  );
}

Object.assign(window, { EntityDirectory, Checkbox, FilterGroup });
