// hooks.jsx — useApi (data fetching hook), useApiMode (preview/live banner),
// AppState context (city / run / search).

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

const { createContext: _cc, useContext: _uc } = React;

// ---- useApi -----------------------------------------------------------
function useApi(path, query, deps) {
  // path: e.g. "/entities" or "/entities/ent_xyz"
  // query: object of querystring params
  // deps: array — extra dependencies that should retrigger the fetch
  const [state, setState] = useState({ data: null, error: null, loading: true });
  const cacheKey = path + "?" + JSON.stringify(query || {});

  useEffect(() => {
    let cancelled = false;
    setState((s) => ({ ...s, loading: true, error: null }));
    window.VK_API.fetchPath(path, query)
      .then((data) => { if (!cancelled) setState({ data, error: null, loading: false }); })
      .catch((err) => { if (!cancelled) setState({ data: null, error: err, loading: false }); });
    return () => { cancelled = true; };
    // eslint-disable-next-line
  }, [cacheKey, ...(deps || [])]);

  return state;
}

// ---- useApiMode -------------------------------------------------------
function useApiMode() {
  const [mode, setMode] = useState(window.__VK_API_MODE || "loading");
  useEffect(() => {
    function onChange(ev) { setMode(ev.detail.mode); }
    window.addEventListener("vk-api-mode", onChange);
    return () => window.removeEventListener("vk-api-mode", onChange);
  }, []);
  return mode;
}

// ---- AppState context -------------------------------------------------
const AppCtx = _cc(null);
function AppStateProvider({ children, initialCity = "Philadelphia" }) {
  const [city, setCity] = useState(initialCity);
  const [runId, setRunId] = useState(null);
  const [runLabel, setRunLabel] = useState("Latest");
  const [search, setSearch] = useState("");

  return (
    <AppCtx.Provider value={{ city, setCity, runId, setRunId, runLabel, setRunLabel, search, setSearch }}>
      {children}
    </AppCtx.Provider>
  );
}
function useAppState() { return _uc(AppCtx); }

// ---- Empty state ------------------------------------------------------
function EmptyState({ icon = "Inbox", title, hint }) {
  return (
    <div style={{
      display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center",
      gap: 8, padding: 32, color: "var(--vk-text-tertiary)",
    }}>
      <Icon name={icon} size={28} />
      <div style={{ fontSize: 13, color: "var(--vk-text-secondary)" }}>{title}</div>
      {hint && <div style={{ fontSize: 11, color: "var(--vk-text-tertiary)" }}>{hint}</div>}
    </div>
  );
}

// ---- Skeleton ---------------------------------------------------------
function SkeletonRow({ height = 16, width = "100%" }) {
  return (
    <div style={{
      height, width,
      background: "var(--vk-surface-2)",
      borderRadius: 3,
      opacity: 0.5,
    }}></div>
  );
}
function SkeletonBlock({ rows = 4 }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 8, padding: 8 }}>
      {Array.from({ length: rows }).map((_, i) => (
        <SkeletonRow key={i} height={14} width={`${80 - i * 6}%`} />
      ))}
    </div>
  );
}

// ---- Format helpers ---------------------------------------------------
function fmtDate(iso) {
  if (!iso) return "";
  const d = new Date(iso);
  return d.toLocaleDateString("en-US", { month: "short", day: "numeric" });
}
function fmtRunLabel(iso) {
  if (!iso) return "Latest run";
  const d = new Date(iso);
  return "Week of " + d.toLocaleDateString("en-US", { month: "short", day: "numeric" });
}

Object.assign(window, {
  useApi, useApiMode,
  AppStateProvider, useAppState, AppCtx,
  EmptyState, SkeletonRow, SkeletonBlock,
  fmtDate, fmtRunLabel,
});
