"use client";

import { useEffect, useRef, useState, useTransition } from "react";
import { useRouter, usePathname } from "next/navigation";
import Link from "next/link";
import { motion } from "motion/react";
import { ArrowUpDown, Bookmark, BookmarkCheck, ChevronDown, ChevronLeft, ChevronRight, Download, Eye, Flame, Loader2, Search, Settings2, Sparkles, TrendingUp as TrendingUpIcon, UserRound, X } from "lucide-react";
import { toast } from "sonner";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Checkbox } from "@/components/ui/checkbox";
import { Card } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { ProductImage } from "@/components/dashboard/product-image";
import { ProductQuickView } from "@/components/dashboard/product-quick-view";
import { DemoBadge } from "@/components/dashboard/demo-badge";
import { saveProductAction, unsaveProductAction } from "@/actions/product-actions";
import { useLanguage } from "@/lib/i18n/context";
import { cn } from "@/lib/utils";
import { STAGGER_CONTAINER, STAGGER_ITEM } from "@/components/dashboard/motion-variants";
import type { ProductCardView } from "@/lib/product-data/view-models";
import type { ProductAvailabilityFilter, ProductMarketMetricView, ProductSortKey } from "@/database/products";

export interface ProductsFilterState {
  q?: string;
  category?: string;
  minPrice?: number;
  maxPrice?: number;
  minOpportunity?: number;
  minTrend?: number;
  maxSaturation?: number;
  minConfidence?: number;
  minGrowthVelocity?: number;
  minDemandAcceleration?: number;
  maxRisk?: number;
  minCompetitionTrend?: number;
  minGrowth?: number;
  minMomentum?: number;
  savedOnly?: boolean;
  availability?: ProductAvailabilityFilter;
  upstreamStatus?: string;
}

export type ProductCatalogVariant = "marketExplorer" | "products";

const SORT_KEYS: ProductSortKey[] = [
  "opportunity",
  "trend",
  "saturation",
  "demand",
  "confidence",
  "growthVelocity",
  "demandAcceleration",
  "risk",
  "competitionTrend",
  "momentum",
  "mostSaved",
  "newest",
  "priceAsc",
  "priceDesc",
];

const SORT_LABEL_KEY: Record<ProductSortKey, string> = {
  opportunity: "highestOpportunity",
  trend: "fastestGrowing",
  saturation: "lowestSaturation",
  demand: "highestDemand",
  confidence: "highestConfidence",
  growthVelocity: "highestGrowthVelocity",
  demandAcceleration: "highestDemandAcceleration",
  risk: "lowestRisk",
  competitionTrend: "strongestCompetitionTrend",
  momentum: "highestMomentum",
  mostSaved: "mostSaved",
  newest: "newest",
  priceAsc: "priceLowToHigh",
  priceDesc: "priceHighToLow",
};

const DEBOUNCE_MS = 400;

const MARKET_COPY = {
  en: {
    eyebrow: "TokNext market intelligence",
    subtitle: "Discover products with the strongest opportunity, momentum and creator signals.",
    catalog: "Active catalog",
    viewing: "Viewing",
    customize: "Customize",
    export: "Export",
    hotLaunches: "Hot new launches",
    hotLaunchesDesc: "Recently listed products",
    opportunities: "Undiscovered opportunities",
    opportunitiesDesc: "Products showing explosive growth trends",
    organic: "Organic top performers",
    organicDesc: "Top products trending without paid ads",
    influencer: "Influencer-driven winners",
    influencerDesc: "Winning products powered by top influencers",
    product: "Products",
    shop: "Shop",
    sold: "Items sold",
    trend: "Items sold trend",
    gmv: "GMV",
    risk: "Risk",
    unavailable: "—",
    sevenDays: "Last 7 days",
    noSignals: "No metric signals are available for this product yet.",
  },
  es: {
    eyebrow: "Inteligencia de mercado TokNext",
    subtitle: "Descubre productos con las mejores señales de oportunidad, momentum y creadores.",
    catalog: "Catálogo activo",
    viewing: "Viendo",
    customize: "Personalizar",
    export: "Exportar",
    hotLaunches: "Lanzamientos recientes",
    hotLaunchesDesc: "Productos listados recientemente",
    opportunities: "Oportunidades ocultas",
    opportunitiesDesc: "Productos con tendencias de crecimiento explosivas",
    organic: "Top performers orgánicos",
    organicDesc: "Productos en tendencia sin anuncios pagados",
    influencer: "Ganadores de influencers",
    influencerDesc: "Productos impulsados por los mejores creadores",
    product: "Productos",
    shop: "Tienda",
    sold: "Unidades vendidas",
    trend: "Tendencia de ventas",
    gmv: "GMV",
    risk: "Riesgo",
    unavailable: "—",
    sevenDays: "Últimos 7 días",
    noSignals: "Todavía no hay señales métricas para este producto.",
  },
} as const;

function formatPrice(price: number, currency: string, locale: "en" | "es"): string {
  return new Intl.NumberFormat(locale === "es" ? "es-US" : "en-US", {
    style: "currency",
    currency,
    maximumFractionDigits: 2,
  }).format(price);
}

function ScoreCell({ value }: { value: number | null | undefined }) {
  if (value === null || value === undefined) return <span className="text-muted-foreground">—</span>;
  const tone = value >= 70 ? "text-success" : value >= 40 ? "text-foreground" : "text-muted-foreground";
  return <span className={`font-medium tabular-nums ${tone}`}>{value}</span>;
}

function SaveButton({
  productId,
  initiallySaved,
  label,
  savedLabel,
}: {
  productId: string;
  initiallySaved: boolean;
  label: string;
  savedLabel: string;
}) {
  const { locale } = useLanguage();
  const [saved, setSaved] = useState(initiallySaved);
  const [isPending, startTransition] = useTransition();

  function toggleSave() {
    const next = !saved;
    setSaved(next);
    startTransition(async () => {
      const result = next
        ? await saveProductAction(productId, locale)
        : await unsaveProductAction(productId, locale);
      if (!result.success) {
        setSaved(!next);
        toast.error(result.error);
      }
    });
  }

  return (
    <Button
      variant="ghost"
      size="icon"
      className="size-8"
      onClick={toggleSave}
      disabled={isPending}
      aria-pressed={saved}
      aria-label={saved ? savedLabel : label}
    >
      {saved ? <BookmarkCheck className="size-4 text-primary" /> : <Bookmark className="size-4" />}
    </Button>
  );
}

export function ProductsPageContent({
  variant = "products",
  products,
  categories,
  total,
  page,
  pageSize,
  sort,
  savedProductIds,
  filters,
  statuses,
  loadError,
  marketMetrics,
}: {
  variant?: ProductCatalogVariant;
  products: ProductCardView[];
  categories: string[];
  statuses: string[];
  total: number;
  page: number;
  pageSize: number;
  sort: ProductSortKey;
  savedProductIds: string[];
  filters: ProductsFilterState;
  loadError: boolean;
  marketMetrics: Record<string, ProductMarketMetricView>;
}) {
  const { t, locale } = useLanguage();
  const c = t.productCatalog;
  const market = MARKET_COPY[locale];
  const isMarketExplorer = variant === "marketExplorer";
  const title = variant === "marketExplorer" ? c.marketExplorerTitle : c.title;
  const description = variant === "marketExplorer" ? c.marketExplorerDescription : c.description;
  const router = useRouter();
  const pathname = usePathname();
  const [isPending, startTransition] = useTransition();
  const savedSet = new Set(savedProductIds);
  const [quickViewId, setQuickViewId] = useState<string | null>(null);

  const [q, setQ] = useState(filters.q ?? "");
  const [minPrice, setMinPrice] = useState(filters.minPrice?.toString() ?? "");
  const [maxPrice, setMaxPrice] = useState(filters.maxPrice?.toString() ?? "");
  const [minOpportunity, setMinOpportunity] = useState(filters.minOpportunity?.toString() ?? "");
  const [minTrend, setMinTrend] = useState(filters.minTrend?.toString() ?? "");
  const [maxSaturation, setMaxSaturation] = useState(filters.maxSaturation?.toString() ?? "");
  const [minConfidence, setMinConfidence] = useState(filters.minConfidence?.toString() ?? "");
  const [minGrowthVelocity, setMinGrowthVelocity] = useState(filters.minGrowthVelocity?.toString() ?? "");
  const [minDemandAcceleration, setMinDemandAcceleration] = useState(filters.minDemandAcceleration?.toString() ?? "");
  const [maxRisk, setMaxRisk] = useState(filters.maxRisk?.toString() ?? "");
  const [minCompetitionTrend, setMinCompetitionTrend] = useState(filters.minCompetitionTrend?.toString() ?? "");
  const [minGrowth, setMinGrowth] = useState(filters.minGrowth?.toString() ?? "");
  const [minMomentum, setMinMomentum] = useState(filters.minMomentum?.toString() ?? "");

  const isFirstRender = useRef(true);

  const hasAdvancedFilterValues = Boolean(
    filters.minPrice !== undefined ||
      filters.maxPrice !== undefined ||
      filters.minOpportunity !== undefined ||
      filters.minTrend !== undefined ||
      filters.maxSaturation !== undefined ||
      filters.minConfidence !== undefined ||
      filters.minGrowthVelocity !== undefined ||
      filters.minDemandAcceleration !== undefined ||
      filters.maxRisk !== undefined ||
      filters.minCompetitionTrend !== undefined ||
      filters.minGrowth !== undefined ||
      filters.minMomentum !== undefined ||
      filters.savedOnly ||
      (filters.availability !== undefined && filters.availability !== "active") ||
      filters.upstreamStatus,
  );
  const [showAdvanced, setShowAdvanced] = useState(hasAdvancedFilterValues);

  function navigate(overrides: Record<string, string | undefined>) {
    const params = new URLSearchParams();
    const current: Record<string, string | undefined> = {
      q,
      category: filters.category,
      minPrice,
      maxPrice,
      minOpportunity,
      minTrend,
      maxSaturation,
      minConfidence,
      minGrowthVelocity,
      minDemandAcceleration,
      maxRisk,
      minCompetitionTrend,
      minGrowth,
      minMomentum,
      savedOnly: filters.savedOnly ? "true" : undefined,
      availability: filters.availability && filters.availability !== "active" ? filters.availability : undefined,
      upstreamStatus: filters.upstreamStatus,
      sort,
      page: String(page),
      pageSize: String(pageSize),
      ...overrides,
    };
    for (const [key, value] of Object.entries(current)) {
      if (value !== undefined && value !== "") params.set(key, value);
    }
    // Any filter change (other than pagination itself) resets to page 1.
    if (!("page" in overrides)) params.set("page", "1");
    startTransition(() => {
      router.push(`${pathname}?${params.toString()}`);
    });
  }

  // Debounce the free-text search and numeric filter inputs so every
  // keystroke doesn't trigger a server round trip.
  useEffect(() => {
    if (isFirstRender.current) {
      isFirstRender.current = false;
      return;
    }
    const timer = setTimeout(() => {
      navigate({
        q,
        minPrice,
        maxPrice,
        minOpportunity,
        minTrend,
        maxSaturation,
        minConfidence,
        minGrowthVelocity,
        minDemandAcceleration,
        maxRisk,
        minCompetitionTrend,
        minGrowth,
        minMomentum,
      });
    }, DEBOUNCE_MS);
    return () => clearTimeout(timer);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [
    q,
    minPrice,
    maxPrice,
    minOpportunity,
    minTrend,
    maxSaturation,
    minConfidence,
    minGrowthVelocity,
    minDemandAcceleration,
    maxRisk,
    minCompetitionTrend,
    minGrowth,
    minMomentum,
  ]);

  function handleClearFilters() {
    setQ("");
    setMinPrice("");
    setMaxPrice("");
    setMinOpportunity("");
    setMinTrend("");
    setMaxSaturation("");
    setMinConfidence("");
    setMinGrowthVelocity("");
    setMinDemandAcceleration("");
    setMaxRisk("");
    setMinCompetitionTrend("");
    setMinGrowth("");
    setMinMomentum("");
    startTransition(() => router.push(pathname));
  }

  const hasActiveFilters = Boolean(filters.q || filters.category || hasAdvancedFilterValues);
  const totalPages = Math.max(1, Math.ceil(total / pageSize));

  const insightCards = [
    {
      href: `${pathname}?sort=newest&page=1`,
      icon: Flame,
      iconClasses: "bg-red-500/10 text-red-600 dark:text-red-400",
      title: market.hotLaunches,
      description: market.hotLaunchesDesc,
    },
    {
      href: `${pathname}?sort=opportunity&page=1`,
      icon: Sparkles,
      iconClasses: "bg-blue-500/10 text-blue-600 dark:text-blue-400",
      title: market.opportunities,
      description: market.opportunitiesDesc,
    },
    {
      href: `${pathname}?sort=trend&page=1`,
      icon: TrendingUpIcon,
      iconClasses: "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400",
      title: market.organic,
      description: market.organicDesc,
    },
    {
      href: "/dashboard/creators",
      icon: UserRound,
      iconClasses: "bg-orange-500/10 text-orange-600 dark:text-orange-400",
      title: market.influencer,
      description: market.influencerDesc,
    },
  ];

  return (
    <div className="flex w-full max-w-[1500px] flex-col gap-4 pb-8">
      <div className={cn("flex flex-wrap items-end justify-between gap-4 pt-0.5", isMarketExplorer && "items-start")}>
        <div>
          {isMarketExplorer && (
            <span className="mb-2 inline-flex items-center gap-1.5 text-[10px] font-extrabold tracking-[0.14em] text-primary uppercase">
              <Sparkles className="size-3.5 text-teal-500" aria-hidden="true" /> {market.eyebrow}
            </span>
          )}
          <h1 className="text-[26px] font-semibold tracking-tight text-foreground sm:text-[28px]">{title}</h1>
          <p className="mt-1 max-w-2xl text-sm text-muted-foreground">{isMarketExplorer ? market.subtitle : description}</p>
        </div>
        {isMarketExplorer && (
          <Badge variant="outline" className="shrink-0 self-start rounded-full border-border bg-card px-3 py-1.5 text-[11px] font-semibold text-muted-foreground">
            {market.catalog}
          </Badge>
        )}
      </div>

      <Card className="rounded-2xl p-4 shadow-xs">
        <div className="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-[minmax(240px,1fr)_200px_220px_auto]">
          <div className="relative min-w-0">
            <Search className="pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-muted-foreground" aria-hidden="true" />
            <Input
              value={q}
              onChange={(e) => setQ(e.target.value)}
              placeholder={c.search}
              className="pl-9"
              aria-label={c.search}
            />
          </div>
          <Select
            value={filters.category ?? "all"}
            onValueChange={(value) => navigate({ category: value === "all" ? undefined : value })}
          >
            <SelectTrigger aria-label={c.filters.category} className="w-full">
              <SelectValue placeholder={c.filters.allCategories} />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">{c.filters.allCategories}</SelectItem>
              {categories.map((category) => (
                <SelectItem key={category} value={category}>
                  {category}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Select value={sort} onValueChange={(value) => navigate({ sort: value })}>
            <SelectTrigger aria-label={c.sort.label} className="w-full">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {SORT_KEYS.map((key) => (
                <SelectItem key={key} value={key}>
                  {c.sort[SORT_LABEL_KEY[key] as keyof typeof c.sort]}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Button
            variant="outline"
            size="sm"
            onClick={() => setShowAdvanced((v) => !v)}
            aria-expanded={showAdvanced}
          >
            {showAdvanced ? c.filters.hideAdvanced : c.filters.showAdvanced}
            <ChevronDown className={cn("size-3.5 transition-transform", showAdvanced && "rotate-180")} />
          </Button>
        </div>

        {showAdvanced && (
          <div className="mt-4 flex flex-col gap-4 border-t pt-4">
            <div className="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-6">
              {[
                { id: "minPrice", label: c.filters.minPrice, value: minPrice, set: setMinPrice, max: undefined },
                { id: "maxPrice", label: c.filters.maxPrice, value: maxPrice, set: setMaxPrice, max: undefined },
                { id: "minOpportunity", label: c.filters.opportunity, value: minOpportunity, set: setMinOpportunity, max: 100 },
                { id: "minTrend", label: c.filters.trend, value: minTrend, set: setMinTrend, max: 100 },
                { id: "maxSaturation", label: c.filters.saturation, value: maxSaturation, set: setMaxSaturation, max: 100 },
                { id: "minConfidence", label: c.filters.confidence, value: minConfidence, set: setMinConfidence, max: 100 },
                { id: "minGrowthVelocity", label: c.filters.growthVelocity, value: minGrowthVelocity, set: setMinGrowthVelocity, max: 100 },
                { id: "minDemandAcceleration", label: c.filters.demandAcceleration, value: minDemandAcceleration, set: setMinDemandAcceleration, max: 100 },
                { id: "maxRisk", label: c.filters.risk, value: maxRisk, set: setMaxRisk, max: 100 },
                { id: "minCompetitionTrend", label: c.filters.competitionTrend, value: minCompetitionTrend, set: setMinCompetitionTrend, max: 100 },
                { id: "minGrowth", label: c.filters.growth, value: minGrowth, set: setMinGrowth, max: 100 },
                { id: "minMomentum", label: c.filters.momentum, value: minMomentum, set: setMinMomentum, max: 100 },
              ].map((field) => (
                <div key={field.id} className="flex flex-col gap-1">
                  <Label htmlFor={field.id} className="text-xs text-muted-foreground">
                    {field.label}
                  </Label>
                  <Input
                    id={field.id}
                    type="number"
                    min={0}
                    max={field.max}
                    value={field.value}
                    onChange={(e) => field.set(e.target.value)}
                  />
                </div>
              ))}
            </div>

            <div className="grid grid-cols-1 items-center gap-3 sm:grid-cols-3">
              <Select
                value={filters.availability ?? "active"}
                onValueChange={(value) => navigate({ availability: value === "active" ? undefined : value })}
              >
                <SelectTrigger aria-label={c.filters.availability} className="w-full">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="active">{c.filters.activeProducts}</SelectItem>
                  <SelectItem value="inactive">{c.filters.inactiveProducts}</SelectItem>
                  <SelectItem value="deleted">{c.filters.deletedProducts}</SelectItem>
                  <SelectItem value="all">{c.filters.allProducts}</SelectItem>
                </SelectContent>
              </Select>

              <Select
                value={filters.upstreamStatus ?? "all"}
                onValueChange={(value) => navigate({ upstreamStatus: value === "all" ? undefined : value })}
              >
                <SelectTrigger aria-label={c.filters.upstreamStatus} className="w-full">
                  <SelectValue placeholder={c.filters.allStatuses} />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">{c.filters.allStatuses}</SelectItem>
                  {statuses.map((status) => (
                    <SelectItem key={status} value={status}>
                      {status}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>

              <label className="flex h-9 items-center gap-2 px-1 text-sm text-foreground">
                <Checkbox
                  checked={Boolean(filters.savedOnly)}
                  onCheckedChange={(checked) => navigate({ savedOnly: checked ? "true" : undefined })}
                  aria-label={c.filters.savedOnly}
                />
                {c.filters.savedOnly}
              </label>
            </div>
          </div>
        )}

        {hasActiveFilters && (
          <Button variant="ghost" size="sm" className="mt-3 w-fit text-muted-foreground" onClick={handleClearFilters}>
            <X className="size-3.5" />
            {c.filters.clear}
          </Button>
        )}
      </Card>

      {isMarketExplorer && (
        <motion.div
          className="grid grid-cols-1 gap-3 sm:grid-cols-2"
          initial="hidden"
          whileInView="visible"
          viewport={{ once: true, amount: 0.2 }}
          variants={STAGGER_CONTAINER}
        >
          {insightCards.map((card) => (
            <motion.div key={card.href} variants={STAGGER_ITEM} whileHover={{ y: -2 }}>
              <Link
                href={card.href}
                className="flex min-h-24 items-center gap-3 rounded-2xl border bg-card px-5 py-4 shadow-xs transition-shadow hover:shadow-md"
              >
                <span className={cn("flex size-9 shrink-0 items-center justify-center rounded-lg", card.iconClasses)}>
                  <card.icon className="size-4" aria-hidden="true" />
                </span>
                <span className="flex min-w-0 flex-1 flex-col gap-0.5">
                  <strong className="text-[15px] font-bold text-foreground">{card.title}</strong>
                  <small className="text-xs text-muted-foreground">{card.description}</small>
                </span>
                <ArrowUpDown className="size-3.5 shrink-0 rotate-45 text-muted-foreground/70" aria-hidden="true" />
              </Link>
            </motion.div>
          ))}
        </motion.div>
      )}

      <Card className="gap-0 overflow-hidden rounded-2xl py-0">
        <div className="flex flex-wrap items-center gap-4 border-b px-5 py-4">
          <div className="flex min-w-0 flex-col gap-0.5">
            <strong className="text-[15px] font-bold text-foreground">
              {isMarketExplorer
                ? `${market.viewing} ${new Intl.NumberFormat(locale).format(total)} ${market.product.toLowerCase()}`
                : c.resultsCount.replace("{count}", new Intl.NumberFormat(locale).format(total))}
            </strong>
            {isMarketExplorer && <span className="text-[11px] text-muted-foreground">{market.sevenDays}</span>}
          </div>
          {isPending && <Loader2 className="size-4 animate-spin text-muted-foreground" />}
          {isMarketExplorer && (
            <div className="ml-auto flex gap-2">
              <Button variant="outline" size="sm" onClick={() => setShowAdvanced(true)}>
                <Settings2 className="size-3.5" />
                {market.customize}
              </Button>
              <Button asChild size="sm">
                <Link href="/api/dashboard/reports/products.csv">
                  <Download className="size-3.5" />
                  {market.export}
                </Link>
              </Button>
            </div>
          )}
        </div>

          {loadError ? (
            <div className="flex min-h-56 flex-col items-center justify-center gap-1 px-5 text-center">
              <p className="text-sm font-semibold text-foreground">{c.error}</p>
            </div>
          ) : products.length === 0 ? (
            <div className="flex min-h-56 flex-col items-center justify-center gap-1 px-5 text-center">
              <p className="text-sm font-semibold text-foreground">{c.empty}</p>
            </div>
          ) : (
            <div className="overflow-x-auto">
              {isMarketExplorer ? (
                <table className="w-full min-w-[980px] table-fixed border-collapse text-left text-sm">
                  <colgroup>
                    <col className="w-[24%]" />
                    <col className="w-[13%]" />
                    <col className="w-[9%]" />
                    <col className="w-[10%]" />
                    <col className="w-[9%]" />
                    <col className="w-[11%]" />
                    <col className="w-[8%]" />
                    <col className="w-[7%]" />
                    <col className="w-[9%]" />
                  </colgroup>
                  <thead>
                    <tr className="border-b border-border text-xs text-muted-foreground">
                      <th className="py-2.5 pr-3 font-medium">{market.product}</th>
                      <th className="py-2.5 pr-3 font-medium">{market.shop}</th>
                      <th className="py-2.5 pr-3 text-right font-medium">{c.table.price}</th>
                      <th className="py-2.5 pr-3 text-right font-medium">
                        {market.sold}
                        <small className="block font-normal text-muted-foreground/70 normal-case">{market.sevenDays}</small>
                      </th>
                      <th className="py-2.5 pr-3 text-center font-medium">{market.trend}</th>
                      <th className="py-2.5 pr-3 text-right font-medium">
                        {market.gmv}
                        <small className="block font-normal text-muted-foreground/70 normal-case">{market.sevenDays}</small>
                      </th>
                      <th className="py-2.5 pr-3 text-center font-medium">{c.table.opportunity}</th>
                      <th className="py-2.5 pr-3 text-center font-medium">{market.risk}</th>
                      <th className="py-2.5 pl-3"><span className="sr-only">{c.table.quickView}</span></th>
                    </tr>
                  </thead>
                  <tbody>
                    {products.map((product) => {
                      const metrics = marketMetrics[product.id];
                      const trend = metrics?.unitsSoldTrend7d ?? null;
                      return (
                        <tr key={product.id} className="border-b border-border last:border-0 hover:bg-secondary/30">
                          <td className="py-2.5 pr-3">
                            <Link href={`/dashboard/products/${product.id}`} className="flex items-center gap-2.5">
                              <Bookmark className="size-4 shrink-0 text-muted-foreground" aria-hidden="true" />
                              <ProductImage src={product.imageUrl} alt={product.canonicalName} className="size-12 shrink-0 rounded-lg border" sizes="48px" />
                              <span className="flex min-w-0 flex-col gap-0.5">
                                <strong className="truncate text-[12.5px] font-bold text-foreground">{product.canonicalName}</strong>
                                <small className="truncate text-[10.5px] text-muted-foreground">{product.brand ?? product.category}</small>
                                <span className="flex min-w-0 items-center gap-1.5">
                                  <span className="truncate text-[10.5px] text-muted-foreground/80">{product.category}</span>
                                  {product.isDemo && <DemoBadge className="shrink-0" />}
                                </span>
                              </span>
                            </Link>
                          </td>
                          <td className="py-2.5 pr-3">
                            <div className="flex min-w-0 items-center gap-2">
                              <span className="flex size-8 shrink-0 items-center justify-center rounded-lg border bg-muted text-xs font-bold text-foreground">
                                {product.storeName ? product.storeName.slice(0, 1).toUpperCase() : "—"}
                              </span>
                              <span className="flex min-w-0 flex-col gap-0.5">
                                <strong className="truncate text-[11.5px] font-semibold text-foreground">{product.storeName ?? c.table.unknownStore}</strong>
                                <small className="truncate text-[10px] text-muted-foreground">{product.brand ?? "TokNext catalog"}</small>
                              </span>
                            </div>
                          </td>
                          <td className="py-2.5 pr-3 text-right tabular-nums whitespace-nowrap text-foreground">
                            {product.currentPrice !== null ? formatPrice(product.currentPrice, product.currency, locale) : market.unavailable}
                          </td>
                          <td className="py-2.5 pr-3 text-right font-semibold tabular-nums whitespace-nowrap text-foreground">
                            {metrics?.unitsSold7d !== null && metrics?.unitsSold7d !== undefined ? new Intl.NumberFormat(locale).format(metrics.unitsSold7d) : market.unavailable}
                          </td>
                          <td className="py-2.5 pr-3 text-center">
                            <span className={cn("inline-flex items-center gap-0.5 text-xs font-bold whitespace-nowrap", trend !== null && trend < 0 ? "text-destructive" : "text-success")}>
                              {trend === null ? market.unavailable : `${trend >= 0 ? "↑" : "↓"} ${Math.abs(trend).toFixed(1)}%`}
                            </span>
                          </td>
                          <td className="py-2.5 pr-3 text-right font-semibold tabular-nums whitespace-nowrap text-foreground">
                            {metrics?.revenue7d !== null && metrics?.revenue7d !== undefined ? formatPrice(metrics.revenue7d, product.currency, locale) : market.unavailable}
                          </td>
                          <td className="py-2.5 pr-3 text-center">
                            <span className="inline-flex min-w-9 items-center justify-center rounded-lg bg-success/10 px-2 py-1 text-xs font-bold text-success">
                              {product.score?.opportunityScore ?? market.unavailable}
                            </span>
                          </td>
                          <td className="py-2.5 pr-3 text-center">
                            <ScoreCell value={product.score?.riskScore} />
                          </td>
                          <td className="py-2.5 pl-3">
                            <div className="flex items-center justify-end gap-1">
                              <Button variant="ghost" size="icon" className="size-8" onClick={() => setQuickViewId(product.id)} aria-label={c.table.quickView}>
                                <Eye className="size-4" />
                              </Button>
                              <SaveButton productId={product.id} initiallySaved={savedSet.has(product.id)} label={c.card.save} savedLabel={c.card.saved} />
                            </div>
                          </td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              ) : (
              <table className="product-catalog-table w-full min-w-[760px] border-collapse text-left text-sm">
              <thead>
                <tr className="border-b border-border text-xs text-muted-foreground">
                  <th scope="col" className="product-column-heading py-2 pr-3 font-medium">
                    <span>{c.table.product}</span>
                  </th>
                  <th scope="col" className="hidden py-2 pr-3 font-medium sm:table-cell">
                    {c.table.store}
                  </th>
                  <th scope="col" className="hidden py-2 pr-3 font-medium md:table-cell">
                    {c.table.category}
                  </th>
                  <th scope="col" className="py-2 pr-3 text-right font-medium">
                    {c.table.price}
                  </th>
                  <th scope="col" className="py-2 pr-3 text-right font-medium">
                    {c.table.opportunity}
                  </th>
                  <th scope="col" className="hidden py-2 pr-3 text-right font-medium lg:table-cell">
                    {c.table.growth}
                  </th>
                  <th scope="col" className="hidden py-2 pr-3 text-right font-medium lg:table-cell">
                    {c.table.risk}
                  </th>
                  <th scope="col" className="hidden py-2 pr-3 text-right font-medium xl:table-cell">
                    {c.table.competition}
                  </th>
                  <th scope="col" className="py-2 pl-3 text-right font-medium">
                    <span className="sr-only">{c.table.quickView}</span>
                  </th>
                </tr>
              </thead>
              <tbody>
                {products.map((product) => (
                  <tr key={product.id} className="border-b border-border last:border-0 hover:bg-secondary/30">
                    <td className="py-2.5 pr-3">
                      <Link href={`/dashboard/products/${product.id}`} className="flex items-center gap-3">
                        <ProductImage src={product.imageUrl} alt={product.canonicalName} className="size-11" sizes="44px" />
                        <div className="min-w-0">
                          <p className="truncate font-medium text-foreground hover:text-primary">
                            {product.canonicalName}
                          </p>
                          <p className="flex min-w-0 items-center gap-1.5 text-xs text-muted-foreground">
                            {product.brand && <span className="truncate">{product.brand}</span>}
                            {product.isDemo && <DemoBadge className="shrink-0" />}
                          </p>
                        </div>
                      </Link>
                    </td>
                    <td className="hidden truncate py-2.5 pr-3 text-muted-foreground sm:table-cell">
                      {product.storeName ?? c.table.unknownStore}
                    </td>
                    <td className="hidden truncate py-2.5 pr-3 text-muted-foreground md:table-cell">{product.category}</td>
                    <td className="py-2.5 pr-3 text-right tabular-nums text-foreground">
                      {product.currentPrice !== null ? formatPrice(product.currentPrice, product.currency, locale) : "—"}
                    </td>
                    <td className="py-2.5 pr-3 text-right">
                      <ScoreCell value={product.score?.opportunityScore} />
                    </td>
                    <td className="hidden py-2.5 pr-3 text-right lg:table-cell">
                      <ScoreCell value={product.score?.growthVelocityScore} />
                    </td>
                    <td className="hidden py-2.5 pr-3 text-right lg:table-cell">
                      <ScoreCell value={product.score?.riskScore} />
                    </td>
                    <td className="hidden py-2.5 pr-3 text-right xl:table-cell">
                      <ScoreCell value={product.score?.competitionTrendScore} />
                    </td>
                    <td className="py-2.5 pl-3">
                      <div className="flex items-center justify-end gap-1">
                        <Button
                          variant="ghost"
                          size="icon"
                          className="size-8"
                          onClick={() => setQuickViewId(product.id)}
                          aria-label={c.table.quickView}
                        >
                          <Eye className="size-4" />
                        </Button>
                        <SaveButton
                          productId={product.id}
                          initiallySaved={savedSet.has(product.id)}
                          label={c.card.save}
                          savedLabel={c.card.saved}
                        />
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
              </table>
              )}
            </div>
          )}
      </Card>

        {!loadError && products.length > 0 && (
          <div className="flex items-center justify-center gap-3">
            <Button
              variant="outline"
              size="sm"
              disabled={page <= 1 || isPending}
              onClick={() => navigate({ page: String(page - 1) })}
            >
              <ChevronLeft className="size-4" />
              {c.pagination.previous}
            </Button>
            <span className="text-sm text-muted-foreground">
              {c.pagination.pageOf.replace("{page}", String(page)).replace("{total}", String(totalPages))}
            </span>
            <Button
              variant="outline"
              size="sm"
              disabled={page >= totalPages || isPending}
              onClick={() => navigate({ page: String(page + 1) })}
            >
              {c.pagination.next}
              <ChevronRight className="size-4" />
            </Button>
          </div>
        )}

      <div className="flex flex-col items-center gap-1 text-center text-xs text-muted-foreground">
        {products.some((product) => product.isDemo) && (
          <p className="max-w-2xl">{c.demoDataNotice}</p>
        )}
        <p className="max-w-2xl">{c.disclaimer}</p>
      </div>

      <ProductQuickView productId={quickViewId} open={quickViewId !== null} onOpenChange={(open) => !open && setQuickViewId(null)} />
    </div>
  );
}
