"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import { useRouter } from "next/navigation";

import { SignalLineChart } from "@/components/line-chart";
import { SectionHeading } from "@/components/section-heading";
import { StatusBadge } from "@/components/status-badge";
import { addWidgetToDashboards } from "@/lib/dashboards";
import { getOptionsDashboardSeries } from "@/lib/api/client";
import { formatMetricValue, formatTimestamp } from "@/lib/format";
import { rangeWindowIso, seriesMaxPoints } from "@/lib/ranges";
import type { OptionsDashboardResponse, OptionsDashboardSummary } from "@/lib/api/types";
import { useStream } from "@/lib/ws/use-stream";

import { OPTIONS_DASHBOARDS } from "./options-config";

function fmtVal(v: unknown): string {
  if (v == null) return "—";
  if (typeof v === "number") return formatMetricValue(v);
  return String(v);
}

function labelize(key: string) {
  return key
    .replace(/_/g, " ")
    .replace(/\b\w/g, (m) => m.toUpperCase());
}

export function OptionsList({ dashboards }: { dashboards: OptionsDashboardSummary[] }) {
  const router = useRouter();

  // Multi-pin state
  const [pinnedIds, setPinnedIds] = useState<Set<string>>(new Set());
  const [seriesMap, setSeriesMap] = useState<Map<string, OptionsDashboardResponse>>(new Map());
  const [underlyingMap, setUnderlyingMap] = useState<Map<string, string>>(() => {
    const m = new Map<string, string>();
    for (const d of dashboards) {
      m.set(d.id, d.supported_underlyings[0] ?? "BTC");
    }
    return m;
  });
  const [loadingIds, setLoadingIds] = useState<Set<string>>(new Set());
  const requestIdsRef = useRef<Map<string, number>>(new Map());
  const abortControllersRef = useRef<Map<string, AbortController>>(new Map());

  const pinnedRef = useRef(pinnedIds);
  pinnedRef.current = pinnedIds;
  const underlyingRef = useRef(underlyingMap);
  underlyingRef.current = underlyingMap;

  const fetchSeries = useCallback(async (dashboardId: string, underlying: string) => {
    abortControllersRef.current.get(dashboardId)?.abort();
    const controller = new AbortController();
    abortControllersRef.current.set(dashboardId, controller);
    const requestId = (requestIdsRef.current.get(dashboardId) ?? 0) + 1;
    requestIdsRef.current.set(dashboardId, requestId);
    setLoadingIds((prev) => new Set(prev).add(dashboardId));
    const config = OPTIONS_DASHBOARDS.find((c) => c.id === dashboardId);
    const ul = config && supportsUnderlying(config.id) ? underlying : undefined;
    const latestUpdatedAt = dashboards.find((dashboard) => dashboard.id === dashboardId)?.latest_updated_at;
    const { start, end } = rangeWindowIso(1, latestUpdatedAt);
    const result = await getOptionsDashboardSeries(
      dashboardId,
      ul,
      start,
      end,
      undefined,
      seriesMaxPoints(1),
      controller.signal,
    );
    if (!controller.signal.aborted && requestIdsRef.current.get(dashboardId) === requestId && result) {
      setSeriesMap((prev) => new Map(prev).set(dashboardId, result));
    }
    if (abortControllersRef.current.get(dashboardId) === controller) {
      abortControllersRef.current.delete(dashboardId);
    }
    if (requestIdsRef.current.get(dashboardId) === requestId) {
      setLoadingIds((prev) => {
        const next = new Set(prev);
        next.delete(dashboardId);
        return next;
      });
    }
  }, [dashboards]);

  const togglePin = useCallback((dashboard: OptionsDashboardSummary) => {
    setPinnedIds((prev) => {
      const next = new Set(prev);
      if (next.has(dashboard.id)) {
        next.delete(dashboard.id);
      } else {
        next.add(dashboard.id);
        const ul = underlyingRef.current.get(dashboard.id) ?? dashboard.supported_underlyings[0] ?? "BTC";
        void fetchSeries(dashboard.id, ul);
      }
      return next;
    });
  }, [fetchSeries]);

  const changeUnderlying = useCallback((dashboardId: string, underlying: string) => {
    setUnderlyingMap((prev) => new Map(prev).set(dashboardId, underlying));
    void fetchSeries(dashboardId, underlying);
  }, [fetchSeries]);

  useEffect(() => {
    return () => {
      for (const controller of abortControllersRef.current.values()) {
        controller.abort();
      }
      abortControllersRef.current.clear();
    };
  }, []);

  // Live refresh pinned charts
  useStream((event) => {
    if (event.event === "dataset.updated" || event.event === "signal.updated") {
      for (const id of pinnedRef.current) {
        const ul = underlyingRef.current.get(id) ?? "BTC";
        void fetchSeries(id, ul);
      }
    }
  });

  // Get pinned dashboards in display order
  const pinnedDashboards = dashboards.filter((d) => pinnedIds.has(d.id));

  return (
    <div className="pageStack">
      <SectionHeading
        kicker="Options"
        title="Options analytics workbench"
        description="Click rows to pin charts. Double-click to open workspace."
      />

      <div className="panel">
        <div className="panelHeader">
          <h3>Dashboards</h3>
          <span style={{ fontSize: 11, color: "var(--text-dim)" }}>
            click to pin chart · double-click for workspace
          </span>
        </div>
        <div className="tableWrap">
          <table className="dataTable">
            <thead>
              <tr>
                <th style={{ width: 28 }}></th>
                <th>Dashboard</th>
                <th>Assets</th>
                <th>Primary</th>
                <th>Secondary</th>
                <th>Tertiary</th>
                <th>Quality</th>
                <th>Updated</th>
                <th>Dashboards</th>
              </tr>
            </thead>
            <tbody>
              {dashboards.map((dashboard) => {
                const entries = Object.entries(dashboard.latest_values ?? {}).slice(0, 3);
                const isPinned = pinnedIds.has(dashboard.id);
                return (
                  <tr
                    key={dashboard.id}
                    className={`rowClickable ${isPinned ? "rowActive" : ""}`}
                    onClick={() => togglePin(dashboard)}
                    onDoubleClick={() => router.push(`/options/${dashboard.id}`)}
                  >
                    <td>
                      <span style={{
                        display: "inline-block",
                        width: 8,
                        height: 8,
                        borderRadius: 2,
                        background: isPinned ? "var(--accent)" : "transparent",
                        border: isPinned ? "none" : "1px solid var(--text-dim)",
                        transition: "background 120ms",
                      }} />
                    </td>
                    <td><strong>{dashboard.name}</strong></td>
                    <td>{dashboard.supported_underlyings.join(", ") || "BTC/ETH"}</td>
                    <td>
                      {entries[0] ? `${labelize(entries[0][0])}: ${fmtVal(entries[0][1])}` : "—"}
                    </td>
                    <td>
                      {entries[1] ? `${labelize(entries[1][0])}: ${fmtVal(entries[1][1])}` : "—"}
                    </td>
                    <td>
                      {entries[2] ? `${labelize(entries[2][0])}: ${fmtVal(entries[2][1])}` : "—"}
                    </td>
                    <td>
                      <StatusBadge
                        label={dashboard.latest_quality ?? "unknown"}
                        tone={dashboard.latest_quality === "ok" ? "ok" : "warn"}
                      />
                    </td>
                    <td>{formatTimestamp(dashboard.latest_updated_at)}</td>
                    <td>
                      <button
                        className="tabItem"
                        onClick={(event) => {
                          event.stopPropagation();
                          addWidgetToDashboards({
                            kind: "chart",
                            family: "options",
                            sourceId: dashboard.id,
                            title: dashboard.name,
                            filters: supportsUnderlying(dashboard.id)
                              ? { underlying: dashboard.supported_underlyings[0] ?? "BTC" }
                              : {},
                            colSpan: 6,
                            rowSpan: 1,
                          });
                        }}
                      >
                        add
                      </button>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>

      {/* ── Pinned Charts ── */}
      {pinnedDashboards.length > 0 && (
        <div className="chartGrid">
          {pinnedDashboards.map((dashboard) => {
            const series = seriesMap.get(dashboard.id);
            const config = OPTIONS_DASHBOARDS.find((c) => c.id === dashboard.id);
            const currentUnderlying = underlyingMap.get(dashboard.id) ?? "BTC";
            const isLoading = loadingIds.has(dashboard.id);
            const isCrossAsset = config ? !supportsUnderlying(config.id) : false;

            const chartData = (series?.points ?? []).map((p) => ({
              ts: p.ts,
              ...p.values,
            }));

            return (
              <div key={dashboard.id} className="panel">
                <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 8 }}>
                  <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                    <h3 style={{ margin: 0, fontSize: "0.82rem", fontWeight: 600 }}>
                      {dashboard.name}
                    </h3>
                    {isLoading && <span className="fetchingIndicator">loading</span>}
                  </div>
                  <div style={{ display: "flex", alignItems: "center", gap: 4 }}>
                    {!isCrossAsset && (
                      <div className="tabBar" style={{ borderBottom: "none", marginBottom: 0 }}>
                        {dashboard.supported_underlyings.map((ul) => (
                          <button
                            key={ul}
                            className={`tabItem ${ul === currentUnderlying ? "tabActive" : ""}`}
                            onClick={() => changeUnderlying(dashboard.id, ul)}
                          >
                            {ul}
                          </button>
                        ))}
                      </div>
                    )}
                    <button
                      onClick={(e) => {
                        e.stopPropagation();
                        router.push(`/options/${dashboard.id}`);
                      }}
                      style={{
                        background: "none",
                        border: "1px solid var(--border)",
                        borderRadius: 3,
                        color: "var(--accent)",
                        cursor: "pointer",
                        padding: "3px 8px",
                        fontSize: 11,
                        fontFamily: "var(--font-mono)",
                      }}
                      title="Open workspace"
                    >
                      open
                    </button>
                    <button
                      onClick={() => togglePin(dashboard)}
                      style={{
                        background: "none",
                        border: "1px solid var(--border)",
                        borderRadius: 3,
                        color: "var(--text-dim)",
                        cursor: "pointer",
                        padding: "3px 8px",
                        fontSize: 11,
                        fontFamily: "var(--font-mono)",
                      }}
                      title="Unpin chart"
                    >
                      ✕
                    </button>
                  </div>
                </div>
                <SignalLineChart
                  data={chartData}
                  lines={config?.lines ?? []}
                  dualAxis={config?.dualAxis}
                  height={pinnedDashboards.length > 2 ? 280 : 380}
                />
              </div>
            );
          })}
        </div>
      )}

      {pinnedDashboards.length === 0 && (
        <div className="panel" style={{ textAlign: "center", padding: "24px 12px" }}>
          <p style={{ color: "var(--text-dim)", fontSize: 12, margin: 0 }}>
            Click dashboards above to pin charts here
          </p>
        </div>
      )}
    </div>
  );
}

function supportsUnderlying(dashboardId: string) {
  return !["cross_asset_rv", "btc_eth_dispersion"].includes(dashboardId);
}
