/**
 * NightboardSmall — the /small kiosk dashboard, Nightboard style.
 *
 * Designed for the office panel: 10.1" 1920×1200 at 1× CSS scale, read from
 * across the room. Hierarchy comes from scale and spacing, not cards — sizes
 * below are tuned to that fixed viewport, so no transform-scale hacks.
 * Data hooks mirror the retired Mini* components one-to-one; only the
 * presentation changed (weather/calendar dropped, clock lives in the top line).
 */
import React, { useEffect, useRef, useState } from "react";
import { useQuery } from "@tanstack/react-query";
import {
  AreaChart,
  Area,
  XAxis,
  YAxis,
  Tooltip,
  ResponsiveContainer,
} from "recharts";
import { acotService } from "@/services/dashboard/acotService";
import { apiClient } from "@/utils/apiClient";
import { apiFetch } from "@/utils/api";
import config from "@/config";
import { PHASE_CONFIG, PHASE_KEYS_WITH_UNKNOWN as PHASE_KEYS } from "@/utils/lifecyclePhases";
// @ts-expect-error - JSX module without type declarations
import { processBasicData } from "@/components/dashboard/RealtimeAnalytics";
// @ts-expect-error - JSX module without type declarations
import { EventDialog } from "@/components/dashboard/EventFeed.jsx";
import LockButton from "@/components/dashboard/LockButton";

// ── palette (Nightboard) ─────────────────────────────────────────────────────
const NB = {
  bg: "#0e1420",
  txt: "#e6ebf4",
  mut: "#8292a8",
  faint: "#46536b",
  line: "#1d2738",
  amberText: "#ffb454", // large type only
  amber: "#c9822a", // chart marks (CVD-validated on this ground)
  up: "#58b98a",
  dn: "#d4707c",
  card: "#131b2c",
} as const;

// ── formatters ───────────────────────────────────────────────────────────────
const fmtMoney = (v: number | null | undefined) =>
  v == null || isNaN(v)
    ? "—"
    : new Intl.NumberFormat("en-US", {
        style: "currency",
        currency: "USD",
        maximumFractionDigits: 0,
      }).format(v);

const fmtCompact = (v: number | null | undefined) => {
  if (v == null || isNaN(v)) return "—";
  if (Math.abs(v) >= 1_000_000) return `$${(v / 1_000_000).toFixed(2)}M`;
  if (Math.abs(v) >= 1_000) return `$${(v / 1_000).toFixed(0)}K`;
  return `$${Math.round(v)}`;
};

const fmtCount = (v: number | null | undefined) => {
  if (v == null || isNaN(v)) return "—";
  if (v >= 10_000) return `${(v / 1_000).toFixed(1)}K`;
  return v.toLocaleString();
};

const trendPct = (cur: number, prev: number) =>
  prev > 0 ? ((cur - prev) / prev) * 100 : null;

// ── tiny presentational atoms ────────────────────────────────────────────────
const Lbl = ({ children }: { children: React.ReactNode }) => (
  <div
    className="text-[15px] font-medium uppercase"
    style={{ color: NB.mut, letterSpacing: "0.22em" }}
  >
    {children}
  </div>
);

const TrendArrow = ({ pct, invert = false }: { pct: number | null; invert?: boolean }) => {
  if (pct == null || Math.abs(pct) < 0.1) return null;
  const good = invert ? pct < 0 : pct > 0;
  return (
    <span style={{ color: good ? NB.up : NB.dn }}>
      {pct > 0 ? "▲" : "▼"} {Math.abs(pct).toFixed(1)}%
    </span>
  );
};

// ── metric ids for the event feed (same Klaviyo metrics as MiniEventFeed) ────
const METRIC_IDS = {
  PLACED_ORDER: "Y8cqcF",
  SHIPPED_ORDER: "VExpdL",
  ACCOUNT_CREATED: "TeeypV",
  CANCELED_ORDER: "YjVMNg",
  NEW_BLOG_POST: "YcxeDr",
  PAYMENT_REFUNDED: "R7XUYh",
} as const;

const EVENT_META: Record<string, { label: string; dot: string }> = {
  [METRIC_IDS.PLACED_ORDER]: { label: "Order", dot: NB.up },
  [METRIC_IDS.SHIPPED_ORDER]: { label: "Shipped", dot: "#5580d0" },
  [METRIC_IDS.ACCOUNT_CREATED]: { label: "Account", dot: "#8f7ad6" },
  [METRIC_IDS.CANCELED_ORDER]: { label: "Canceled", dot: NB.dn },
  [METRIC_IDS.PAYMENT_REFUNDED]: { label: "Refund", dot: "#e0a15a" },
  [METRIC_IDS.NEW_BLOG_POST]: { label: "Blog", dot: NB.mut },
};

const fmtEventMoney = (amount: string | number | undefined) => {
  const num = typeof amount === "string" ? parseFloat(amount) : amount;
  if (num == null || isNaN(num)) return "";
  return `${num < 0 ? "-" : ""}$${Math.abs(num).toFixed(2)}`;
};

const shipMethod = (method: string | undefined) => {
  if (!method) return "Digital";
  if (method.includes("usps")) return "USPS";
  if (method.includes("fedex")) return "FedEx";
  if (method.includes("ups")) return "UPS";
  return "Standard";
};

interface EventProps {
  ShippingName?: string;
  OrderId?: string | number;
  TotalAmount?: string | number;
  IsOnHold?: boolean;
  StillOwes?: boolean;
  LocalPickup?: boolean;
  HasPreorder?: boolean;
  ShipMethod?: string;
  ShippedBy?: string;
  FirstName?: string;
  LastName?: string;
  EmailAddress?: string;
  CancelReason?: string;
  FromOrder?: string | number;
  PaymentAmount?: string | number;
  PaymentName?: string;
  title?: string;
  description?: string;
}

interface FeedEvent {
  id: string;
  metric_id: string;
  datetime?: string;
  attributes?: { datetime?: string; event_properties?: EventProps };
  event_properties: EventProps;
}

interface PhaseSlice {
  phase: string;
  revenue: number;
  percentage: number;
}

// ── response shapes (acotService is untyped JS; these mirror what the API returns) ──
interface TodayStats {
  revenue: number;
  orderCount: number;
  itemCount: number;
  averageOrderValue: number;
  averageItemsPerOrder: number;
  periodProgress: number;
  prevPeriodRevenue: number;
  prevPeriodOrders: number;
  prevPeriodAOV: number;
  projectedRevenue?: number;
}

interface Projection {
  projectedRevenue?: number;
  projectedOrders?: number;
}

interface DailyRow {
  revenue?: number;
  orders?: number;
  prevRevenue?: number;
  prevOrders?: number;
  periodProgress?: number;
}

interface FinancialsResponse {
  totals?: Record<string, number>;
  previousTotals?: Record<string, number>;
  comparison?: { margin?: { absolute?: number } };
}

// ── clock ────────────────────────────────────────────────────────────────────
const Clock = () => {
  const [now, setNow] = useState(() => new Date());
  useEffect(() => {
    const t = setInterval(() => setNow(new Date()), 10_000);
    return () => clearInterval(t);
  }, []);
  return (
    <span className="text-[17px]" style={{ color: NB.mut, letterSpacing: "0.06em" }}>
      {now.toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric" })}
      {" · "}
      <span style={{ color: NB.txt, fontWeight: 500 }}>
        {now.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" })}
      </span>
    </span>
  );
};

// ── main component ───────────────────────────────────────────────────────────
const NightboardSmall = () => {
  // Today stats (same source as MiniStatCards)
  const { data: stats } = useQuery({
    queryKey: ["nightboard-stats-today"],
    queryFn: async () => {
      const res = (await acotService.getStats({ timeRange: "today" })) as { stats: TodayStats };
      return res.stats;
    },
    refetchInterval: 60_000,
  });

  const { data: projection } = useQuery({
    queryKey: ["nightboard-projection-today"],
    queryFn: async () =>
      (await acotService.getProjection({ timeRange: "today" })) as Projection,
    enabled: stats != null && stats.periodProgress < 100,
    refetchInterval: 60_000,
  });

  const { data: realtime } = useQuery({
    queryKey: ["nightboard-realtime-users"],
    queryFn: async () => {
      const response = await apiFetch("/api/dashboard-analytics/realtime/basic", {
        credentials: "include",
      });
      if (!response.ok) throw new Error("Failed to fetch realtime");
      const result = await response.json();
      return processBasicData(result.data) as { last30MinUsers: number; last5MinUsers: number };
    },
    refetchInterval: 30_000,
  });

  // 30-day summary + avg/day (same source as MiniSalesChart / MiniBusinessMetrics)
  const { data: sum30 } = useQuery({
    queryKey: ["nightboard-stats-30d"],
    queryFn: async () => {
      const response = (await acotService.getStatsDetails({
        timeRange: "last30days",
        metric: "revenue",
        daily: true,
      })) as { stats?: DailyRow[] };
      const rows = Array.isArray(response.stats) ? response.stats : [];
      const t = rows.reduce<Required<DailyRow>>(
        (acc, day) => ({
          revenue: acc.revenue + (Number(day.revenue) || 0),
          orders: acc.orders + (Number(day.orders) || 0),
          prevRevenue: acc.prevRevenue + (Number(day.prevRevenue) || 0),
          prevOrders: acc.prevOrders + (Number(day.prevOrders) || 0),
          periodProgress: day.periodProgress || 100,
        }),
        { revenue: 0, orders: 0, prevRevenue: 0, prevOrders: 0, periodProgress: 100 }
      );
      const days = rows.length || 1;
      return {
        ...t,
        avgPerDay: t.revenue / days,
        prevAvgPerDay: t.prevRevenue / days,
      };
    },
    refetchInterval: 300_000,
  });

  const { data: projection30 } = useQuery({
    queryKey: ["nightboard-projection-30d"],
    queryFn: async () =>
      (await acotService.getProjection({ timeRange: "last30days" })) as Projection,
    enabled: sum30 != null && sum30.periodProgress < 100,
    refetchInterval: 300_000,
  });

  // 30-day chart + phase mix (same endpoint as MiniSalesChart)
  const { data: chartData } = useQuery({
    queryKey: ["nightboard-sales-chart-30d"],
    queryFn: async () => {
      const now = new Date();
      const thirtyDaysAgo = new Date(now);
      thirtyDaysAgo.setDate(now.getDate() - 30);
      const params = new URLSearchParams({
        startDate: thirtyDaysAgo.toISOString(),
        endDate: now.toISOString(),
      });
      const response = await apiFetch(`${config.apiUrl}/dashboard/sales/metrics?${params}`);
      if (!response.ok) throw new Error("Failed to fetch sales metrics");
      return response.json();
    },
    refetchInterval: 300_000,
  });

  // Business band (same sources as MiniBusinessMetrics)
  const { data: forecastData } = useQuery({
    queryKey: ["nightboard-forecast-30d"],
    queryFn: async () => {
      const response = await apiFetch(`${config.apiUrl}/dashboard/forecast/metrics`);
      if (!response.ok) throw new Error("Failed to fetch forecast");
      return response.json();
    },
    refetchInterval: 600_000,
  });

  const { data: yearData } = useQuery({
    queryKey: ["nightboard-year-estimate"],
    queryFn: async () => {
      const response = await apiFetch(`${config.apiUrl}/dashboard/year-revenue-estimate`);
      if (!response.ok) throw new Error("Failed to fetch year estimate");
      return response.json();
    },
    refetchInterval: 600_000,
  });

  const { data: financialData } = useQuery({
    queryKey: ["nightboard-financials-30d"],
    queryFn: async () =>
      (await acotService.getFinancials({ timeRange: "last30days" })) as FinancialsResponse,
    refetchInterval: 300_000,
  });

  const { data: fteData } = useQuery({
    queryKey: ["nightboard-fte-30d"],
    queryFn: async () =>
      // @ts-expect-error - acotService is a JS file, TypeScript can't infer the param type
      (await acotService.getEmployeeMetrics({ timeRange: "last30days" })) as {
        totals?: { fte?: number };
        previousTotals?: { fte?: number };
      },
    refetchInterval: 300_000,
  });

  // Ops / inventory band (same sources as MiniInventorySnapshot)
  const { data: opsData } = useQuery({
    queryKey: ["nightboard-ops-today"],
    queryFn: async () =>
      // @ts-expect-error - acotService is a JS file, TypeScript can't infer the param type
      (await acotService.getOperationsMetrics({ timeRange: "today" })) as {
        totals?: { ordersShipped?: number; piecesPicked?: number };
      },
    refetchInterval: 120_000,
  });

  const { data: stockData } = useQuery({
    queryKey: ["nightboard-stock-metrics"],
    queryFn: async () => {
      const response = await apiFetch(`${config.apiUrl}/dashboard/stock/metrics`);
      if (!response.ok) throw new Error("Failed to fetch stock metrics");
      return response.json();
    },
    refetchInterval: 300_000,
  });

  const { data: replenishData } = useQuery({
    queryKey: ["nightboard-replenish-metrics"],
    queryFn: async () => {
      const response = await apiFetch(`${config.apiUrl}/dashboard/replenishment/metrics`);
      if (!response.ok) throw new Error("Failed to fetch replenishment");
      return response.json();
    },
    refetchInterval: 300_000,
  });

  const { data: overstockData } = useQuery({
    queryKey: ["nightboard-overstock-metrics"],
    queryFn: async () => {
      const response = await apiFetch(`${config.apiUrl}/dashboard/overstock/metrics`);
      if (!response.ok) throw new Error("Failed to fetch overstock");
      return response.json();
    },
    refetchInterval: 300_000,
  });

  // Event feed (same source as MiniEventFeed)
  const { data: events = [] } = useQuery<FeedEvent[]>({
    queryKey: ["nightboard-event-feed"],
    queryFn: async () => {
      const response = await apiClient.get("/api/klaviyo/events/feed", {
        params: {
          timeRange: "today",
          metricIds: JSON.stringify(Object.values(METRIC_IDS)),
        },
      });
      return (response.data.data || []).map((event: FeedEvent) => ({
        ...event,
        datetime: event.attributes?.datetime || event.datetime,
        event_properties: event.attributes?.event_properties || {},
      }));
    },
    refetchInterval: 30_000,
  });

  const feedRef = useRef<HTMLDivElement>(null);
  useEffect(() => {
    if (feedRef.current && events.length > 0) {
      const el = feedRef.current;
      const t = setTimeout(
        () => el.scrollTo({ left: el.scrollWidth, behavior: "instant" as ScrollBehavior }),
        150
      );
      return () => clearTimeout(t);
    }
  }, [events]);

  // ── derived values ─────────────────────────────────────────────────────────
  const inProgress = stats != null && stats.periodProgress < 100;
  const projRevenue = projection?.projectedRevenue ?? stats?.projectedRevenue ?? null;
  const revTrend =
    stats && stats.prevPeriodRevenue > 0
      ? trendPct(
          inProgress ? projRevenue ?? stats.revenue : stats.revenue,
          stats.prevPeriodRevenue
        )
      : null;
  const projOrders =
    projection?.projectedOrders ??
    (stats && stats.periodProgress > 0
      ? Math.round(stats.orderCount / (stats.periodProgress / 100))
      : null);

  const rev30Current =
    sum30 && sum30.periodProgress < 100
      ? projection30?.projectedRevenue || sum30.revenue
      : sum30?.revenue;
  const rev30Trend = sum30 ? trendPct(rev30Current ?? 0, sum30.prevRevenue) : null;
  const orders30Current =
    sum30 && sum30.periodProgress < 100 && sum30.periodProgress > 0
      ? Math.round(sum30.orders * (100 / sum30.periodProgress))
      : sum30?.orders;
  const orders30Trend = sum30 ? trendPct(orders30Current ?? 0, sum30.prevOrders) : null;

  const dailyTotals: { date: string; total: number }[] = (chartData?.dailySalesByPhase || []).map(
    (day: { date: string } & Record<string, unknown>) => ({
      date: day.date,
      total: PHASE_KEYS.reduce((sum, key) => sum + (Number(day[key]) || 0), 0),
    })
  );
  const activePhases: PhaseSlice[] = (chartData?.phaseBreakdown || [])
    .filter((p: PhaseSlice) => p.revenue > 0)
    .sort((a: PhaseSlice, b: PhaseSlice) => b.revenue - a.revenue);

  // margin (same fallback math as MiniBusinessMetrics)
  let margin: number | null = null;
  let prevMargin: number | null = null;
  if (financialData?.totals) {
    const t = financialData.totals;
    if (Number.isFinite(t.margin)) margin = t.margin;
    else {
      const income = (t.grossSales || 0) - (t.refunds || 0) - (t.discounts || 0) + (t.shippingFees || 0);
      margin = income > 0 ? ((income - (t.cogs || 0)) / income) * 100 : 0;
    }
    const prev = financialData.previousTotals;
    if (prev) {
      if (Number.isFinite(prev.margin)) prevMargin = prev.margin;
      else {
        const pIncome =
          (prev.grossSales || 0) - (prev.refunds || 0) - (prev.discounts || 0) + (prev.shippingFees || 0);
        prevMargin = pIncome > 0 ? ((pIncome - (prev.cogs || 0)) / pIncome) * 100 : 0;
      }
    }
  }

  const fte = fteData?.totals?.fte ?? null;
  const prevFte = fteData?.previousTotals?.fte ?? null;
  const ops = opsData?.totals;

  const band: { label: string; value: string; sub: React.ReactNode; group?: boolean }[] = [
    {
      label: "Forecast 30d",
      value: fmtCompact(forecastData?.forecastRevenue),
      sub: yearData?.yearTotal != null ? `${fmtCompact(yearData.yearTotal)} for year` : "—",
    },
    {
      label: "Avg rev/day",
      value: sum30 ? fmtMoney(sum30.avgPerDay) : "—",
      sub: sum30 ? (
        <>
          prev {fmtMoney(sum30.prevAvgPerDay)}{" "}
          <TrendArrow pct={trendPct(sum30.avgPerDay, sum30.prevAvgPerDay)} />
        </>
      ) : (
        "—"
      ),
    },
    {
      label: "Margin",
      value: margin != null ? `${margin.toFixed(1)}%` : "—",
      sub:
        prevMargin != null && margin != null ? (
          <>
            prev {prevMargin.toFixed(1)}%{" "}
            <span style={{ color: margin >= prevMargin ? NB.up : NB.dn }}>
              {margin >= prevMargin ? "▲" : "▼"} {Math.abs(margin - prevMargin).toFixed(1)}pp
            </span>
          </>
        ) : (
          "—"
        ),
    },
    {
      label: "Payroll FTE",
      value: fte != null ? fte.toFixed(1) : "—",
      sub:
        prevFte != null && fte != null ? (
          <>
            prev {prevFte.toFixed(1)} <TrendArrow pct={trendPct(fte, prevFte)} invert />
          </>
        ) : (
          "—"
        ),
    },
    {
      label: "Shipped today",
      value: ops ? fmtCount(ops.ordersShipped) : "—",
      sub: ops ? `${fmtCount(ops.piecesPicked)} pcs picked` : "—",
      group: true,
    },
    {
      label: "Stock value",
      value: fmtCompact(stockData?.totalStockCost),
      sub: stockData ? `${fmtCount(stockData.productsInStock)} products` : "—",
    },
    {
      label: "Replenish",
      value: replenishData ? `${fmtCount(replenishData.unitsToReplenish)} u` : "—",
      sub: replenishData ? `${fmtCompact(replenishData.replenishmentCost)} cost` : "—",
    },
    {
      label: "Overstocked",
      value: overstockData ? fmtCount(overstockData.overstockedProducts) : "—",
      sub: overstockData ? `${fmtCompact(overstockData.totalExcessCost)} excess` : "—",
    },
  ];

  return (
    <div
      className="h-screen w-screen overflow-hidden grid grid-rows-[auto_auto_minmax(0,1fr)_auto_auto] grid-cols-[minmax(0,1fr)] px-12 pt-8"
      style={{
        background: `radial-gradient(1200px 500px at 25% -10%, rgba(22,32,50,0.45) 0%, transparent 60%), ${NB.bg}`,
        color: NB.txt,
        fontVariantNumeric: "tabular-nums",
      }}
    >
      {/* top line */}
      <div className="flex items-baseline justify-between pb-6">
        <span
          className="text-[16px] font-medium uppercase"
          style={{ color: NB.mut, letterSpacing: "0.3em" }}
        >
          A Cherry On Top
        </span>
        <div className="flex items-center gap-4">
          <Clock />
          <span className="opacity-30 hover:opacity-100 transition-opacity">
            <LockButton />
          </span>
        </div>
      </div>

      {/* hero metrics */}
      <div className="grid grid-cols-[1.5fr_1fr_1fr_1fr] gap-10 items-end pb-8">
        <div>
          <Lbl>Revenue today</Lbl>
          <div
            className="text-[104px] font-extralight leading-[0.95] mt-2"
            style={{ color: NB.amberText, letterSpacing: "-0.03em" }}
          >
            {fmtMoney(stats?.revenue)}
          </div>
          <div className="text-[18px] mt-3" style={{ color: NB.mut }}>
            {inProgress && projRevenue != null && (
              <>
                proj <span style={{ color: NB.txt, fontWeight: 500 }}>{fmtMoney(projRevenue)}</span>
                {" · "}
              </>
            )}
            <TrendArrow pct={revTrend} /> {revTrend != null && "vs last week"}
          </div>
        </div>
        <div>
          <Lbl>Orders</Lbl>
          <div className="text-[52px] font-light leading-none mt-2">
            {stats?.orderCount?.toLocaleString() ?? "—"}
          </div>
          <div className="text-[17px] mt-2" style={{ color: NB.mut }}>
            {projOrders != null && inProgress && (
              <>
                proj <span style={{ color: NB.txt, fontWeight: 500 }}>{projOrders}</span>
                {" · "}
              </>
            )}
            {stats?.itemCount != null ? `${fmtCount(stats.itemCount)} items` : ""}
          </div>
        </div>
        <div>
          <Lbl>Avg order</Lbl>
          <div className="text-[52px] font-light leading-none mt-2">
            {stats?.averageOrderValue != null ? `$${stats.averageOrderValue.toFixed(2)}` : "—"}
          </div>
          <div className="text-[17px] mt-2" style={{ color: NB.mut }}>
            {stats?.averageItemsPerOrder != null
              ? `${stats.averageItemsPerOrder.toFixed(1)} items / order`
              : ""}
          </div>
        </div>
        <div>
          <Lbl>On site now</Lbl>
          <div className="text-[52px] font-light leading-none mt-2 flex items-center gap-4">
            <span className="relative inline-flex h-3 w-3">
              <span
                className="absolute inline-flex h-full w-full rounded-full opacity-75 motion-safe:animate-ping"
                style={{ background: NB.up }}
              />
              <span className="relative inline-flex h-3 w-3 rounded-full" style={{ background: NB.up }} />
            </span>
            {realtime?.last5MinUsers ?? "—"}
          </div>
          <div className="text-[17px] mt-2" style={{ color: NB.mut }}>
            {realtime != null ? `${realtime.last30MinUsers} last 30 min` : ""}
          </div>
        </div>
      </div>

      {/* 30-day chart */}
      <div className="flex flex-col min-h-0 pt-4" style={{ borderTop: `1px solid ${NB.line}` }}>
        <div className="flex items-baseline justify-between pb-1">
          <Lbl>Last 30 days</Lbl>
          <span className="text-[17px]" style={{ color: NB.mut }}>
            Revenue <span style={{ color: NB.txt, fontWeight: 500 }}>{fmtCompact(sum30?.revenue)}</span>{" "}
            <TrendArrow pct={rev30Trend} />
            {"  ·  "}
            Orders <span style={{ color: NB.txt, fontWeight: 500 }}>{fmtCount(sum30?.orders)}</span>{" "}
            <TrendArrow pct={orders30Trend} />
          </span>
        </div>
        <div className="flex-1 min-h-0">
          <ResponsiveContainer width="100%" height="100%">
            <AreaChart data={dailyTotals} margin={{ top: 10, right: 4, left: 4, bottom: 0 }}>
              <defs>
                <linearGradient id="nbRevFill" x1="0" y1="0" x2="0" y2="1">
                  <stop offset="0%" stopColor={NB.amber} stopOpacity={0.28} />
                  <stop offset="100%" stopColor={NB.amber} stopOpacity={0} />
                </linearGradient>
              </defs>
              <XAxis
                dataKey="date"
                tickFormatter={(v: string) =>
                  new Date(v).toLocaleDateString([], { month: "numeric", day: "numeric" })
                }
                tick={{ fill: NB.mut, fontSize: 14 }}
                tickLine={false}
                axisLine={false}
                interval={5}
              />
              <YAxis
                tickFormatter={(v: number) => fmtCompact(v)}
                tick={{ fill: NB.mut, fontSize: 14 }}
                tickLine={false}
                axisLine={false}
                width={52}
              />
              <Tooltip
                cursor={{ stroke: NB.faint, strokeDasharray: "3 4" }}
                content={({ active, payload }) => {
                  if (!active || !payload?.length) return null;
                  const row = payload[0].payload as { date: string; total: number };
                  return (
                    <div
                      className="rounded-lg px-4 py-2.5 text-[15px]"
                      style={{ background: NB.card, border: `1px solid ${NB.line}`, color: NB.txt }}
                    >
                      <div style={{ color: NB.mut }}>
                        {new Date(row.date).toLocaleDateString([], {
                          weekday: "short",
                          month: "short",
                          day: "numeric",
                        })}
                      </div>
                      <div className="font-medium">{fmtMoney(row.total)}</div>
                    </div>
                  );
                }}
              />
              <Area
                type="monotone"
                dataKey="total"
                stroke={NB.amber}
                strokeWidth={2.5}
                fill="url(#nbRevFill)"
                dot={false}
                activeDot={{ r: 5, fill: NB.amberText, stroke: "none" }}
              />
            </AreaChart>
          </ResponsiveContainer>
        </div>
        {/* lifecycle-phase mix */}
        {activePhases.length > 0 && (
          <div className="flex items-center gap-5 pt-2 pb-3">
            <div className="flex flex-1 gap-[3px]" style={{ height: 6 }}>
              {activePhases.map((p) => (
                <div
                  key={p.phase}
                  className="rounded-[3px]"
                  style={{
                    width: `${p.percentage}%`,
                    background: PHASE_CONFIG[p.phase]?.color || "#94A3B8",
                  }}
                />
              ))}
            </div>
            <div className="flex gap-5 text-[13px]" style={{ color: NB.mut }}>
              {activePhases.slice(0, 5).map((p) => (
                <span key={p.phase} className="flex items-center gap-2 whitespace-nowrap">
                  <span
                    className="inline-block h-2.5 w-2.5 rounded-[3px]"
                    style={{ background: PHASE_CONFIG[p.phase]?.color || "#94A3B8" }}
                  />
                  {PHASE_CONFIG[p.phase]?.label || p.phase}
                </span>
              ))}
            </div>
          </div>
        )}
      </div>

      {/* business + ops band */}
      <div className="grid grid-cols-8 py-5" style={{ borderTop: `1px solid ${NB.line}` }}>
        {band.map((cell, i) => (
          <div
            key={cell.label}
            className="px-5 first:pl-0"
            style={{
              borderLeft: i === 0 ? "none" : `1px solid ${cell.group ? "#2a3852" : "#1a2334"}`,
            }}
          >
            <div
              className="text-[13px] font-medium uppercase"
              style={{ color: NB.mut, letterSpacing: "0.18em" }}
            >
              {cell.label}
            </div>
            <div className="text-[34px] font-light mt-1.5" style={{ letterSpacing: "-0.01em" }}>
              {cell.value}
            </div>
            <div className="text-[15px] mt-1" style={{ color: NB.mut }}>
              {cell.sub}
            </div>
          </div>
        ))}
      </div>

      {/* live event feed */}
      <div className="relative min-w-0" style={{ borderTop: `1px solid ${NB.line}` }}>
        <div
          ref={feedRef}
          className="overflow-x-auto overflow-y-hidden py-4 [&::-webkit-scrollbar]:hidden"
          style={{ scrollbarWidth: "none" }}
        >
          <div className="flex gap-3 px-1" style={{ width: "max-content" }}>
            {[...events].reverse().map((event) => {
              const meta = EVENT_META[event.metric_id];
              if (!meta) return null;
              const d = event.event_properties;
              let name = "";
              let detail: React.ReactNode = "";
              if (event.metric_id === METRIC_IDS.PLACED_ORDER) {
                name = d.ShippingName ?? "";
                const flags = [
                  d.IsOnHold && "On Hold",
                  d.StillOwes && "Owes",
                  d.LocalPickup && "Local",
                  d.HasPreorder && "Pre-order",
                ].filter(Boolean);
                detail = (
                  <>
                    #{d.OrderId} · <span style={{ color: NB.amberText }}>{fmtEventMoney(d.TotalAmount)}</span>
                    {flags.length > 0 && ` · ${flags.join(" · ")}`}
                  </>
                );
              } else if (event.metric_id === METRIC_IDS.SHIPPED_ORDER) {
                name = d.ShippingName ?? "";
                detail = `#${d.OrderId} · ${shipMethod(d.ShipMethod)}${d.ShippedBy ? ` · by ${d.ShippedBy}` : ""}`;
              } else if (event.metric_id === METRIC_IDS.ACCOUNT_CREATED) {
                name = `${d.FirstName ?? ""} ${d.LastName ?? ""}`.trim();
                detail = d.EmailAddress;
              } else if (event.metric_id === METRIC_IDS.CANCELED_ORDER) {
                name = d.ShippingName ?? "";
                detail = (
                  <>
                    #{d.OrderId} · {fmtEventMoney(d.TotalAmount)}
                    {d.CancelReason ? ` · ${d.CancelReason}` : ""}
                  </>
                );
              } else if (event.metric_id === METRIC_IDS.PAYMENT_REFUNDED) {
                name = d.ShippingName ?? "";
                detail = (
                  <>
                    #{d.FromOrder} · {fmtEventMoney(d.PaymentAmount)}
                    {d.PaymentName ? ` · ${d.PaymentName}` : ""}
                  </>
                );
              } else if (event.metric_id === METRIC_IDS.NEW_BLOG_POST) {
                name = d.title ?? "";
                detail = d.description;
              }
              return (
                <EventDialog key={event.id} event={event} scale={1.75}>
                  <div
                    className="w-[290px] shrink-0 rounded-2xl px-5 py-4 cursor-pointer transition-colors hover:brightness-125"
                    style={{ background: NB.card }}
                  >
                    <div
                      className="flex items-center justify-between text-[12px] font-medium uppercase"
                      style={{ color: NB.mut, letterSpacing: "0.16em" }}
                    >
                      <span className="flex items-center gap-2.5">
                        <span
                          className="inline-block h-2 w-2 rounded-full"
                          style={{ background: meta.dot }}
                        />
                        {meta.label}
                      </span>
                      {event.datetime && (
                        <span style={{ letterSpacing: "0.04em" }}>
                          {new Date(event.datetime).toLocaleTimeString("en-US", {
                            hour: "numeric",
                            minute: "2-digit",
                          })}
                        </span>
                      )}
                    </div>
                    <div className="text-[21px] font-medium mt-2 truncate">{name || "—"}</div>
                    <div className="text-[16px] mt-1 truncate" style={{ color: NB.mut }}>
                      {detail}
                    </div>
                  </div>
                </EventDialog>
              );
            })}
          </div>
        </div>
        {/* edge fades */}
        <div
          className="pointer-events-none absolute inset-y-0 left-0 w-14"
          style={{ background: `linear-gradient(to right, ${NB.bg}, transparent)` }}
        />
        <div
          className="pointer-events-none absolute inset-y-0 right-0 w-14"
          style={{ background: `linear-gradient(to left, ${NB.bg}, transparent)` }}
        />
      </div>
    </div>
  );
};

export default NightboardSmall;
