const { useState: US, useMemo: UM } = React;

function toJST(dateStr) {
  if (!dateStr) return "";
  var d = new Date(dateStr);
  return (
    d.toLocaleString("en-US", {
      timeZone: "Asia/Tokyo",
      month: "short",
      day: "numeric",
      hour: "2-digit",
      minute: "2-digit",
      hour12: false,
    }) + " JST"
  );
}

// Health status: green = fresh, yellow = stale, red = dead
function healthColor(dateStr, maxMinutes) {
  if (!dateStr) return "#ef4444"; // red — no data
  var age = (Date.now() - new Date(dateStr).getTime()) / 60000;
  if (age <= maxMinutes) return "#22c55e"; // green — on time
  if (age <= maxMinutes * 3) return "#f59e0b"; // yellow — late
  return "#ef4444"; // red — dead
}
function HealthDot({ dateStr, maxMinutes, label }) {
  var color = healthColor(dateStr, maxMinutes);
  var age = dateStr
    ? Math.floor((Date.now() - new Date(dateStr).getTime()) / 60000)
    : -1;
  var title =
    label +
    ": " +
    (age < 0
      ? "no data"
      : age < 60
        ? age + "m ago"
        : Math.floor(age / 60) + "h ago");
  return (
    <span
      title={title}
      style={{
        display: "inline-block",
        width: 8,
        height: 8,
        borderRadius: "50%",
        background: color,
        marginRight: 4,
        verticalAlign: "middle",
        boxShadow: color === "#22c55e" ? "0 0 6px " + color : "none",
        animation: color === "#22c55e" ? "pulse 2s infinite" : "none",
      }}
    />
  );
}

function App() {
  const [view, setView] = US("registry");
  const [selectedHook, setSelectedHook] = US(null);
  const [chainFilter, setChainFilter] = US("all");
  const [query, setQuery] = US("");
  const [focusFilter, setFocusFilter] = US("all"); // all|has_token|mcap_1m|audited|gem7

  const hooks = window.HOOKS || [];
  const chains = window.CHAIN_STATS || [];
  const summary = window.SUMMARY || {};

  // Pre-compute focus counts
  const focusCounts = UM(
    () => ({
      has_token: hooks.filter((h) => h.topToken && h.topToken.priceUSD > 0)
        .length,
      mcap_1m: hooks.filter((h) => h.topToken && h.topToken.mcapUSD > 1e6)
        .length,
      audited: hooks.filter((h) => h.auditUrl).length,
      gem7: hooks.filter((h) => h.gemScore >= 7).length,
      pending: hooks.filter((h) => h.registryStatus === "pending").length,
      live: hooks.filter((h) => h.registryStatus === "merged").length,
    }),
    [hooks],
  );

  const openHook = (hook) => {
    setSelectedHook(hook);
    setView("detail");
  };

  return (
    <div className="app">
      <div className="header">
        <div style={{ display: "flex", alignItems: "center" }}>
          <div className="header-brand">
            Hook<span>Monitor</span>
          </div>
          <div className="header-sub">Uniswap v4 Hook Registry</div>
        </div>
        <div className="header-nav">
          <button
            className={
              "nav-btn" +
              (view === "registry" || view === "detail" ? " on" : "")
            }
            onClick={() => {
              setView("registry");
              setSelectedHook(null);
            }}
          >
            Registry
          </button>
          <button
            className={"nav-btn" + (view === "gems" ? " on" : "")}
            onClick={() => setView("gems")}
          >
            Gem Radar
          </button>
        </div>
        <div className="header-stats">
          <span>
            <b>{summary.total_hooks || 0}</b> hooks
          </span>
          <span>
            <b>{summary.total_chains || 0}</b> chains
          </span>
          <span
            style={{
              borderLeft: "1px solid var(--line)",
              paddingLeft: 12,
              marginLeft: 4,
            }}
          >
            <HealthDot
              dateStr={summary.updated_at}
              maxMinutes={30}
              label="Hook registry (cron, every 15m)"
            />
            Hooks <b>{summary.updated_at ? toJST(summary.updated_at) : "—"}</b>
          </span>
          <span>
            <HealthDot
              dateStr={window.LIVE_PRICES && window.LIVE_PRICES.updatedAt}
              maxMinutes={1}
              label="Live prices (DexScreener, every 10s)"
            />
            Prices{" "}
            <b>
              {window.LIVE_PRICES && window.LIVE_PRICES.updatedAt
                ? toJST(window.LIVE_PRICES.updatedAt)
                : "—"}
            </b>
          </span>
          <span>
            ETH{" "}
            <b>
              $
              {(
                (window.LIVE_PRICES && window.LIVE_PRICES.ethUsd) ||
                (window.LIVE_PRICES && window.LIVE_PRICES.ethUSD) ||
                0
              ).toLocaleString()}
            </b>
          </span>
        </div>
      </div>

      <div className="main-content">
        {/* Stats bar */}
        {view === "registry" && !selectedHook && (
          <>
            <div className="stats-bar">
              <div className="stat-card">
                <div className="stat-value">{summary.total_hooks || 0}</div>
                <div className="stat-label">Total Hooks</div>
              </div>
              <div className="stat-card">
                <div className="stat-value" style={{ color: "var(--up)" }}>
                  {summary.audited || 0}
                </div>
                <div className="stat-label">Audited</div>
              </div>
              <div className="stat-card">
                <div className="stat-value" style={{ color: "var(--accent)" }}>
                  {summary.total_pools || 0}
                </div>
                <div className="stat-label">Pools Found</div>
              </div>
              <div className="stat-card">
                <div className="stat-value" style={{ color: "var(--gem)" }}>
                  {summary.gems || 0}
                </div>
                <div className="stat-label">Gems (5+)</div>
              </div>
              <div className="stat-card">
                <div className="stat-value">{summary.verified || 0}</div>
                <div className="stat-label">Verified Source</div>
              </div>
            </div>

            {/* Chain filter */}
            <div className="chain-bars">
              <div
                className={"chain-bar" + (chainFilter === "all" ? " on" : "")}
                onClick={() => setChainFilter("all")}
              >
                <span className="chain-count">All ({hooks.length})</span>
              </div>
              {chains.map((c) => (
                <div
                  key={c.chain}
                  className={
                    "chain-bar" + (chainFilter === c.chain ? " on" : "")
                  }
                  onClick={() =>
                    setChainFilter(chainFilter === c.chain ? "all" : c.chain)
                  }
                >
                  <span className="chain-dot" style={{ background: c.color }} />
                  <span>{c.chain}</span>
                  <span className="chain-count">{c.count}</span>
                </div>
              ))}
            </div>

            {/* Focus filters — cut through the noise */}
            <div className="chain-bars" style={{ marginBottom: 12 }}>
              {[
                { key: "all", label: "All", count: hooks.length },
                {
                  key: "gem7",
                  label: "Top Gems (7+)",
                  count: focusCounts.gem7,
                  color: "var(--gem)",
                },
                {
                  key: "mcap_1m",
                  label: "MCap >$1M",
                  count: focusCounts.mcap_1m,
                  color: "var(--up)",
                },
                {
                  key: "has_token",
                  label: "Has Token",
                  count: focusCounts.has_token,
                  color: "var(--accent)",
                },
                {
                  key: "audited",
                  label: "Audited",
                  count: focusCounts.audited,
                  color: "var(--up)",
                },
                {
                  key: "pending",
                  label: "Pending PRs",
                  count: focusCounts.pending,
                  color: "var(--warn)",
                },
              ].map((f) => (
                <div
                  key={f.key}
                  className={"chain-bar" + (focusFilter === f.key ? " on" : "")}
                  onClick={() =>
                    setFocusFilter(focusFilter === f.key ? "all" : f.key)
                  }
                >
                  <span style={{ color: f.color }}>{f.label}</span>
                  <span className="chain-count">{f.count}</span>
                </div>
              ))}
            </div>

            {/* Search */}
            <div className="search-bar">
              <input
                className="search-input"
                placeholder="Search hooks by name, address, or description..."
                value={query}
                onChange={(e) => setQuery(e.target.value)}
              />
            </div>
          </>
        )}

        {/* Views */}
        {view === "detail" && selectedHook ? (
          <HookDetail
            hook={selectedHook}
            onBack={() => {
              setSelectedHook(null);
              setView("registry");
            }}
          />
        ) : view === "gems" ? (
          <GemRadar onSelect={openHook} />
        ) : (
          <HooksTable
            hooks={hooks}
            chainFilter={chainFilter}
            focusFilter={focusFilter}
            query={query}
            onSelect={openHook}
          />
        )}
      </div>

      <div className="footer">
        Hook Monitor · Uniswap v4 · {summary.total_hooks || 0} hooks across{" "}
        {summary.total_chains || 0} chains
        {summary.updated_at && (
          <span> · Data: {toJST(summary.updated_at)}</span>
        )}
        {window.LIVE_PRICES && window.LIVE_PRICES.updatedAt && (
          <span> · Prices: {toJST(window.LIVE_PRICES.updatedAt)}</span>
        )}
      </div>
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById("root"));
if (window._dataLoaded) {
  window._dataLoaded.then(() => root.render(<App />));
} else {
  root.render(<App />);
}
