"use client";

import Link from "next/link";
import type { ComponentType } from "react";
import { useState } from "react";
import type { Session } from "next-auth";
import { motion } from "motion/react";
import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts";
import { ProductImage } from "@/components/dashboard/product-image";
import { UserMenu } from "@/components/auth/user-menu";
import {
  BellIcon,
  CalendarIcon,
} from "@/components/dashboard/reference-icons";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuLabel,
  DropdownMenuRadioGroup,
  DropdownMenuRadioItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { Card, CardContent } from "@/components/ui/card";
import { ChartContainer, ChartTooltip, ChartTooltipContent, type ChartConfig } from "@/components/ui/chart";
import { Badge } from "@/components/ui/badge";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
  ArrowDownRight,
  ArrowUpRight,
  Bookmark,
  ChevronDown,
  Eye,
  Flame,
  Info,
  Minus,
  PackageSearch,
  Play,
  TrendingUp,
  Trophy,
  Users,
} from "lucide-react";
import { useLanguage } from "@/lib/i18n/context";
import { opportunityLevel } from "@/lib/scoring/config";
import type { DashboardOverviewView } from "@/database/dashboard";
import type { PlanCode } from "@prisma/client";
import { buildKpiCards, type KpiCardKey, type KpiChange } from "@/components/dashboard/dashboard-kpi-view-model";
import { cn } from "@/lib/utils";
import { STAGGER_CONTAINER, STAGGER_ITEM } from "@/components/dashboard/motion-variants";

/** Score tone in the reference CSS only has two states (.score.good /
 * .score.warn) — the scoring engine's four-tier opportunityLevel() is
 * collapsed to those two: excellent/good -> good, fair/limited -> warn. */
function scoreTone(level: ReturnType<typeof opportunityLevel>): "good" | "warn" {
  return level === "excellent" || level === "good" ? "good" : "warn";
}

const SCORE_BADGE_CLASSES: Record<"good" | "warn", string> = {
  good: "bg-success/10 text-success",
  warn: "bg-warning/10 text-warning",
};

/** Gold/silver/bronze/neutral treatment for a 0-based rank index — shared by
 * the product grid's overlay badge and the ranked list rows' small circle. */
function rankBadgeClasses(index: number): string {
  if (index === 0) return "bg-warning text-white";
  if (index === 1) return "bg-muted text-foreground";
  if (index === 2) return "bg-orange-500/15 text-orange-700 dark:text-orange-400";
  return "bg-muted text-muted-foreground";
}

const DISCOVERY_COPY = {
  en: {
    eyebrow: "Discovery hub",
    title: "Signals worth acting on",
    subtitle: "A focused view of opportunity, momentum, categories and creator activity from your catalog.",
    topProducts: "Top opportunity products",
    topProductsSubtitle: "Highest Opportunity Score in the active catalog",
    topVideos: "Top video signals",
    topVideosSubtitle: "Product-level video metrics from the latest synchronized snapshots",
    topInfluencers: "Top influencers",
    topInfluencersSubtitle: "Creators ranked by attributed sales, influence and audience reach",
    hotCategories: "Hot categories",
    hotCategoriesSubtitle: "Average trend and Opportunity Score by active category",
    growth: "Growth over time",
    viewAll: "View all",
    noProducts: "No scored products are available yet.",
    noVideos: "No video metrics have been synchronized yet.",
    noCreators: "No creator signals are available yet.",
    noCategories: "No category score signals are available yet.",
    views: "views",
    videos: "videos",
    engagement: "engagement",
    score: "score",
    influence: "influence",
    followers: "followers",
    attributedSales: "attributed sales",
    products: "products",
    trend: "trend",
    opportunity: "opportunity",
    videoScope: "Individual video posts appear when the provider supplies them.",
  },
  es: {
    eyebrow: "Discovery hub",
    title: "Señales para actuar",
    subtitle: "Una vista enfocada en oportunidad, momentum, categorías y actividad de creadores de tu catálogo.",
    topProducts: "Productos con mayor oportunidad",
    topProductsSubtitle: "Mayor Opportunity Score del catálogo activo",
    topVideos: "Principales señales de video",
    topVideosSubtitle: "Métricas de video a nivel producto de los últimos snapshots sincronizados",
    topInfluencers: "Top influencers",
    topInfluencersSubtitle: "Creadores ordenados por ventas atribuidas, influencia y alcance",
    hotCategories: "Categorías en tendencia",
    hotCategoriesSubtitle: "Promedio de Trend y Opportunity Score por categoría activa",
    growth: "Crecimiento en el tiempo",
    viewAll: "Ver todos",
    noProducts: "Todavía no hay productos puntuados disponibles.",
    noVideos: "Aún no se han sincronizado métricas de video.",
    noCreators: "Todavía no hay señales de creadores disponibles.",
    noCategories: "Todavía no hay señales de puntuación por categoría.",
    views: "vistas",
    videos: "videos",
    engagement: "engagement",
    score: "score",
    influence: "influencia",
    followers: "seguidores",
    attributedSales: "ventas atribuidas",
    products: "productos",
    trend: "trend",
    opportunity: "oportunidad",
    videoScope: "Los posts individuales aparecen cuando el proveedor los entrega.",
  },
} as const;

function initials(value: string): string {
  return value
    .trim()
    .split(/\s+/)
    .slice(0, 2)
    .map((part) => part[0]?.toUpperCase())
    .join("") || "?";
}

type DashboardDateRange = 7 | 30 | 90;

/** Trigger button styling is fully caller-controlled via `className` (both
 * the topbar's date-range pill and the growth chart's compact variant reuse
 * this), matching the shadcn-space blocks' pattern of styling triggers with
 * plain Tailwind utility classes rather than a bespoke CSS component class. */
function DateRangeMenu({
  value,
  onChange,
  labels,
  className,
  showCalendar = true,
}: {
  value: DashboardDateRange;
  onChange: (value: DashboardDateRange) => void;
  labels: Record<DashboardDateRange, string>;
  className: string;
  showCalendar?: boolean;
}) {
  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <button className={className} type="button" aria-label={labels[value]}>
          {showCalendar && <CalendarIcon className="size-4" aria-hidden="true" />}
          <span>{labels[value]}</span>
          <ChevronDown className="size-3.5 text-muted-foreground" aria-hidden="true" />
        </button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end" className="w-48">
        <DropdownMenuLabel>{labels[value]}</DropdownMenuLabel>
        <DropdownMenuSeparator />
        <DropdownMenuRadioGroup
          value={String(value)}
          onValueChange={(next) => {
            const days = Number(next);
            if (days === 7 || days === 30 || days === 90) onChange(days);
          }}
        >
          <DropdownMenuRadioItem value="7">{labels[7]}</DropdownMenuRadioItem>
          <DropdownMenuRadioItem value="30">{labels[30]}</DropdownMenuRadioItem>
          <DropdownMenuRadioItem value="90">{labels[90]}</DropdownMenuRadioItem>
        </DropdownMenuRadioGroup>
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

/**
 * Compact, data-first KPI card: icon + label (+ optional tooltip) on top,
 * a dominant numeric value with an optional unit and change badge in the
 * middle, and a single line of context (plain text or an internal link) at
 * the bottom. No card ever fabricates a comparison — `change` and `subtitle`
 * are computed by the caller from real data, including the "no prior data" /
 * "no scored products yet" states.
 */
function KpiTile({
  icon: Icon,
  label,
  value,
  unit,
  change,
  subtitle,
  subtitleHref,
  tooltip,
}: {
  icon: ComponentType<{ className?: string; "aria-hidden"?: boolean | "true" | "false" }>;
  label: string;
  value: string;
  unit?: string;
  change?: KpiChange | null;
  subtitle: string;
  subtitleHref?: string;
  tooltip?: string;
}) {
  const ChangeIcon = change ? { positive: ArrowUpRight, negative: ArrowDownRight, neutral: Minus }[change.state] : null;
  const changeClasses: Record<KpiChange["state"], string> = {
    positive: "bg-success/10 text-success",
    negative: "bg-destructive/10 text-destructive",
    neutral: "bg-muted text-muted-foreground",
  };
  const subtitleNode = subtitleHref ? (
    <Link href={subtitleHref} className="transition-colors hover:text-primary hover:underline">
      {subtitle}
    </Link>
  ) : (
    subtitle
  );

  return (
    <Card className="rounded-2xl py-4 transition-colors hover:ring-foreground/20">
      <CardContent className="flex min-h-[102px] flex-col gap-2.5">
        <div className="flex min-w-0 items-center gap-2">
          <span className="flex size-7 shrink-0 items-center justify-center rounded-full bg-muted">
            <Icon className="size-3.5 text-muted-foreground" aria-hidden="true" />
          </span>
          <span className="truncate text-[13px] font-medium text-muted-foreground">{label}</span>
          {tooltip && (
            <Tooltip>
              <TooltipTrigger asChild>
                <button
                  type="button"
                  className="ml-auto flex size-4 shrink-0 cursor-help items-center justify-center text-muted-foreground/70 hover:text-foreground"
                  aria-label={tooltip}
                >
                  <Info className="size-3.5" aria-hidden="true" />
                </button>
              </TooltipTrigger>
              <TooltipContent>{tooltip}</TooltipContent>
            </Tooltip>
          )}
        </div>
        <div className="flex flex-wrap items-baseline gap-1.5">
          <span className="text-2xl leading-none font-medium tracking-tight text-card-foreground tabular-nums">{value}</span>
          {unit && <span className="text-sm font-normal text-muted-foreground">{unit}</span>}
          {change && (
            <Badge className={`gap-0.5 font-normal ${changeClasses[change.state]}`}>
              {ChangeIcon && <ChangeIcon aria-hidden="true" />}
              {change.text}
            </Badge>
          )}
        </div>
        <div className="mt-auto truncate text-[12.5px] leading-tight text-muted-foreground">{subtitleNode}</div>
      </CardContent>
    </Card>
  );
}

export function DashboardOverview({
  firstName,
  plan: _plan,
  overview,
  user,
}: {
  firstName: string;
  plan: PlanCode;
  overview: DashboardOverviewView;
  user: Session["user"];
}) {
  const { t, locale } = useLanguage();
  const o = t.dashboard.overview;
  const d = DISCOVERY_COPY[locale];
  const [dateRange, setDateRange] = useState<DashboardDateRange>(7);
  const dateRangeLabels: Record<DashboardDateRange, string> = {
    7: t.dashboard.topbar.last7Days,
    30: t.dashboard.topbar.last30Days,
    90: t.dashboard.topbar.last90Days,
  };
  const numberFormatter = new Intl.NumberFormat(locale === "es" ? "es-US" : "en-US");
  const compactNumberFormatter = new Intl.NumberFormat(locale === "es" ? "es-US" : "en-US", {
    notation: "compact",
    maximumFractionDigits: 1,
  });
  const dayFormatter = new Intl.DateTimeFormat(locale === "es" ? "es-US" : "en-US", { month: "short", day: "numeric" });

  function formatPrice(price: number, currency: string): string {
    return new Intl.NumberFormat(locale === "es" ? "es-US" : "en-US", {
      style: "currency",
      currency,
      maximumFractionDigits: 2,
    }).format(price);
  }

  function formatMetric(value: number | null, compact = true): string {
    if (value === null) return "—";
    return (compact ? compactNumberFormatter : numberFormatter).format(value);
  }

  function formatPercent(value: number | null): string {
    if (value === null) return "—";
    return new Intl.NumberFormat(locale === "es" ? "es-US" : "en-US", {
      style: "percent",
      maximumFractionDigits: 1,
    }).format(value);
  }

  const visibleTrend = overview.trend.slice(-dateRange);
  /** Recharts-ready rows for the Growth chart — `t` is a real timestamp (not
   * a string) so the x-axis renders a true time scale. `productsScoredCount`
   * is never null, so any 2+ point window is enough real data to plot. */
  const growthChartRows = visibleTrend.map((point) => ({
    t: point.date.getTime(),
    opportunity: point.avgOpportunityScore,
    scored: point.productsScoredCount,
  }));
  const hasChartData = growthChartRows.length >= 2;
  const growthChartConfig = {
    opportunity: { label: o.growth.avgOpportunity, color: "var(--color-blue-500)" },
    scored: { label: o.growth.productsScored, color: "var(--color-violet-500)" },
  } satisfies ChartConfig;

  const CATEGORY_COLORS = ["#2476ff", "#13c6e9", "#38c99d", "#8b38f5", "#cbd1da"];

  const kpi = overview.kpi;
  const kpiCards = buildKpiCards(kpi, o.kpi, (value) => numberFormatter.format(value));
  const kpiIcons: Record<KpiCardKey, ComponentType<{ className?: string; "aria-hidden"?: boolean | "true" | "false" }>> = {
    bestOpportunity: Trophy,
    productsAnalyzed: PackageSearch,
    trending: Flame,
    savedProducts: Bookmark,
  };

  return (
    <div className="flex w-full max-w-[1500px] flex-col gap-4 pb-8">
      <header className="flex flex-wrap items-start justify-between gap-4 pt-0.5">
        <div>
          <h1 className="text-[26px] font-semibold tracking-tight text-foreground sm:text-[30px]">
            {o.welcome.replace("{firstName}", firstName)}! <span aria-hidden="true">👋</span>
          </h1>
          <p className="mt-1 text-sm text-muted-foreground sm:text-base">{o.subtitle}</p>
        </div>
        <div className="flex items-center gap-2">
          <DateRangeMenu
            value={dateRange}
            onChange={setDateRange}
            labels={dateRangeLabels}
            className="inline-flex h-9 items-center gap-2 rounded-lg border border-border bg-card px-3 text-[13px] font-semibold text-foreground shadow-xs transition-colors hover:bg-accent"
          />
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <button
                className="relative flex size-9 items-center justify-center rounded-full border border-border bg-card text-muted-foreground shadow-xs transition-colors hover:bg-accent hover:text-foreground"
                type="button"
                aria-label={o.recentActivity.title}
              >
                <BellIcon className="size-4" />
                {overview.recentActivity.length > 0 && (
                  <span className="absolute top-1.5 right-1.5 size-2 rounded-full bg-destructive ring-2 ring-card" />
                )}
              </button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end" className="w-80">
              <DropdownMenuLabel>{o.recentActivity.title}</DropdownMenuLabel>
              <DropdownMenuSeparator />
              {overview.recentActivity.length === 0 ? (
                <p className="px-2 py-3 text-sm text-muted-foreground">{o.recentActivity.empty}</p>
              ) : (
                <div className="grid gap-1 p-1">
                  {overview.recentActivity.map((activity) => (
                    <div className="rounded-md px-2 py-2 text-sm" key={`${activity.type}-${activity.id}`}>
                      <span className="block truncate font-medium">{activity.label}</span>
                      <time className="text-xs text-muted-foreground" dateTime={activity.occurredAt.toISOString()}>
                        {dayFormatter.format(activity.occurredAt)}
                      </time>
                    </div>
                  ))}
                </div>
              )}
            </DropdownMenuContent>
          </DropdownMenu>
          {/* Real UserMenu (sign out, profile, billing, settings) in place of
              the reference's decorative avatar illustration — the shared
              DashboardTopbar renders nothing on this route (see its isOverview
              branch), so this is the only place that functionality is
              reachable from /dashboard. */}
          <UserMenu user={user} triggerClassName="rounded-full" avatarClassName="size-9" />
        </div>
      </header>

      <section className="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4">
        {kpi.isDemoData && (
          <Badge
            className="col-span-full -mb-0.5 justify-self-end bg-warning/15 font-bold tracking-wide text-warning uppercase"
            title={o.demoDataNotice}
          >
            {o.kpi.demoBadge}
          </Badge>
        )}
        {kpiCards.map((card) => (
          <KpiTile
            key={card.key}
            icon={kpiIcons[card.key]}
            label={card.label}
            value={card.value}
            unit={card.unit}
            change={card.change}
            subtitle={card.subtitle}
            subtitleHref={card.href}
            tooltip={card.tooltip}
          />
        ))}
      </section>

      <Card className="gap-0 overflow-hidden rounded-2xl py-0">
        <div className="flex flex-wrap items-end justify-between gap-4 border-b px-6 py-5">
          <div className="min-w-0">
            <Badge variant="outline" className="mb-2 gap-1.5 border-primary/20 bg-primary/5 font-bold tracking-wider text-primary uppercase">
              <Flame className="size-3" aria-hidden="true" /> {d.eyebrow}
            </Badge>
            <h2 className="text-lg font-semibold tracking-tight text-foreground sm:text-xl">{d.title}</h2>
            <p className="mt-1 max-w-2xl text-xs text-muted-foreground sm:text-sm">{d.subtitle}</p>
          </div>
          <Link className="flex shrink-0 items-center gap-1 text-sm font-semibold text-primary hover:underline" href="/dashboard/products">
            {d.viewAll}
            <ArrowUpRight className="size-3.5" aria-hidden="true" />
          </Link>
        </div>
        {overview.topProducts.length === 0 ? (
          <div className="flex min-h-40 items-center justify-center p-6 text-sm text-muted-foreground">{d.noProducts}</div>
        ) : (
          <motion.div
            className="grid grid-cols-2 gap-3 p-4 sm:grid-cols-3 lg:grid-cols-5"
            initial="hidden"
            whileInView="visible"
            viewport={{ once: true, amount: 0.15 }}
            variants={STAGGER_CONTAINER}
          >
            {overview.topProducts.map((product, index) => {
              const level = product.score ? opportunityLevel(product.score.opportunityScore) : null;
              const tone = level ? scoreTone(level) : "warn";
              return (
                <motion.div
                  key={product.id}
                  variants={STAGGER_ITEM}
                  transition={{ type: "spring", stiffness: 300, damping: 24 }}
                  whileHover={{ y: -3 }}
                >
                  <Link
                    href={`/dashboard/products/${product.id}`}
                    className="group flex h-full flex-col overflow-hidden rounded-xl border bg-card shadow-xs transition-shadow hover:shadow-md"
                  >
                    <div className="relative aspect-square overflow-hidden bg-muted">
                      <Badge className={cn("absolute top-2 left-2 z-10 size-6 justify-center rounded-full p-0 text-[11px] shadow-sm", rankBadgeClasses(index))}>
                        {index + 1}
                      </Badge>
                      <ProductImage
                        src={product.imageUrl}
                        alt={product.canonicalName}
                        className="!size-full !rounded-none !bg-transparent transition-transform duration-300 group-hover:scale-105"
                        sizes="(max-width: 820px) 100vw, 20vw"
                      />
                    </div>
                    <div className="flex flex-1 flex-col gap-1.5 p-3">
                      <h3 className="line-clamp-2 text-[12.5px] leading-snug font-semibold text-card-foreground">{product.canonicalName}</h3>
                      <p className="truncate text-[10.5px] text-muted-foreground">{product.category}</p>
                      <div className="mt-auto flex items-baseline justify-between gap-2">
                        <strong className="text-[13px] font-bold text-card-foreground">
                          {product.currentPrice !== null ? formatPrice(product.currentPrice, product.currency) : "—"}
                        </strong>
                        <span className="text-[10.5px] font-medium whitespace-nowrap text-muted-foreground">
                          {product.sales7d !== null ? formatMetric(product.sales7d) : "—"} {o.snapshot.columns.sales7d}
                        </span>
                      </div>
                      <div className="flex items-center gap-1.5 text-[10px] text-muted-foreground">
                        <Badge className={cn("font-bold tabular-nums", SCORE_BADGE_CLASSES[tone])}>{product.score?.opportunityScore ?? "—"}</Badge>
                        <span>{d.opportunity}</span>
                        {product.growthPercent !== null && (
                          <b className={cn("ml-auto font-bold", product.growthPercent < 0 ? "text-destructive" : "text-success")}>
                            {product.growthPercent > 0 ? "↑" : product.growthPercent < 0 ? "↓" : "→"} {Math.abs(product.growthPercent)}%
                          </b>
                        )}
                      </div>
                    </div>
                  </Link>
                </motion.div>
              );
            })}
          </motion.div>
        )}
      </Card>

      <section className="grid grid-cols-1 gap-4 lg:grid-cols-2">
        <Card className="gap-0 overflow-hidden rounded-2xl py-0">
          <div className="flex items-center justify-between gap-4 border-b px-5 py-4">
            <div className="flex min-w-0 items-center gap-3">
              <span className="flex size-9 shrink-0 items-center justify-center rounded-full bg-cyan-500/10 text-cyan-600 dark:text-cyan-400">
                <Play className="size-4" aria-hidden="true" />
              </span>
              <div className="min-w-0">
                <h2 className="truncate text-[15px] font-semibold text-foreground">{d.topVideos}</h2>
                <p className="truncate text-[11px] text-muted-foreground">{d.topVideosSubtitle}</p>
              </div>
            </div>
            <Link className="flex shrink-0 items-center gap-1 text-sm font-semibold text-primary hover:underline" href="/dashboard/videos">
              {d.viewAll}
              <ArrowUpRight className="size-3.5" aria-hidden="true" />
            </Link>
          </div>
          {overview.topVideos.length === 0 ? (
            <div className="flex flex-col items-center justify-center gap-2 px-6 py-14 text-center">
              <Play className="size-6 text-muted-foreground/70" aria-hidden="true" />
              <p className="text-sm font-semibold text-foreground">{d.noVideos}</p>
              <span className="max-w-xs text-xs text-muted-foreground">{d.videoScope}</span>
            </div>
          ) : (
            <motion.div initial="hidden" whileInView="visible" viewport={{ once: true, amount: 0.2 }} variants={STAGGER_CONTAINER}>
              {overview.topVideos.map((video, index) => (
                <motion.div key={`${video.product.id}-${video.capturedAt.toISOString()}`} variants={STAGGER_ITEM}>
                  <Link
                    href={`/dashboard/products/${video.product.id}`}
                    className="flex items-center gap-3 border-b px-5 py-3 transition-colors last:border-b-0 hover:bg-muted/50"
                  >
                    <Badge className={cn("size-6 shrink-0 justify-center rounded-full p-0 text-[11px]", rankBadgeClasses(index))}>{index + 1}</Badge>
                    <span className="relative size-11 shrink-0 overflow-hidden rounded-lg border bg-muted">
                      <ProductImage src={video.product.imageUrl} alt={video.product.canonicalName} className="!size-full !rounded-none !bg-transparent" sizes="52px" />
                      <i className="absolute right-1 bottom-1 flex size-4 items-center justify-center rounded-full bg-black/70 not-italic text-white">
                        <Play className="size-2" fill="currentColor" aria-hidden="true" />
                      </i>
                    </span>
                    <span className="min-w-0 flex-1">
                      <strong className="block truncate text-[12.5px] font-semibold text-foreground">{video.product.canonicalName}</strong>
                      <small className="block truncate text-[10.5px] text-muted-foreground">
                        {video.creator?.displayName ?? video.creator?.handle ?? video.product.category}
                      </small>
                    </span>
                    <span className="flex w-16 shrink-0 flex-col items-end gap-0.5 text-right">
                      <b className="text-xs font-bold text-foreground">{formatMetric(video.views)}</b>
                      <small className="flex items-center gap-1 text-[9.5px] text-muted-foreground">
                        <Eye className="size-2.5" aria-hidden="true" /> {d.views}
                      </small>
                    </span>
                    <span className="flex w-16 shrink-0 flex-col items-end gap-0.5 text-right">
                      <b className="text-xs font-bold text-foreground">{formatPercent(video.engagement)}</b>
                      <small className="text-[9.5px] text-muted-foreground">{d.engagement}</small>
                    </span>
                  </Link>
                </motion.div>
              ))}
            </motion.div>
          )}
        </Card>

        <Card className="gap-0 overflow-hidden rounded-2xl py-0">
          <div className="flex items-center justify-between gap-4 border-b px-5 py-4">
            <div className="flex min-w-0 items-center gap-3">
              <span className="flex size-9 shrink-0 items-center justify-center rounded-full bg-purple-500/10 text-purple-600 dark:text-purple-400">
                <Users className="size-4" aria-hidden="true" />
              </span>
              <div className="min-w-0">
                <h2 className="truncate text-[15px] font-semibold text-foreground">{d.topInfluencers}</h2>
                <p className="truncate text-[11px] text-muted-foreground">{d.topInfluencersSubtitle}</p>
              </div>
            </div>
            <Link className="flex shrink-0 items-center gap-1 text-sm font-semibold text-primary hover:underline" href="/dashboard/creators">
              {d.viewAll}
              <ArrowUpRight className="size-3.5" aria-hidden="true" />
            </Link>
          </div>
          {overview.topCreators.length === 0 ? (
            <div className="flex flex-col items-center justify-center gap-2 px-6 py-14 text-center">
              <Users className="size-6 text-muted-foreground/70" aria-hidden="true" />
              <p className="text-sm font-semibold text-foreground">{d.noCreators}</p>
            </div>
          ) : (
            <motion.div initial="hidden" whileInView="visible" viewport={{ once: true, amount: 0.2 }} variants={STAGGER_CONTAINER}>
              {overview.topCreators.map((creator, index) => {
                const name = creator.displayName ?? creator.handle ?? "Creator";
                return (
                  <motion.div key={creator.id} variants={STAGGER_ITEM}>
                    <Link
                      href={`/dashboard/creators/${creator.id}`}
                      className="flex items-center gap-3 border-b px-5 py-3 transition-colors last:border-b-0 hover:bg-muted/50"
                    >
                      <Badge className={cn("size-6 shrink-0 justify-center rounded-full p-0 text-[11px]", rankBadgeClasses(index))}>{index + 1}</Badge>
                      <Avatar className="size-9 shrink-0">
                        {creator.avatarUrl && <AvatarImage src={creator.avatarUrl} alt={name} />}
                        <AvatarFallback>{initials(name)}</AvatarFallback>
                      </Avatar>
                      <span className="min-w-0 flex-1">
                        <strong className="block truncate text-[12.5px] font-semibold text-foreground">{name}</strong>
                        <small className="block truncate text-[10.5px] text-muted-foreground">
                          {creator.handle ? `@${creator.handle}` : creator.followerCount !== null ? `${formatMetric(creator.followerCount)} ${d.followers}` : d.influence}
                        </small>
                      </span>
                      <span className="flex w-14 shrink-0 flex-col items-end gap-0.5 text-right">
                        <b className="text-xs font-bold text-foreground">{creator.estimatedInfluence ?? "—"}</b>
                        <small className="text-[9.5px] text-muted-foreground">{d.influence}</small>
                      </span>
                      <span className="flex w-20 shrink-0 flex-col items-end gap-0.5 text-right">
                        <b className="text-xs font-bold text-foreground">{creator.attributedSales !== null ? formatMetric(creator.attributedSales, false) : "—"}</b>
                        <small className="text-[9.5px] text-muted-foreground">{d.attributedSales}</small>
                      </span>
                    </Link>
                  </motion.div>
                );
              })}
            </motion.div>
          )}
        </Card>
      </section>

      <section className="grid grid-cols-1 gap-4 lg:grid-cols-[1.15fr_.85fr]">
        <Card className="gap-0 overflow-hidden rounded-2xl py-0">
          <div className="flex items-center justify-between gap-4 border-b px-5 py-4">
            <div className="flex items-center gap-3">
              <span className="flex size-9 shrink-0 items-center justify-center rounded-full bg-orange-500/10 text-orange-600 dark:text-orange-400">
                <TrendingUp className="size-4" aria-hidden="true" />
              </span>
              <div>
                <h2 className="text-[15px] font-semibold text-foreground">{d.hotCategories}</h2>
                <p className="text-[11px] text-muted-foreground">{d.hotCategoriesSubtitle}</p>
              </div>
            </div>
            <Link className="flex shrink-0 items-center gap-1 text-sm font-semibold text-primary hover:underline" href="/dashboard/trends">
              {d.viewAll}
              <ArrowUpRight className="size-3.5" aria-hidden="true" />
            </Link>
          </div>
          {overview.hotCategories.length === 0 ? (
            <div className="flex flex-col items-center justify-center gap-2 px-6 py-14 text-center">
              <TrendingUp className="size-6 text-muted-foreground/70" aria-hidden="true" />
              <p className="text-sm font-semibold text-foreground">{d.noCategories}</p>
            </div>
          ) : (
            <div className="flex flex-col gap-4 p-5">
              {overview.hotCategories.map((category, index) => {
                const strongest = category.trendScore ?? category.opportunityScore;
                const width = strongest === null ? 0 : Math.max(0, Math.min(100, strongest));
                const color = CATEGORY_COLORS[index % CATEGORY_COLORS.length];
                return (
                  <div className="flex flex-col gap-1.5" key={category.category}>
                    <div className="flex items-center justify-between gap-3 text-[12px]">
                      <span className="flex min-w-0 items-center gap-2 truncate font-semibold text-foreground">
                        <i className="size-2 shrink-0 rounded-full" style={{ background: color }} />
                        {category.category}
                      </span>
                      <b className="shrink-0 text-[10.5px] font-medium text-muted-foreground">
                        {category.productCount} {d.products}
                      </b>
                    </div>
                    <div className="h-1.5 overflow-hidden rounded-full bg-muted">
                      <div className="h-full rounded-full" style={{ width: `${width}%`, background: color }} />
                    </div>
                    <div className="flex justify-between text-[10.5px] text-muted-foreground">
                      <span>
                        {d.trend}: <b className="font-semibold text-foreground">{category.trendScore ?? "—"}</b>
                      </span>
                      <span>
                        {d.opportunity}: <b className="font-semibold text-foreground">{category.opportunityScore ?? "—"}</b>
                      </span>
                    </div>
                  </div>
                );
              })}
            </div>
          )}
        </Card>

        <Card className="gap-0 overflow-hidden rounded-2xl py-0">
          <div className="flex flex-wrap items-center justify-between gap-3 border-b px-5 py-4">
            <h2 className="text-[15px] font-semibold text-foreground">{d.growth}</h2>
            <DateRangeMenu
              value={dateRange}
              onChange={setDateRange}
              labels={dateRangeLabels}
              showCalendar={false}
              className="inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-card px-2.5 text-xs font-semibold text-foreground shadow-xs transition-colors hover:bg-accent"
            />
          </div>
          <div className="p-5">
            {!hasChartData ? (
              <p className="flex min-h-[230px] items-center justify-center text-center text-sm text-muted-foreground">{o.growth.insufficientData}</p>
            ) : (
              <>
                <div className="mb-3 flex gap-4 text-[11.5px] font-semibold text-muted-foreground">
                  <span className="flex items-center gap-1.5">
                    <i className="inline-block h-0.5 w-3 rounded-full" style={{ background: "var(--color-blue-500)" }} />
                    {o.growth.avgOpportunity}
                  </span>
                  <span className="flex items-center gap-1.5">
                    <i className="inline-block h-0.5 w-3 rounded-full" style={{ background: "var(--color-violet-500)" }} />
                    {o.growth.productsScored}
                  </span>
                </div>
                <ChartContainer config={growthChartConfig} className="aspect-auto h-[230px] w-full">
                  <AreaChart data={growthChartRows} margin={{ left: 0, right: 8, top: 8, bottom: 0 }}>
                    <defs>
                      <linearGradient id="overviewOpportunityFill" x1="0" y1="0" x2="0" y2="1">
                        <stop offset="0%" stopColor="var(--color-opportunity)" stopOpacity={0.25} />
                        <stop offset="100%" stopColor="var(--color-opportunity)" stopOpacity={0} />
                      </linearGradient>
                      <linearGradient id="overviewScoredFill" x1="0" y1="0" x2="0" y2="1">
                        <stop offset="0%" stopColor="var(--color-scored)" stopOpacity={0.2} />
                        <stop offset="100%" stopColor="var(--color-scored)" stopOpacity={0} />
                      </linearGradient>
                    </defs>
                    <CartesianGrid vertical={false} strokeDasharray="3 3" />
                    <XAxis
                      dataKey="t"
                      type="number"
                      scale="time"
                      domain={["dataMin", "dataMax"]}
                      tickLine={false}
                      axisLine={false}
                      tickMargin={8}
                      fontSize={11}
                      tickFormatter={(value) => dayFormatter.format(new Date(value))}
                    />
                    <YAxis yAxisId="opportunity" hide domain={[0, 100]} />
                    <YAxis yAxisId="scored" hide domain={[0, "dataMax + 2"]} />
                    <ChartTooltip
                      content={
                        <ChartTooltipContent
                          labelFormatter={(_value, payload) => {
                            const t = payload?.[0]?.payload?.t;
                            return typeof t === "number" ? dayFormatter.format(new Date(t)) : "";
                          }}
                        />
                      }
                    />
                    <Area
                      yAxisId="opportunity"
                      dataKey="opportunity"
                      type="monotone"
                      stroke="var(--color-opportunity)"
                      fill="url(#overviewOpportunityFill)"
                      strokeWidth={2.5}
                      connectNulls
                    />
                    <Area
                      yAxisId="scored"
                      dataKey="scored"
                      type="monotone"
                      stroke="var(--color-scored)"
                      fill="url(#overviewScoredFill)"
                      strokeWidth={2.5}
                      connectNulls
                    />
                  </AreaChart>
                </ChartContainer>
              </>
            )}
          </div>
        </Card>
      </section>
    </div>
  );
}
