/**
 * StudioMobile — the /mobile dashboard, Sorbet Studio style.
 *
 * One scrolling page tuned to a phone viewport (~420px). Bento-style hero with
 * a featured revenue tile, then light-chrome cards. Charts and lists here are
 * mobile-specific simplifications — plain SVG lines instead of recharts, no
 * axes chrome, no tables — because the full dashboard components don't survive
 * being squeezed to phone width. Data hooks mirror NightboardSmall/StatCards
 * one-to-one; only the presentation is new. Deliberately lighter than the full
 * dashboard and a little richer than the kiosk: scroll buys some depth, but
 * every section should still read at a glance.
 */
import React from "react";
import { useQuery } from "@tanstack/react-query";
import { acotService } from "@/services/dashboard/acotService";
import { apiClient } from "@/utils/apiClient";
import { apiFetch } from "@/utils/api";
import config from "@/config";
import { STUDIO_TILES } from "@/lib/dashboard/designTokens";
import { useNow } from "@/hooks/useNow";
// @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";

// ── palette (Sorbet Studio, hex-pinned like the tokens file) ─────────────────
const C = {
  ground: "#f8f7f5",
  ink: "#2b2925",
  muted: "#7c7870",
  faint: "#a09b92",
  border: "#e7e5e1",
  hairline: "#f0eeea",
  coral: "#e06a4e",
  teal: "#0f8f77",
  up: "#237a4d",
  down: "#b3503f",
} as const;

// ── formatters (same conventions as NightboardSmall) ─────────────────────────
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;

const fmtTime = (iso: string | undefined) =>
  iso
    ? new Date(iso).toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" })
    : "";

const hourLabel = (h: number) => `${h % 12 || 12} ${h < 12 ? "AM" : "PM"}`;

// ── metric ids for the event feed (same Klaviyo metrics as EventFeed) ────────
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: C.up },
  [METRIC_IDS.SHIPPED_ORDER]: { label: "Shipped", dot: "#3f7fae" },
  [METRIC_IDS.ACCOUNT_CREATED]: { label: "Account", dot: "#6b5fc7" },
  [METRIC_IDS.CANCELED_ORDER]: { label: "Canceled", dot: C.down },
  [METRIC_IDS.PAYMENT_REFUNDED]: { label: "Refund", dot: "#c9822a" },
  [METRIC_IDS.NEW_BLOG_POST]: { label: "Blog", dot: C.muted },
};

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";
};

// ── response shapes (acotService is untyped JS; mirrors what the API returns) ─
interface EventProps {
  ShippingName?: string;
  OrderId?: string | number;
  TotalAmount?: string | number;
  ShipMethod?: 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 TypeSlice {
  count?: number;
}

interface TodayStats {
  revenue: number;
  orderCount: number;
  itemCount: number;
  averageOrderValue: number;
  averageItemsPerOrder: number;
  periodProgress: number;
  prevPeriodRevenue: number;
  prevPeriodOrders: number;
  prevPeriodAOV: number;
  projectedRevenue?: number;
  orderTypes?: { preOrders?: TypeSlice; localPickup?: TypeSlice; heldItems?: TypeSlice };
  shipping?: { shippedCount?: number; locations?: { total?: number } };
  refunds?: { total?: number; count?: number };
  canceledOrders?: { total?: number; count?: number };
}

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

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

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

interface TopProduct {
  id: number | string;
  name: string;
  ImgThumb?: string;
  totalQuantity: number;
  orderCount: number;
  totalRevenue: number;
}

// ── tiny presentational atoms ────────────────────────────────────────────────
// Beyond a few hundred percent the number is an artifact (day-boundary
// projections, near-zero baselines) — on a glance page, show nothing.
const trendVisible = (pct: number | null | undefined): pct is number =>
  pct != null && isFinite(pct) && Math.abs(pct) >= 0.1 && Math.abs(pct) < 500;

const TrendChip = ({
  pct,
  invert = false,
  big = false,
}: {
  pct: number | null | undefined;
  invert?: boolean;
  big?: boolean;
}) => {
  if (!trendVisible(pct)) return null;
  const good = invert ? pct < 0 : pct > 0;
  return (
    <span
      className={`font-semibold ${big ? "text-[13px]" : "text-[11px]"}`}
      style={{ color: good ? C.up : C.down }}
    >
      {pct > 0 ? "▲" : "▼"} {Math.abs(pct).toFixed(1)}%
    </span>
  );
};

/** Percentage-point delta (for margin) — same voice as TrendChip. */
const PpChip = ({ delta }: { delta: number | null | undefined }) => {
  if (delta == null || !isFinite(delta) || Math.abs(delta) < 0.1) return null;
  return (
    <span className="text-[11px] font-semibold" style={{ color: delta > 0 ? C.up : C.down }}>
      {delta > 0 ? "▲" : "▼"} {Math.abs(delta).toFixed(1)}pp
    </span>
  );
};

/** Uppercase eyebrow above a bare strip — the page's only section chrome. */
const Eyebrow = ({ children }: { children: React.ReactNode }) => (
  <div
    className="mb-1.5 mt-4 px-1 text-[10.5px] font-semibold uppercase"
    style={{ color: C.faint, letterSpacing: "0.08em" }}
  >
    {children}
  </div>
);

/** White section card with a slim bordered header — chrome kept, weight shed. */
const SectionCard = ({
  title,
  aside,
  children,
  className = "",
}: {
  title: string;
  aside?: React.ReactNode;
  children: React.ReactNode;
  className?: string;
}) => (
  <div
    className={`mt-4 overflow-hidden rounded-[14px] border bg-white ${className}`}
    style={{ borderColor: C.border, boxShadow: "0 1px 2px rgba(43,41,37,.04)" }}
  >
    <div
      className="flex items-center justify-between border-b px-3.5 py-2.5"
      style={{ borderColor: C.hairline }}
    >
      <span className="text-[12.5px] font-semibold tracking-tight">{title}</span>
      {aside}
    </div>
    {children}
  </div>
);

const QuietCell = ({
  label,
  value,
  sub,
}: {
  label: string;
  value: React.ReactNode;
  sub?: React.ReactNode;
}) => (
  <div className="bg-white px-3 py-2.5">
    <div
      className="text-[10px] font-semibold uppercase"
      style={{ color: C.faint, letterSpacing: "0.06em" }}
    >
      {label}
    </div>
    <div className="mt-0.5 text-[15px] font-bold tracking-tight">{value}</div>
    {sub != null && (
      <div className="text-[10.5px]" style={{ color: C.faint }}>
        {sub}
      </div>
    )}
  </div>
);

/** gap-px strip of QuietCells on a hairline ground */
const QuietStrip = ({ cols, children }: { cols: 2 | 3; children: React.ReactNode }) => (
  <div
    className={`grid gap-px overflow-hidden rounded-[14px] border ${
      cols === 3 ? "grid-cols-3" : "grid-cols-2"
    }`}
    style={{ borderColor: C.hairline, background: C.hairline }}
  >
    {children}
  </div>
);

/**
 * Mobile chart: a plain SVG polyline with a soft area fill and an emphasized
 * endpoint — no recharts, no axes chrome. Optional dashed previous-period
 * series shares the same scale (one axis, one story).
 */
const MobileLine = ({
  values,
  prevValues,
  height,
  stroke,
  fill,
  prevStroke,
  startLabel,
  endLabel,
  labelColor,
  baseline,
}: {
  values: number[];
  prevValues?: number[];
  height: number;
  stroke: string;
  fill: string;
  prevStroke?: string;
  startLabel?: string;
  endLabel?: string;
  labelColor: string;
  baseline: string;
}) => {
  if (values.length < 2) return <div style={{ height }} />;
  const W = 360;
  const labelSpace = startLabel || endLabel ? 14 : 0;
  const H = height - labelSpace;
  const max = Math.max(...values, ...(prevValues || []), 1);
  const toXY = (vals: number[]) => {
    const step = vals.length > 1 ? W / (vals.length - 1) : W;
    return vals.map((v, i) => ({
      x: i * step,
      y: H - 3 - (v / max) * (H - 6),
    }));
  };
  const cur = toXY(values);
  const prev = prevValues && prevValues.length > 1 ? toXY(prevValues) : null;
  const curStr = cur.map((p) => `${p.x.toFixed(1)},${p.y.toFixed(1)}`).join(" ");
  const prevStr = prev?.map((p) => `${p.x.toFixed(1)},${p.y.toFixed(1)}`).join(" ");
  const last = cur[cur.length - 1];
  return (
    <svg
      width="100%"
      height={height}
      viewBox={`0 0 ${W} ${height}`}
      preserveAspectRatio="none"
      aria-hidden="true"
      className="block"
    >
      <line x1="0" y1={H} x2={W} y2={H} stroke={baseline} strokeWidth="1" />
      {prevStr && prevStroke && (
        <polyline
          points={prevStr}
          fill="none"
          stroke={prevStroke}
          strokeWidth="2"
          strokeDasharray="5 4"
          vectorEffect="non-scaling-stroke"
        />
      )}
      <path d={`M${curStr.replace(/ /g, " L")} L${W},${H} L0,${H} Z`} fill={fill} />
      <polyline
        points={curStr}
        fill="none"
        stroke={stroke}
        strokeWidth="2"
        vectorEffect="non-scaling-stroke"
        strokeLinejoin="round"
      />
      <circle cx={last.x} cy={last.y} r="3.4" fill={stroke} stroke="#fff" strokeWidth="1.5" />
      {startLabel && (
        <text x="0" y={height - 2} fontSize="10" fill={labelColor}>
          {startLabel}
        </text>
      )}
      {endLabel && (
        <text x={W} y={height - 2} fontSize="10" fill={labelColor} textAnchor="end">
          {endLabel}
        </text>
      )}
    </svg>
  );
};

// ── main component ───────────────────────────────────────────────────────────
const StudioMobile = () => {
  const now = useNow();

  // Today stats (same source as StatCards)
  const { data: stats, dataUpdatedAt } = useQuery({
    queryKey: ["mobile-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: ["mobile-projection-today"],
    queryFn: async () =>
      (await acotService.getProjection({ timeRange: "today" })) as Projection,
    enabled: stats != null && stats.periodProgress < 100,
    refetchInterval: 60_000,
  });

  // Today financials for the profit tile (same source as the StatCards hero)
  const { data: financialsToday } = useQuery({
    queryKey: ["mobile-financials-today"],
    queryFn: async () =>
      (await acotService.getFinancials({ timeRange: "today" })) as FinancialsResponse,
    refetchInterval: 120_000,
  });

  // Ops for the shipped tile
  const { data: opsData } = useQuery({
    queryKey: ["mobile-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: realtime } = useQuery({
    queryKey: ["mobile-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,
  });

  // Event feed (same source as EventFeed)
  const { data: events = [] } = useQuery<FeedEvent[]>({
    queryKey: ["mobile-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,
  });

  // Top sellers (same source as ProductGrid)
  const { data: products = [] } = useQuery<TopProduct[]>({
    queryKey: ["mobile-top-products"],
    queryFn: async () => {
      const res = (await acotService.getProducts({ timeRange: "today" })) as {
        stats?: { products?: { list?: TopProduct[] } };
      };
      return res.stats?.products?.list || [];
    },
    refetchInterval: 300_000,
  });

  // 30-day dailies (chart + totals), financials, forecast
  const { data: daily30 = [] } = useQuery({
    queryKey: ["mobile-daily-30d"],
    queryFn: async () => {
      const res = (await acotService.getStatsDetails({
        timeRange: "last30days",
        metric: "revenue",
        daily: true,
      })) as { stats?: DailyRow[] };
      return Array.isArray(res.stats) ? res.stats : [];
    },
    refetchInterval: 300_000,
  });

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

  // Inventory band
  const { data: stockData } = useQuery({
    queryKey: ["mobile-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: 600_000,
  });

  const { data: replenishData } = useQuery({
    queryKey: ["mobile-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: 600_000,
  });

  const { data: overstockData } = useQuery({
    queryKey: ["mobile-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: 600_000,
  });

  // ── derived values ─────────────────────────────────────────────────────────
  const inProgress = stats != null && stats.periodProgress < 100;
  // Minutes into the business day a projection multiplies noise ("▲ 9,914%").
  // Glanceability beats completeness here: hide projection-based chips until
  // enough of the day exists to project from.
  const projReliable = stats != null && stats.periodProgress >= 10;
  const projRevenue = projection?.projectedRevenue ?? stats?.projectedRevenue ?? null;
  const revTrend =
    stats && projReliable && 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 ordersTrend =
    stats && projReliable && stats.prevPeriodOrders > 0
      ? trendPct(
          inProgress ? projOrders ?? stats.orderCount : stats.orderCount,
          stats.prevPeriodOrders
        )
      : null;
  const aovTrend =
    stats && stats.prevPeriodAOV > 0
      ? trendPct(stats.averageOrderValue, stats.prevPeriodAOV)
      : null;

  const profit = financialsToday?.totals?.profit ?? null;
  const marginToday = financialsToday?.totals?.margin ?? null;
  // mid-period the raw profit always trails yesterday; scale by projected
  // revenue the same way the StatCards hero does
  const profitTrend = (() => {
    const prev = financialsToday?.previousTotals?.profit;
    if (!projReliable || profit == null || prev == null || prev <= 0) return null;
    const scaled =
      inProgress && stats && stats.revenue > 0 && projRevenue
        ? profit * (projRevenue / stats.revenue)
        : profit;
    return trendPct(scaled, prev);
  })();

  const ops = opsData?.totals;

  // Hourly revenue shape for the hero curve, bucketed from today's placed-order
  // feed events (the stats/details endpoint only returns one daily row for
  // "today", and the feed is uncapped — every order today is already here).
  // Sums won't exactly reconcile with stats.revenue (cancels/refunds); the
  // curve is the day's shape, not a ledger.
  const hourlyCurve = React.useMemo(() => {
    const totals = new Array(24).fill(0) as number[];
    let any = false;
    for (const e of events) {
      if (e.metric_id !== METRIC_IDS.PLACED_ORDER || !e.datetime) continue;
      const amt = parseFloat(String(e.event_properties?.TotalAmount ?? ""));
      if (!Number.isFinite(amt)) continue;
      totals[new Date(e.datetime).getHours()] += amt;
      any = true;
    }
    if (!any) return null;
    // business day runs 1 AM → 1 AM (see shared/business-time)
    const nowH = now.getHours();
    const values: number[] = [];
    let h = 1;
    for (let i = 0; i < 24; i++) {
      values.push(totals[h]);
      if (h === nowH) break;
      h = (h + 1) % 24;
    }
    return { values, start: hourLabel(1), end: hourLabel(nowH) };
  }, [events, now]);

  const daily30Rev = daily30.map((r) => Number(r.revenue) || 0);
  const daily30Prev = daily30.map((r) => Number(r.prevRevenue) || 0);
  const sum30 = daily30.reduce<{
    revenue: number;
    prevRevenue: number;
    orders: number;
    prevOrders: number;
  }>(
    (acc, d) => ({
      revenue: acc.revenue + (Number(d.revenue) || 0),
      prevRevenue: acc.prevRevenue + (Number(d.prevRevenue) || 0),
      orders: acc.orders + (Number(d.orders) || 0),
      prevOrders: acc.prevOrders + (Number(d.prevOrders) || 0),
    }),
    { revenue: 0, prevRevenue: 0, orders: 0, prevOrders: 0 }
  );
  const avgPerDay = daily30.length ? sum30.revenue / daily30.length : null;
  const rev30Trend = daily30.length ? trendPct(sum30.revenue, sum30.prevRevenue) : null;
  const orders30Trend = daily30.length ? trendPct(sum30.orders, sum30.prevOrders) : null;
  const prevAvgPerDay = daily30.length ? sum30.prevRevenue / daily30.length : null;
  const avg30Trend =
    avgPerDay != null && prevAvgPerDay != null ? trendPct(avgPerDay, prevAvgPerDay) : null;

  // margin with the same income-based fallback the nightboard band uses
  const marginFrom = (t: Record<string, number> | undefined) => {
    if (!t) return null;
    if (Number.isFinite(t.margin)) return t.margin;
    const income = (t.grossSales || 0) - (t.refunds || 0) - (t.discounts || 0) + (t.shippingFees || 0);
    return income > 0 ? ((income - (t.cogs || 0)) / income) * 100 : 0;
  };
  const margin30 = marginFrom(financials30?.totals);
  const prevMargin30 = marginFrom(financials30?.previousTotals);
  const margin30Delta =
    margin30 != null && prevMargin30 != null ? margin30 - prevMargin30 : null;

  const hour = now.getHours();
  const greeting = hour < 12 ? "Good morning" : hour < 17 ? "Good afternoon" : "Good evening";
  const dateLine = now.toLocaleDateString("en-US", {
    weekday: "long",
    month: "long",
    day: "numeric",
  });

  const tiles = STUDIO_TILES;
  const rankTones = [tiles.peach, tiles.mint, tiles.lemon, tiles.lilac];

  return (
    <div
      className="min-h-screen"
      style={{
        background: C.ground,
        color: C.ink,
        fontVariantNumeric: "tabular-nums",
      }}
    >
      <div
        className="mx-auto max-w-[480px] px-3.5 pt-5"
        style={{ paddingBottom: "calc(3rem + env(safe-area-inset-bottom))" }}
      >
        {/* header — actives live in the hero's realtime tile, so no chip here */}
        <div className="flex items-baseline justify-between px-0.5">
          <div className="text-[19px] font-bold tracking-tight">{greeting}</div>
          <div className="text-[12px]" style={{ color: C.muted }}>
            {dateLine}
          </div>
        </div>

        {/* hero — bento: featured revenue + pastel tiles */}
        <div className="mt-3.5 grid grid-cols-2 gap-2">
          <div
            className="col-span-2 rounded-[16px] px-3.5 pb-2 pt-3"
            style={{ background: tiles.peach.fill }}
          >
            <div
              className="text-[10.5px] font-bold uppercase"
              style={{ color: "rgba(43,41,37,.5)", letterSpacing: "0.08em" }}
            >
              Revenue · today
            </div>
            <div className="mt-1 flex items-baseline gap-2">
              <span className="text-[32px] font-bold leading-none tracking-tight">
                {fmtMoney(stats?.revenue)}
              </span>
              <TrendChip pct={revTrend} big />
            </div>
            {stats != null && (
              <div className="mt-1 text-[11.5px]" style={{ color: "rgba(43,41,37,.55)" }}>
                {inProgress && projReliable && projRevenue != null
                  ? `proj ${fmtCompact(projRevenue)} · `
                  : ""}
                {stats.prevPeriodRevenue > 0 ? `prev ${fmtCompact(stats.prevPeriodRevenue)}` : ""}
              </div>
            )}
            {hourlyCurve != null && hourlyCurve.values.length >= 2 && (
              <div className="mt-2">
                <MobileLine
                  values={hourlyCurve.values}
                  height={76}
                  stroke={tiles.peach.spark}
                  fill={tiles.peach.sparkFill}
                  startLabel={hourlyCurve.start}
                  endLabel={hourlyCurve.end}
                  labelColor="rgba(43,41,37,.42)"
                  baseline="rgba(43,41,37,.12)"
                />
              </div>
            )}
          </div>

          <div className="rounded-[16px] px-3.5 py-3" style={{ background: tiles.mint.fill }}>
            <div
              className="text-[10.5px] font-bold uppercase"
              style={{ color: "rgba(43,41,37,.5)", letterSpacing: "0.08em" }}
            >
              Orders
            </div>
            <div className="mt-1 text-[22px] font-bold leading-none tracking-tight">
              {stats ? fmtCount(stats.orderCount) : "—"}
            </div>
            <div
              className="mt-1 flex items-baseline gap-1 text-[11px]"
              style={{ color: "rgba(43,41,37,.55)" }}
            >
              <TrendChip pct={ordersTrend} />
              <span>
                {stats
                  ? `${trendVisible(ordersTrend) ? "· " : ""}${fmtCount(stats.itemCount)} items`
                  : "…"}
              </span>
            </div>
          </div>

          <div className="rounded-[16px] px-3.5 py-3" style={{ background: tiles.lilac.fill }}>
            <div
              className="text-[10.5px] font-bold uppercase"
              style={{ color: "rgba(43,41,37,.5)", letterSpacing: "0.08em" }}
            >
              Gross profit
            </div>
            <div className="mt-1 text-[22px] font-bold leading-none tracking-tight">
              {profit != null ? fmtMoney(profit) : "—"}
            </div>
            <div
              className="mt-1 flex items-baseline gap-1 text-[11px]"
              style={{ color: "rgba(43,41,37,.55)" }}
            >
              <TrendChip pct={profitTrend} />
              <span>
                {marginToday != null && Number.isFinite(marginToday)
                  ? `${trendVisible(profitTrend) ? "· " : ""}${marginToday.toFixed(1)}% margin`
                  : "…"}
              </span>
            </div>
          </div>

          <div className="rounded-[16px] px-3.5 py-3" style={{ background: tiles.lemon.fill }}>
            <div
              className="text-[10.5px] font-bold uppercase"
              style={{ color: "rgba(43,41,37,.5)", letterSpacing: "0.08em" }}
            >
              AOV
            </div>
            <div className="mt-1 text-[22px] font-bold leading-none tracking-tight">
              {stats?.averageOrderValue != null
                ? `$${stats.averageOrderValue.toFixed(2)}`
                : "—"}
            </div>
            <div
              className="mt-1 flex items-baseline gap-1 text-[11px]"
              style={{ color: "rgba(43,41,37,.55)" }}
            >
              <TrendChip pct={aovTrend} />
              <span>
                {stats?.averageItemsPerOrder != null
                  ? `${trendVisible(aovTrend) ? "· " : ""}${stats.averageItemsPerOrder.toFixed(1)} items/order`
                  : "…"}
              </span>
            </div>
          </div>

          <div
            className="rounded-[16px] border bg-white px-3.5 py-3"
            style={{ borderColor: C.border }}
          >
            <div
              className="text-[10.5px] font-bold uppercase"
              style={{ color: C.faint, letterSpacing: "0.08em" }}
            >
              Active now
            </div>
            <div
              className="mt-1 flex items-center gap-1.5 text-[22px] font-bold leading-none tracking-tight"
              style={{ color: "#0d6b58" }}
            >
              <span
                className="inline-block h-2 w-2 rounded-full motion-safe:animate-pulse"
                style={{ background: C.teal }}
              />
              {realtime ? fmtCount(realtime.last5MinUsers) : "—"}
            </div>
            <div className="mt-1 text-[11px]" style={{ color: C.faint }}>
              {realtime ? `${fmtCount(realtime.last30MinUsers)} last 30 min` : "…"}
            </div>
          </div>
        </div>

        {/* order flow strip */}
        <Eyebrow>Order flow · today</Eyebrow>
        <QuietStrip cols={3}>
          <QuietCell
            label="Pre-orders"
            value={fmtCount(stats?.orderTypes?.preOrders?.count ?? 0)}
            sub="orders"
          />
          <QuietCell
            label="On hold"
            value={fmtCount(stats?.orderTypes?.heldItems?.count ?? 0)}
            sub="orders"
          />
          <QuietCell
            label="Pickup"
            value={fmtCount(stats?.orderTypes?.localPickup?.count ?? 0)}
            sub="orders"
          />
          <QuietCell
            label="Shipped"
            value={ops ? fmtCount(ops.ordersShipped) : "—"}
            sub={ops ? `${fmtCount(ops.piecesPicked)} picked` : "…"}
          />
          <QuietCell
            label="Refunds"
            value={`$${(stats?.refunds?.total ?? 0).toFixed(0)}`}
            sub={`${stats?.refunds?.count ?? 0} orders`}
          />
          <QuietCell
            label="Cancels"
            value={`$${(stats?.canceledOrders?.total ?? 0).toFixed(0)}`}
            sub={`${stats?.canceledOrders?.count ?? 0} orders`}
          />
        </QuietStrip>

        {/* live feed */}
        <SectionCard
          title="Live feed"
          aside={
            <span className="text-[11px]" style={{ color: C.faint }}>
              today
            </span>
          }
        >
          {events.length === 0 ? (
            <div className="px-3.5 py-6 text-center text-[12px]" style={{ color: C.faint }}>
              Nothing yet today
            </div>
          ) : (
            <div className="dashboard-scroll max-h-[280px] overflow-y-auto overscroll-contain">
            {events.slice(0, 40).map((event) => {
              const meta = EVENT_META[event.metric_id] || { label: "Event", dot: C.muted };
              const d = event.event_properties || {};
              let name: string | undefined;
              let detail: React.ReactNode = null;
              if (event.metric_id === METRIC_IDS.PLACED_ORDER) {
                name = d.ShippingName;
                detail = <>#{d.OrderId} · {fmtEventMoney(d.TotalAmount)}</>;
              } else if (event.metric_id === METRIC_IDS.SHIPPED_ORDER) {
                name = d.ShippingName;
                detail = <>#{d.OrderId} · {shipMethod(d.ShipMethod)}</>;
              } else if (event.metric_id === METRIC_IDS.ACCOUNT_CREATED) {
                name = [d.FirstName, d.LastName].filter(Boolean).join(" ") || d.EmailAddress;
                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)}</>;
              } else if (event.metric_id === METRIC_IDS.NEW_BLOG_POST) {
                name = d.title;
                detail = d.description;
              }
              return (
                <EventDialog key={event.id} event={event}>
                  <div
                    className="flex cursor-pointer items-center gap-2.5 border-t px-3.5 py-2.5 first:border-t-0 active:bg-[#faf9f7]"
                    style={{ borderColor: "#f5f3f0" }}
                  >
                    <span
                      className="h-[7px] w-[7px] shrink-0 rounded-full"
                      style={{ background: meta.dot }}
                    />
                    <span className="min-w-0 flex-1">
                      <span className="block truncate text-[12.5px] font-medium leading-tight">
                        {name || meta.label}
                      </span>
                      <span
                        className="block truncate text-[11px] leading-tight"
                        style={{ color: C.faint }}
                      >
                        {meta.label}
                        {detail ? <> · {detail}</> : null}
                      </span>
                    </span>
                    <span className="shrink-0 text-[10.5px]" style={{ color: C.faint }}>
                      {fmtTime(event.datetime)}
                    </span>
                  </div>
                </EventDialog>
              );
            })}
            </div>
          )}
        </SectionCard>

        {/* top sellers */}
        <SectionCard
          title="Top sellers"
          aside={
            <span className="text-[11px]" style={{ color: C.faint }}>
              today
            </span>
          }
        >
          {products.length === 0 ? (
            <div className="px-3.5 py-6 text-center text-[12px]" style={{ color: C.faint }}>
              No sales yet today
            </div>
          ) : (
            <div className="dashboard-scroll max-h-[280px] overflow-y-auto overscroll-contain">
            {[...products]
              .sort((a, b) => (b.totalRevenue || 0) - (a.totalRevenue || 0))
              .slice(0, 25)
              .map((product, i) => {
                const tone = rankTones[i % rankTones.length];
                return (
                  <a
                    key={product.id}
                    href={`https://backend.acherryontop.com/product/${product.id}`}
                    target="_blank"
                    rel="noreferrer"
                    className="flex items-center gap-2.5 border-t px-3.5 py-2.5 first:border-t-0 active:bg-[#faf9f7]"
                    style={{ borderColor: "#f5f3f0" }}
                  >
                    <span
                      className="flex h-[22px] w-[22px] shrink-0 items-center justify-center rounded-[7px] text-[11px] font-bold"
                      style={{ background: tone.fill, color: tone.spark }}
                    >
                      {i + 1}
                    </span>
                    {product.ImgThumb ? (
                      <img
                        src={product.ImgThumb}
                        alt=""
                        loading="lazy"
                        className="h-9 w-9 shrink-0 rounded-lg object-cover"
                        style={{ background: C.hairline }}
                      />
                    ) : (
                      <span
                        className="h-9 w-9 shrink-0 rounded-lg"
                        style={{ background: C.hairline }}
                      />
                    )}
                    <span className="min-w-0 flex-1">
                      <span className="block truncate text-[12.5px] font-medium leading-tight">
                        {product.name}
                      </span>
                      <span className="block text-[11px] leading-tight" style={{ color: C.faint }}>
                        {fmtCount(product.totalQuantity)} sold · {fmtCount(product.orderCount)}{" "}
                        {product.orderCount === 1 ? "order" : "orders"}
                      </span>
                    </span>
                    <span className="shrink-0 text-[12.5px] font-bold">
                      {fmtMoney(product.totalRevenue)}
                    </span>
                  </a>
                );
              })}
            </div>
          )}
        </SectionCard>

        {/* last 30 days */}
        <SectionCard
          title="Last 30 days"
          aside={
            <span className="flex items-center gap-2.5 text-[10.5px]" style={{ color: C.faint }}>
              <span className="flex items-center gap-1">
                <span className="inline-block h-[7px] w-[7px] rounded-full" style={{ background: C.coral }} />
                this 30d
              </span>
              <span className="flex items-center gap-1">
                <span
                  className="inline-block w-[10px] border-t-2 border-dashed"
                  style={{ borderColor: C.teal }}
                />
                prev
              </span>
            </span>
          }
        >
          <div className="px-3.5 pt-3">
            <MobileLine
              values={daily30Rev}
              prevValues={daily30Prev}
              height={84}
              stroke={C.coral}
              fill="rgba(224,106,78,.08)"
              prevStroke={C.teal}
              labelColor={C.faint}
              baseline={C.hairline}
            />
          </div>
          <div
            className="mt-3 grid grid-cols-2 gap-px border-t"
            style={{ background: C.hairline, borderColor: C.hairline }}
          >
            <QuietCell
              label="Revenue"
              value={fmtCompact(sum30.revenue)}
              sub={<TrendChip pct={rev30Trend} />}
            />
            <QuietCell
              label="Orders"
              value={daily30.length ? fmtCount(sum30.orders) : "—"}
              sub={<TrendChip pct={orders30Trend} />}
            />
            <QuietCell
              label="Avg / day"
              value={avgPerDay != null ? fmtMoney(avgPerDay) : "—"}
              sub={<TrendChip pct={avg30Trend} />}
            />
            <QuietCell
              label="Margin"
              value={margin30 != null ? `${margin30.toFixed(1)}%` : "—"}
              sub={<PpChip delta={margin30Delta} />}
            />
          </div>
        </SectionCard>

        {/* inventory strip */}
        <Eyebrow>Inventory</Eyebrow>
        <QuietStrip cols={3}>
          <QuietCell
            label="Stock value"
            value={fmtCompact(stockData?.totalStockCost)}
            sub={stockData ? `${fmtCount(stockData.productsInStock)} products` : "…"}
          />
          <QuietCell
            label="Replenish"
            value={replenishData ? fmtCount(replenishData.unitsToReplenish) : "—"}
            sub={replenishData ? `${fmtCompact(replenishData.replenishmentCost)} cost` : "…"}
          />
          <QuietCell
            label="Overstocked"
            value={overstockData ? fmtCount(overstockData.overstockedProducts) : "—"}
            sub={overstockData ? `${fmtCompact(overstockData.totalExcessCost)} excess` : "…"}
          />
        </QuietStrip>

        {/* footer stamp */}
        <div className="mt-6 text-center text-[11px]" style={{ color: C.faint }}>
          {dataUpdatedAt
            ? `Updated ${new Date(dataUpdatedAt).toLocaleTimeString("en-US", {
                hour: "numeric",
                minute: "2-digit",
              })} · refreshes automatically`
            : "Loading…"}
        </div>
      </div>
    </div>
  );
};

export default StudioMobile;
