import { useState, useMemo, useEffect } from 'react';
import { Link } from '@tanstack/react-router';
import { motion, useReducedMotion } from 'framer-motion';
import {
  SlidersHorizontal, X, LayoutGrid, ChevronLeft, ChevronRight,
  Package, Flame, BadgePercent, Tag,
} from 'lucide-react';
import { Slider } from '@/components/ui/slider';
import { Skeleton } from '@/components/ui/skeleton';
import ProductCard from '@/components/ProductCard';
import Breadcrumbs from '@/components/Breadcrumbs';
import CategorySEOSection from '@/components/CategorySEOSection';
import RelatedCategories from '@/components/RelatedCategories';
import ProductAssistant from '@/components/ProductAssistant';
import { getCategorySeo } from '@/data/categorySeo';
import { useSearchParams } from '@/hooks/useSearchParams';
import { products as mockProducts, categories as mockCategories } from '@/data/mockProducts';
import { useProducts, useCategories, SHOP_DEFAULT_PRODUCTS_PARAMS } from '@/hooks/useWooCommerce';
import { getCategoryIcon } from '@/lib/categoryIcons';
import { useT, useLang } from '@/lib/i18n';

type SortOption = 'popular' | 'price-asc' | 'price-desc' | 'newest' | 'rating';

const PRODUCTS_PER_PAGE = 12;

const sortMap: Record<SortOption, { orderby: string; order: string }> = {
  popular: { orderby: 'popularity', order: 'desc' },
  'price-asc': { orderby: 'price', order: 'asc' },
  'price-desc': { orderby: 'price', order: 'desc' },
  newest: { orderby: 'date', order: 'desc' },
  rating: { orderby: 'rating', order: 'desc' },
};

/** Maakt van een productnaam een korte, klikbare zoekterm. */
function toSearchTerm(name: string): string {
  return name
    .split(/[–—|(]/)[0]
    .replace(/\b\d+\s?(mg|mcg|iu|ml|stuks?)\b.*/i, '')
    .replace(/\s+/g, ' ')
    .trim();
}


/**
 * Grid reveal. The delay is capped at six rows' worth of stagger: past that the
 * shopper is waiting for content instead of reading it, and a slow grid costs
 * clicks. Short and front-loaded keeps the page feeling fast.
 */
const fadeUp = {
  hidden: { opacity: 0, y: 20 },
  visible: (i: number = 0) => ({
    opacity: 1, y: 0,
    transition: { delay: Math.min(i, 6) * 0.05, duration: 0.4, ease: 'easeOut' as const },
  }),
};

/** Same shape, no movement, for visitors who asked for reduced motion. */
const fadeUpStatic = {
  hidden: { opacity: 1, y: 0 },
  visible: { opacity: 1, y: 0 },
};

function buildPageNumbers(current: number, total: number): (number | 'ellipsis')[] {
  if (total <= 7) return Array.from({ length: total }, (_, i) => i + 1);
  const pages: (number | 'ellipsis')[] = [1];
  if (current > 3) pages.push('ellipsis');
  const start = Math.max(2, current - 1);
  const end = Math.min(total - 1, current + 1);
  for (let i = start; i <= end; i++) pages.push(i);
  if (current < total - 2) pages.push('ellipsis');
  pages.push(total);
  return pages;
}

const VALID_SORTS: SortOption[] = ['popular', 'price-asc', 'price-desc', 'newest', 'rating'];

interface ProductsListingProps {
  /** Category slug from /product-category/$slug route. When undefined, falls back to ?categorie= query. */
  categorySlugFromRoute?: string;
}

export default function ProductsListing({ categorySlugFromRoute }: ProductsListingProps) {
  const reducedMotion = useReducedMotion();
  const [searchParams, setSearchParams] = useSearchParams();
  const activeCategory = categorySlugFromRoute || searchParams.get('categorie') || '';
  const searchQuery = searchParams.get('zoeken') || '';
  const sortParam = searchParams.get('sort') as SortOption | null;
  const initialSort: SortOption = sortParam && VALID_SORTS.includes(sortParam) ? sortParam : 'popular';
  const [sort, setSort] = useState<SortOption>(initialSort);
  const [inStockOnly, setInStockOnly] = useState(false);
  const [onSaleOnly, setOnSaleOnly] = useState(false);
  const [featuredOnly, setFeaturedOnly] = useState(false);
  const [showFilters, setShowFilters] = useState(false);
  const [priceRange, setPriceRange] = useState<[number, number]>([0, 500]);
  const [currentPage, setCurrentPage] = useState(1);

  useEffect(() => {
    if (sortParam && VALID_SORTS.includes(sortParam) && sortParam !== sort) {
      setSort(sortParam);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [sortParam]);

  const t = useT();
  const lang = useLang();
  const { data: wcCategories } = useCategories();
  const categories = wcCategories ?? mockCategories;
  const activeCategoryObj = categories.find((c) => c.slug === activeCategory || (!!activeCategory && c.slugEn === activeCategory));
  const categorySeo = getCategorySeo(activeCategoryObj?.slug ?? activeCategory, lang);
  const activeCategoryId = activeCategoryObj?.id;

  // Build the params; when the user is on a fresh page with default filters
  // we reuse the exact shared constant so the query key matches what route
  // loaders prime. Any user-driven change diverges from the default and
  // becomes a normal client-side fetch.
  const isDefault =
    currentPage === 1 &&
    sort === 'popular' &&
    !inStockOnly &&
    !featuredOnly &&
    !searchQuery &&
    priceRange[0] === 0 &&
    priceRange[1] === 500;
  const productsParams = isDefault
    ? { ...SHOP_DEFAULT_PRODUCTS_PARAMS, category: activeCategoryId }
    : {
        page: currentPage,
        per_page: PRODUCTS_PER_PAGE,
        category: activeCategoryId,
        orderby: sortMap[sort].orderby,
        order: sortMap[sort].order,
        min_price: priceRange[0],
        max_price: priceRange[1],
        stock_status: inStockOnly ? 'instock' : undefined,
        search: searchQuery || undefined,
        featured: featuredOnly || undefined,
      };
  const { data: wcData, isLoading } = useProducts(productsParams);

  const filtered = useMemo(() => {
    if (wcData) {
      let result = wcData.products;
      if (onSaleOnly) result = result.filter((p) => p.salePrice !== undefined);
      return result;
    }
    if (isLoading) return [];
    let result = [...mockProducts];
    if (searchQuery) result = result.filter((p) => p.name.toLowerCase().includes(searchQuery.toLowerCase()));
    if (activeCategory) result = result.filter((p) => p.categorySlug === activeCategory);
    if (inStockOnly) result = result.filter((p) => p.inStock);
    if (onSaleOnly) result = result.filter((p) => p.salePrice !== undefined);
    if (featuredOnly) result = result.filter((p) => p.isFeatured);
    result = result.filter((p) => {
      const price = p.salePrice ?? p.price;
      return price >= priceRange[0] && price <= priceRange[1];
    });
    switch (sort) {
      case 'price-asc': result.sort((a, b) => (a.salePrice ?? a.price) - (b.salePrice ?? b.price)); break;
      case 'price-desc': result.sort((a, b) => (b.salePrice ?? b.price) - (a.salePrice ?? a.price)); break;
      case 'newest': result.sort((a, b) => (b.isNew ? 1 : 0) - (a.isNew ? 1 : 0)); break;
      case 'rating': result.sort((a, b) => b.rating - a.rating); break;
    }
    return result.slice((currentPage - 1) * PRODUCTS_PER_PAGE, currentPage * PRODUCTS_PER_PAGE);
  }, [wcData, isLoading, activeCategory, searchQuery, sort, inStockOnly, onSaleOnly, featuredOnly, priceRange, currentPage]);

  const totalItems = wcData?.totalItems ?? mockProducts.length;
  const totalPages = wcData
    ? Math.max(1, wcData.totalPages ?? Math.ceil(totalItems / PRODUCTS_PER_PAGE))
    : Math.max(1, Math.ceil(mockProducts.length / PRODUCTS_PER_PAGE));

  useEffect(() => { setCurrentPage(1); }, [activeCategory, searchQuery, sort, inStockOnly, onSaleOnly, featuredOnly, priceRange]);

  const handleCategoryChange = (slug: string) => {
    if (categorySlugFromRoute) return; // route-level navigation handled by Link
    const params: Record<string, string> = {};
    if (slug) params.categorie = slug;
    if (searchQuery) params.zoeken = searchQuery;
    setSearchParams(params);
  };

  const handleTagClick = (tag: string) => {
    if (searchQuery.toLowerCase() === tag.toLowerCase()) {
      searchParams.delete('zoeken');
      setSearchParams(searchParams);
    } else {
      const params: Record<string, string> = { zoeken: tag };
      if (!categorySlugFromRoute && activeCategory) params.categorie = activeCategory;
      setSearchParams(params);
    }
  };

  const clearSearch = () => {
    searchParams.delete('zoeken');
    setSearchParams(searchParams);
  };

  const activeFilterCount = [inStockOnly, onSaleOnly, featuredOnly, priceRange[0] > 0 || priceRange[1] < 500].filter(Boolean).length;
  const pageNumbers = buildPageNumbers(currentPage, totalPages);

  // Populaire zoektermen: dynamisch afgeleid van de producten in de huidige
  // categorie + de SEO-keywords van die categorie.
  const [popularTags, setPopularTags] = useState<string[]>([]);
  const wcProducts = wcData?.products;
  useEffect(() => {
    // Bij een actieve zoekterm de lijst niet laten krimpen.
    if (searchQuery) return;
    const source = wcProducts?.length
      ? wcProducts
      : mockProducts.filter((p) => !activeCategory || p.categorySlug === activeCategory);
    const out: string[] = [];
    const push = (raw: string) => {
      const term = raw.trim();
      if (!term || term.length < 3 || term.length > 26) return;
      if (out.some((t) => t.toLowerCase() === term.toLowerCase())) return;
      out.push(term);
    };
    source.forEach((p) => push(toSearchTerm(p.name)));
    (categorySeo?.keywords ?? [])
      .filter((k) => k.split(' ').length <= 2)
      .forEach((k) => push(k.charAt(0).toUpperCase() + k.slice(1)));
    setPopularTags(out.slice(0, 14));
  }, [wcProducts, activeCategory, categorySeo, searchQuery]);



  // Sidebar category links: use real <Link> to category routes.
  //
  // The active row used the brand gradient with white text. That gradient runs
  // through a very light gold (#FFD777), so the label was unreadable wherever it
  // crossed that stop. The active row is now a solid primary block with
  // primary-foreground text, the same treatment as the category chips above the
  // grid: readable in both themes and clearly distinguishable from the rest.
  const renderCategoryButton = (slug: string, label: string, isActive: boolean, count?: number) => {
    const className = `flex w-full items-center justify-between gap-2 rounded-lg px-3 py-2 text-sm transition-colors ${
      isActive
        ? 'bg-primary font-semibold text-primary-foreground shadow-sm'
        : 'font-medium text-foreground/75 hover:bg-muted hover:text-foreground'
    }`;
    const content = (
      <>
        <span className="min-w-0 truncate">{label}</span>
        {count !== undefined && (
          <span
            className={`shrink-0 rounded-md border px-1.5 py-0.5 text-[11px] font-semibold tabular-nums ${
              isActive
                ? 'border-primary-foreground/25 text-primary-foreground/90'
                : 'border-border/70 text-muted-foreground'
            }`}
          >
            {count}
          </span>
        )}
      </>
    );
    if (!slug) {
      return (
        <Link to="/shop" className={className}>
          {content}
        </Link>
      );
    }
    return (
      <Link to="/product-category/$slug" params={{ slug }} className={className}>
        {content}
      </Link>
    );
  };

  const renderCategoryChip = (slug: string, label: string, Icon: React.ElementType, isActive: boolean) => {
    const className = `flex flex-col items-center gap-1.5 px-3 py-3 rounded-2xl border text-xs font-semibold transition-all duration-300 ${
      isActive
        ? 'border-primary bg-primary text-primary-foreground shadow-glow'
        : 'border-border/50 bg-card text-muted-foreground hover:border-primary/50 hover:shadow-card-hover hover:-translate-y-0.5 shadow-card'
    }`;
    if (!slug) {
      return (
        <Link key="all" to="/shop" className={className}>
          <Icon className="w-5 h-5" />
          {label}
        </Link>
      );
    }
    return (
      <Link key={slug} to="/product-category/$slug" params={{ slug }} className={className}>
        <Icon className="w-5 h-5" />
        <span className="w-full text-center text-xs leading-tight line-clamp-2 break-words" lang={lang}>{label}</span>
      </Link>
    );
  };

  const filterToggles: {
    key: string;
    checked: boolean;
    onChange: (value: boolean) => void;
    Icon: React.ElementType;
    label: string;
  }[] = [
    { key: 'stock', checked: inStockOnly, onChange: setInStockOnly, Icon: Package, label: t('Op voorraad', 'In stock') },
    { key: 'sale', checked: onSaleOnly, onChange: setOnSaleOnly, Icon: BadgePercent, label: t('In de aanbieding', 'On sale') },
    { key: 'featured', checked: featuredOnly, onChange: setFeaturedOnly, Icon: Flame, label: t('Uitgelicht', 'Featured') },
  ];

  return (
    <div className="min-h-screen">
      <Breadcrumbs items={[{ label: activeCategoryObj?.name || t('Webshop', 'Shop') }]} />
      <div className="container pt-8 pb-2">
        <motion.div initial={{ opacity: 0, y: 12 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.4 }}>
          <div className="flex items-end justify-between gap-4">
            <div>
              <h1 className="text-2xl md:text-3xl font-black">
                {searchQuery
                  ? <>{t('Resultaten voor', 'Results for')} "<span className="text-primary">{searchQuery}</span>"</>
                  : categorySeo?.heading || activeCategoryObj?.name || t('Alle Producten', 'All Products')}
              </h1>
              <p className="text-sm text-muted-foreground mt-1">
                <span className="font-semibold text-foreground">{totalItems}</span> {t('producten gevonden', 'products found')}
              </p>
            </div>
            {searchQuery && (
              <button
                onClick={clearSearch}
                className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg border border-border/50 bg-card text-sm font-medium text-muted-foreground hover:text-foreground hover:border-primary/50 transition-all shadow-card shrink-0"
              >
                <X className="w-3.5 h-3.5" /> {t('Wissen', 'Clear')}
              </button>
            )}
          </div>
        </motion.div>

        {!searchQuery && categorySeo?.intro?.length ? (
          <div className="mt-4 max-w-3xl space-y-2">
            {categorySeo.intro.map((para, i) => (
              <p key={i} className="text-sm text-muted-foreground leading-relaxed">{para}</p>
            ))}
          </div>
        ) : null}
      </div>

      <div className="container py-4">
        <div className="grid grid-cols-2 min-[400px]:grid-cols-3 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6 xl:grid-cols-8 gap-2">
          {renderCategoryChip('', t('Alles', 'All'), LayoutGrid, !activeCategory)}
          {categories.map((cat) => {
            const Icon = getCategoryIcon(cat.slug);
            return renderCategoryChip(cat.slug, cat.name, Icon, activeCategory === cat.slug);
          })}
        </div>
      </div>

      <div className="container pb-12">
        <div className="flex items-center justify-between mb-4 lg:hidden">
          <button
            onClick={() => setShowFilters(!showFilters)}
            className="flex items-center gap-2 px-4 py-2.5 border border-border/50 rounded-xl text-sm font-medium bg-card shadow-card hover:shadow-card-hover transition-all"
          >
            <SlidersHorizontal className="w-4 h-4" /> {t('Filters', 'Filters')}
            {activeFilterCount > 0 && (
              <span className="ml-1 w-5 h-5 rounded-full bg-primary text-primary-foreground text-xs flex items-center justify-center font-bold">
                {activeFilterCount}
              </span>
            )}
          </button>
          <select
            value={sort}
            onChange={(e) => setSort(e.target.value as SortOption)}
            className="text-sm px-3 py-2.5 rounded-xl border border-border/50 bg-card shadow-card outline-none lg:hidden"
          >
            <option value="popular">{t('Populairste', 'Most popular')}</option>
            <option value="price-asc">{t('Prijs ↑', 'Price ↑')}</option>
            <option value="price-desc">{t('Prijs ↓', 'Price ↓')}</option>
            <option value="newest">{t('Nieuwste', 'Newest')}</option>
            <option value="rating">{t('Best beoordeeld', 'Best rated')}</option>
          </select>
        </div>

        <div className="flex gap-6">
          <aside className={`${showFilters ? 'block' : 'hidden'} lg:block w-full lg:w-60 shrink-0`}>
            <div className="sticky top-24 space-y-3">
              {showFilters && (
                <button onClick={() => setShowFilters(false)} className="lg:hidden flex items-center gap-1 text-sm text-muted-foreground mb-3">
                  <X className="w-4 h-4" /> {t('Sluiten', 'Close')}
                </button>
              )}

              <div className="bg-card rounded-2xl border border-border/50 p-5 shadow-card">
                <h3 className="font-bold text-sm mb-3 text-foreground">{t('Categorieën', 'Categories')}</h3>
                <ul className="space-y-1">
                  <li>{renderCategoryButton('', t('Alle producten', 'All products'), !activeCategory)}</li>
                  {categories.map((cat) => (
                    <li key={cat.id}>
                      {renderCategoryButton(cat.slug, cat.name, activeCategory === cat.slug, cat.count)}
                    </li>
                  ))}
                </ul>
              </div>

              <div className="bg-card rounded-2xl border border-border/50 p-5 shadow-card hidden lg:block">
                <h3 className="font-bold text-sm mb-3 text-foreground">{t('Sorteren', 'Sort')}</h3>
                <select
                  value={sort}
                  onChange={(e) => setSort(e.target.value as SortOption)}
                  className="w-full text-sm px-3 py-2.5 rounded-xl border border-border/50 bg-background focus:ring-2 focus:ring-ring outline-none transition-all"
                >
                  <option value="popular">{t('Populairste', 'Most popular')}</option>
                  <option value="price-asc">{t('Prijs: laag → hoog', 'Price: low → high')}</option>
                  <option value="price-desc">{t('Prijs: hoog → laag', 'Price: high → low')}</option>
                  <option value="newest">{t('Nieuwste', 'Newest')}</option>
                  <option value="rating">{t('Best beoordeeld', 'Best rated')}</option>
                </select>
              </div>

              <div className="bg-card rounded-2xl border border-border/50 p-5 shadow-card">
                <h3 className="font-bold text-sm mb-4 text-foreground">{t('Prijsbereik', 'Price range')}</h3>
                <Slider
                  min={0} max={500} step={5}
                  value={priceRange}
                  onValueChange={(v) => setPriceRange(v as [number, number])}
                  className="mb-4"
                />
                <div className="flex items-center justify-between text-sm">
                  <span className="bg-muted px-3 py-1 rounded-lg font-semibold text-foreground">€{priceRange[0]}</span>
                  <span className="text-muted-foreground">—</span>
                  <span className="bg-muted px-3 py-1 rounded-lg font-semibold text-foreground">€{priceRange[1]}</span>
                </div>
              </div>

              <div className="bg-card rounded-2xl border border-border/50 p-5 shadow-card space-y-4">
                <h3 className="font-bold text-sm text-foreground">{t('Filters', 'Filters')}</h3>
                {/*
                  The switch had no visible on-state: the track carried
                  `peer-checked:gradient-primary`, and Tailwind never generates a
                  variant for that hand-written class, so toggling changed
                  nothing on screen. The track is now a plain `.pw-switch`
                  element that is filled by CSS from the checkbox state, and the
                  icon, label and row all react too, so "on" is unmistakable.
                */}
                <div className="space-y-1">
                  {filterToggles.map(({ key, checked, onChange, Icon, label }) => (
                    <label
                      key={key}
                      className="-mx-2 flex cursor-pointer select-none items-center gap-3 rounded-lg px-2 py-2 transition-colors hover:bg-muted/60 has-[:checked]:bg-brand-gold/10"
                    >
                      <input
                        type="checkbox"
                        checked={checked}
                        onChange={(e) => onChange(e.target.checked)}
                        className="peer sr-only"
                      />
                      <span className="pw-switch" aria-hidden="true" />
                      <Icon className="h-4 w-4 shrink-0 text-muted-foreground transition-colors peer-checked:text-brand-gold" />
                      <span className="text-sm font-medium text-muted-foreground transition-colors peer-checked:text-foreground">
                        {label}
                      </span>
                    </label>
                  ))}
                </div>
              </div>

              {(() => {
                const tags = popularTags;
                return tags && tags.length > 0 ? (

                  <div className="bg-card rounded-2xl border border-border/50 p-5 shadow-card">
                    <h3 className="font-bold text-sm mb-3 text-foreground flex items-center gap-1.5">
                      <Tag className="w-4 h-4" /> {t('Populaire zoektermen', 'Popular searches')}
                    </h3>
                    <div className="flex flex-wrap gap-1.5">
                      {tags.map((tag) => {
                        const isActive = searchQuery.toLowerCase() === tag.toLowerCase();
                        return (
                          <button
                            key={tag}
                            onClick={() => handleTagClick(tag)}
                            className={`px-2.5 py-1 rounded-lg text-xs font-medium transition-all duration-200 ${
                              isActive
                                ? 'bg-primary text-primary-foreground shadow-sm'
                                : 'bg-muted text-muted-foreground hover:text-foreground hover:bg-primary/10'
                            }`}
                          >
                            {tag}
                            {isActive && <X className="w-3 h-3 inline ml-1 -mr-0.5" />}
                          </button>
                        );
                      })}
                    </div>
                  </div>
                ) : null;
              })()}
            </div>
          </aside>

          <div className="flex-1 min-w-0">
            {isLoading ? (
              <div className="grid grid-cols-2 md:grid-cols-3 gap-5">
                {Array.from({ length: PRODUCTS_PER_PAGE }).map((_, i) => (
                  <div key={i} className="bg-card rounded-2xl border border-border/50 overflow-hidden shadow-card">
                    <Skeleton className="aspect-square" />
                    <div className="p-5 space-y-2.5">
                      <Skeleton className="h-3 w-16 rounded-full" />
                      <Skeleton className="h-4 w-full rounded-full" />
                      <Skeleton className="h-3 w-24 rounded-full" />
                      <Skeleton className="h-6 w-20 rounded-full" />
                    </div>
                  </div>
                ))}
              </div>
            ) : (
              <>
                <motion.div
                  className="grid grid-cols-2 md:grid-cols-3 gap-5"
                  initial="hidden" animate="visible"
                  variants={{ visible: { transition: { staggerChildren: reducedMotion ? 0 : 0.05 } } }}
                >
                  {filtered.map((product, i) => (
                    <motion.div key={product.id} variants={reducedMotion ? fadeUpStatic : fadeUp} custom={i}>
                      <ProductCard product={product} />
                    </motion.div>
                  ))}
                </motion.div>
                {filtered.length === 0 && (
                  <motion.div initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} className="text-center py-20">
                    <div className="w-16 h-16 rounded-2xl bg-muted flex items-center justify-center mx-auto mb-4">
                      <Package className="w-8 h-8 text-muted-foreground" />
                    </div>
                    <p className="text-lg font-bold">{t('Geen producten gevonden', 'No products found')}</p>
                    <p className="text-sm text-muted-foreground mt-1">{t('Probeer een andere categorie of filter.', 'Try a different category or filter.')}</p>
                  </motion.div>
                )}
              </>
            )}

            {totalPages > 1 && (
              <nav aria-label={t('Paginering', 'Pagination')} className="flex items-center justify-center gap-1.5 mt-10">
                <button
                  onClick={() => setCurrentPage(Math.max(1, currentPage - 1))}
                  disabled={currentPage === 1}
                  className="p-2.5 rounded-xl border border-border/50 bg-card shadow-card hover:shadow-card-hover transition-all disabled:opacity-40 disabled:cursor-not-allowed"
                  aria-label={t('Vorige pagina', 'Previous page')}
                >
                  <ChevronLeft className="w-4 h-4" />
                </button>

                {pageNumbers.map((page, idx) =>
                  page === 'ellipsis' ? (
                    <span key={`e-${idx}`} className="w-10 h-10 flex items-center justify-center text-muted-foreground">···</span>
                  ) : (
                    <button
                      key={page}
                      onClick={() => setCurrentPage(page)}
                      aria-current={currentPage === page ? 'page' : undefined}
                      className={`w-10 h-10 rounded-xl text-sm font-bold transition-all duration-200 ${
                        currentPage === page
                          ? 'gradient-primary text-white shadow-glow'
                          : 'border border-border/50 bg-card shadow-card hover:shadow-card-hover'
                      }`}
                    >
                      {page}
                    </button>
                  )
                )}

                <button
                  onClick={() => setCurrentPage(Math.min(totalPages, currentPage + 1))}
                  disabled={currentPage === totalPages}
                  className="p-2.5 rounded-xl border border-border/50 bg-card shadow-card hover:shadow-card-hover transition-all disabled:opacity-40 disabled:cursor-not-allowed"
                  aria-label={t('Volgende pagina', 'Next page')}
                >
                  <ChevronRight className="w-4 h-4" />
                </button>

                <span className="ml-3 text-xs text-muted-foreground">
                  {t('Pagina', 'Page')} {currentPage} {t('van', 'of')} {totalPages}
                </span>
              </nav>
            )}
          </div>
        </div>
      </div>

      {activeCategory && activeCategoryObj && (
        <>
          <ProductAssistant context={categorySeo?.heading || activeCategoryObj.name} />
          <RelatedCategories slug={activeCategoryObj.slug} />
          <CategorySEOSection
            slug={activeCategoryObj.slug}
            name={categorySeo?.heading || activeCategoryObj.name}
            description={categorySeo?.body || activeCategoryObj.description}
          />
        </>
      )}
    </div>
  );
}
