'use client';

import { precioProducto } from '@/lib/precioProducto';
import { useEffect, useMemo, useState } from 'react';
import Button from '@mui/material/Button';
import Chip from '@mui/material/Chip';
import Slider from '@mui/material/Slider';
import Tooltip from '@mui/material/Tooltip';
import ArrowForwardRoundedIcon from '@mui/icons-material/ArrowForwardRounded';
import CampaignRoundedIcon from '@mui/icons-material/CampaignRounded';
import CategoryRoundedIcon from '@mui/icons-material/CategoryRounded';
import ChevronLeftRoundedIcon from '@mui/icons-material/ChevronLeftRounded';
import ChevronRightRoundedIcon from '@mui/icons-material/ChevronRightRounded';
import FavoriteRoundedIcon from '@mui/icons-material/FavoriteRounded';
import GridViewRoundedIcon from '@mui/icons-material/GridViewRounded';
import HomeRoundedIcon from '@mui/icons-material/HomeRounded';
import SearchRoundedIcon from '@mui/icons-material/SearchRounded';
import ShoppingCartRoundedIcon from '@mui/icons-material/ShoppingCartRounded';
import StarRoundedIcon from '@mui/icons-material/StarRounded';
import TuneIcon from '@mui/icons-material/Tune';
import VisibilityRoundedIcon from '@mui/icons-material/VisibilityRounded';
import ViewListRoundedIcon from '@mui/icons-material/ViewListRounded';
import { DEFAULT_STORE_CONFIG } from '../../config/defaultStoreConfig';
import type {
	CategoryTreeNode,
	EcommerceNews,
	FeaturedCategory,
	Product,
	PromotionConfig,
	StoreConfig
} from '../../config/defaultStoreConfig';
import NewsIcon from '../novedades/NewsIcon';
import StoreProductCard from '../producto/StoreProductCard';
import StoreShowcaseCard from '../producto/StoreShowcaseCard';
import { storeImageSrc } from '@/lib/storeImage';
import type { StoreSearchResponse } from '@/lib/storeSearch';
import {
	HeroSliderRoot,
	HeroSliderMain,
	HeroSliderTrack,
	HeroSlide,
	HeroSlideContent,
	HeroSlideDeal,
	HeroSliderArrow,
	HeroDotBar,
	HeroDot,
	HeroAsideColumn,
	HeroAsideCard,
	HeroBannerRow,
	HeroBannerCard
} from './styles';
import {
	BadgeStack,
	Catalog,
	CatalogBreadcrumb,
	CatalogHeader,
	CatalogLayout,
	CatalogToolbar,
	CatalogToolbarLabel,
	CatalogViewButton,
	CategoryBanner,
	CategoryCatalog,
	CategoryFeatureAside,
	CategoryHeaderActions,
	CategoryHeaderLine,
	CategoryHotList,
	CategoryList,
	CategoryProductBody,
	CategoryProductHeader,
	CategoryProductSection,
	CategoryRibbon,
	CategoryShowcaseLayout,
	CategoryShowcaseMain,
	CategorySortLink,
	CategoryViewAll,
	FilterLabel,
	FilterTitle,
	FilterToggle,
	FilterValue,
	NewsAction,
	NewsCard,
	NewsHeader,
	NewsList,
	NewsTag,
	PaginationBar,
	PriceRow,
	PrimaryIconAction,
	ProductActions,
	ProductGrid,
	IconAction,
	ProductListGrid,
	ProductListRow,
	ProductListRowBody,
	PromoPanel,
	Rating,
	SearchContext,
	SearchEmptyState,
	SearchFeedback,
	ShopByFilterGroup,
	ShopByHeader,
	ShopByPanel,
	ShopByResetButton,
	ShopBySearch,
	ShopBySubcategoryList,
	SidePanel,
	SubcategoryPreviewCard,
	SubcategoryPreviewGrid
} from '../styles';

const BANNER_COLORS = ['var(--store-primary)', 'var(--store-accent)', 'var(--store-secondary)'];

function productMatchesCategory(product: Product, category: string) {
	return product.category === category || Boolean(product.categoryPath?.includes(category));
}

interface CatalogSection {
	name: string;
	products: Product[];
}

type CatalogSort = 'default' | 'priceAsc' | 'priceDesc' | 'rating' | 'newest';

// Orden rápido de los carruseles por categoría en la home.
type CategorySortKey = 'oferta' | 'nuevo' | 'rating' | 'precio';

const CATEGORY_SORT_TABS: { key: CategorySortKey; label: string }[] = [
	{ key: 'oferta', label: 'Oferta' },
	{ key: 'nuevo', label: 'Nuevo' },
	{ key: 'rating', label: 'Rating' },
	{ key: 'precio', label: 'Precio' },
];

type PaginationItem = number | 'ellipsis-start' | 'ellipsis-end';

function getPaginationItems(currentPage: number, totalPages: number): PaginationItem[] {
	if (totalPages <= 7) {
		return Array.from({ length: totalPages }, (_, index) => index + 1);
	}

	const current = Math.min(Math.max(currentPage, 1), totalPages);

	if (current <= 4) {
		return [1, 2, 3, 4, 5, 'ellipsis-end', totalPages];
	}

	if (current >= totalPages - 3) {
		return [1, 'ellipsis-start', totalPages - 4, totalPages - 3, totalPages - 2, totalPages - 1, totalPages];
	}

	return [1, 'ellipsis-start', current - 1, current, current + 1, 'ellipsis-end', totalPages];
}

function tieneOferta(p: Product): number {
	return p.oldPrice && p.oldPrice > p.price ? (p.oldPrice - p.price) / p.oldPrice : 0;
}

function sortCategoryProducts(products: Product[], key: CategorySortKey): Product[] {
	// Array.sort es estable: los empates conservan el orden original ("más vistos").
	const arr = [...products];
	switch (key) {
		case 'precio':
			return arr.sort((a, b) => a.price - b.price);
		case 'rating':
			return arr.sort((a, b) => (b.rating ?? 0) - (a.rating ?? 0));
		case 'nuevo': {
			const esNuevo = (p: Product) => ((p.badges ?? []).some((b) => b.toLowerCase().includes('nuevo')) ? 1 : 0);
			return arr.sort((a, b) => esNuevo(b) - esNuevo(a));
		}
		case 'oferta':
		default:
			return arr.sort((a, b) => tieneOferta(b) - tieneOferta(a));
	}
}

interface Props {
	query: string;
	category: string;
	maxPrice: number;
	priceRangeMax: number;
	catalogPage: number;
	catalogSort: CatalogSort;
	catalogPageSize: number;
	showHomeIntro: boolean;
	showCategoryCarousels: boolean;
	hasGlobalSearch: boolean;
	searchResponse: StoreSearchResponse | null;
	searchLoading: boolean;
	catalogSections: CatalogSection[];
	selectedCategoryNode: CategoryTreeNode | null;
	/** Nombre de categoría (cualquier nivel) → imagen cargada en el panel. */
	categoryImages?: Record<string, string>;
	categoryScopedProducts: Product[];
	filteredProducts: Product[];
	paginatedProducts: Product[];
	totalPages: number;
	selectedBrands: string[];
	selectedSubcategories: string[];
	sortedNews: EcommerceNews[];
	categories: string[];
	featuredCategories: FeaturedCategory[];
	activePromotions: PromotionConfig;
	storeConfig: StoreConfig;
	formatPrice: (value: number) => string;
	onSetQuery: (value: string) => void;
	onSetCategory: (category: string) => void;
	onSetMaxPrice: (value: number) => void;
	onSetCatalogPage: (value: number | ((prev: number) => number)) => void;
	onSetCatalogSort: (value: CatalogSort) => void;
	onSetCatalogPageSize: (value: number) => void;
	onToggleBrand: (brand: string) => void;
	onToggleSubcategory: (subcategory: string) => void;
	onResetCatalogFilters: () => void;
	onGoHome: () => void;
	onOpenDetail: (product: Product) => void;
	onAddToCart: (product: Product) => void;
	onQuickView: (product: Product) => void;
	onViewAll: (categoryName: string) => void;
	wishlistIds?: Set<string>;
	onToggleWishlist?: (productId: string) => void;
}

export default function HomeCatalogSection({
	query,
	category,
	maxPrice,
	priceRangeMax,
	catalogPage,
	catalogSort,
	catalogPageSize,
	showHomeIntro,
	showCategoryCarousels,
	hasGlobalSearch,
	searchResponse,
	searchLoading,
	catalogSections,
	selectedCategoryNode,
	categoryImages = {},
	categoryScopedProducts,
	filteredProducts,
	paginatedProducts,
	totalPages,
	selectedBrands,
	selectedSubcategories,
	sortedNews,
	categories,
	featuredCategories,
	activePromotions,
	storeConfig,
	formatPrice,
	onSetQuery,
	onSetCategory,
	onSetMaxPrice,
	onSetCatalogPage,
	onSetCatalogSort,
	onSetCatalogPageSize,
	onToggleBrand,
	onToggleSubcategory,
	onResetCatalogFilters,
	onGoHome,
	onOpenDetail,
	onAddToCart,
	onQuickView,
	onViewAll,
	wishlistIds,
	onToggleWishlist,
}: Props) {
	const { catalog } = storeConfig;
	const texts = storeConfig.texts ?? DEFAULT_STORE_CONFIG.texts;
	const [listView, setListView] = useState(false);
	const [currentSlide, setCurrentSlide] = useState(0);
	// Orden elegido por categoría en los carruseles de la home (default: ofertas).
	const [categorySort, setCategorySort] = useState<Record<string, CategorySortKey>>({});

	const [mobileFiltersOpen, setMobileFiltersOpen] = useState(false);
	const showFilterPanel = !showCategoryCarousels;
	const isCategoryLanding = !showCategoryCarousels && !hasGlobalSearch && category !== 'Todos';
	// Vista con filtros en el sidebar (categoría o listado de productos): en
	// móvil/tablet el panel arranca colapsado detrás del botón "Filtros".
	const isFilterView = isCategoryLanding || (showFilterPanel && !showHomeIntro);
	// En vista home, el sidebar sólo tiene sentido si hay novedades para mostrar.
	// En vista filtro/categoría siempre se muestra (filtros o shopby).
	const showSidePanel = (showFilterPanel && !showHomeIntro) || isCategoryLanding || sortedNews.length > 0;
	// Las destacadas son sólo raíces; una subcategoría con imagen propia también tiene banner.
	const categoryFeature =
		featuredCategories.find((item) => item.name === category) ??
		(categoryImages[category] ? { name: category, image: categoryImages[category] } : undefined);
	const categoryProducts = categoryScopedProducts;
	const subcategoryItems = (selectedCategoryNode?.children ?? [])
		.map((node) => {
			const productsInSubcategory = categoryScopedProducts.filter((product) => {
				const matchesSubcategory = productMatchesCategory(product, node.name);
				const matchesBrand = selectedBrands.length === 0 || selectedBrands.includes(product.brand);
				const matchesPrice = product.price <= maxPrice;
				return matchesSubcategory && matchesBrand && matchesPrice;
			});
			const sampleProduct = productsInSubcategory[0] ?? categoryScopedProducts.find((product) =>
				productMatchesCategory(product, node.name)
			);
			return {
				name: node.name,
				count: productsInSubcategory.length,
				// Sólo imágenes reales de la subcategoría o de un producto suyo. Antes
				// caía a categoryFeature/heroImage (fotos hardcodeadas de comida): una
				// subcategoría sin imagen mostraba un plato. El placeholder se resuelve
				// al renderizar con storeImageSrc().
				image: node.image || sampleProduct?.image || ''
			};
		})
		.filter((item) => item.count > 0 || selectedSubcategories.includes(item.name));
	const categoryBrands = Array.from(new Set(categoryProducts.map((product) => product.brand).filter(Boolean))).slice(0, 8);
	const minCategoryPrice = categoryProducts.length
		? Math.min(...categoryProducts.map((product) => product.price))
		: 0;
	const maxCategoryPrice = categoryProducts.length
		? Math.max(...categoryProducts.map((product) => product.price))
		: priceRangeMax;

	// Fondos por posición: se ciclan tintes de la marca para dar variedad.
	const slideBackgrounds = [
		'color-mix(in srgb, var(--store-primary) 8%, var(--store-background))',
		'color-mix(in srgb, var(--store-secondary) 8%, var(--store-background))',
		'color-mix(in srgb, var(--store-accent) 8%, var(--store-background))'
	];

	// Slides del carrusel. Si el comercio definió diapositivas propias
	// (heroSlides habilitadas), se usan esas; si no, se arma el carrusel
	// automático: promo principal + las primeras 2 categorías destacadas.
	const slides = useMemo(() => {
		const custom = (activePromotions.heroSlides ?? []).filter(
			(s) => s && s.enabled !== false && (s.title || s.image)
		);
		if (custom.length > 0) {
			return custom.map((s, i) => ({
				id: s.id || `slide-${i}`,
				subtitle: s.badge ?? '',
				title: s.title ?? '',
				description: s.description ?? '',
				cta: s.ctaLabel || 'Ver más',
				image: s.image ?? '',
				bg: slideBackgrounds[i % slideBackgrounds.length],
				category: s.category ?? ''
			}));
		}
		return [
			{
				id: 'main-promo',
				subtitle: activePromotions.heroBadge,
				title: activePromotions.heroTitle,
				description: activePromotions.heroSubtitle,
				// El texto de oferta se usaba como etiqueta del botón y el subtexto no se
				// mostraba en ningún lado. Ahora van juntos y destacados, como dice el panel.
				cta: 'Ver catálogo',
				dealTitle: activePromotions.heroDealTitle ?? '',
				dealSubtitle: activePromotions.heroDealSubtitle ?? '',
				image: activePromotions.heroImage,
				bg: slideBackgrounds[0],
				category: ''
			},
			...featuredCategories.slice(0, 2).map((cat, i) => ({
				id: cat.name,
				subtitle: i === 0 ? 'DESTACADO' : 'EXCLUSIVO',
				title: cat.name,
				description: `Descubre la mejor seleccion de ${cat.name.toLowerCase()} con precios exclusivos.`,
				cta: 'Ver coleccion',
				image: cat.image,
				bg: slideBackgrounds[(i + 1) % slideBackgrounds.length],
				category: cat.name
			}))
		];
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [activePromotions, featuredCategories]);

	// Minimum price per category (for aside cards)
	const minPriceByCategory = useMemo(() => {
		const map: Record<string, number> = {};
		filteredProducts.forEach((p) => {
			// Un precio 0 es un producto sin precio cargado: no puede ser el "desde".
			if (!(p.price > 0)) return;
			if (!(p.category in map) || p.price < map[p.category]) {
				map[p.category] = p.price;
			}
		});
		return map;
	}, [filteredProducts]);

	const asideCards = featuredCategories.slice(0, 2);
	const bottomBanners = featuredCategories.slice(0, 3);

	// Auto-advance slider while in home view
	useEffect(() => {
		if (!showHomeIntro || slides.length <= 1) return;

		const timer = setInterval(() => {
			setCurrentSlide((c) => (c + 1) % slides.length);
		}, 4500);
		return () => clearInterval(timer);
	}, [slides.length, showHomeIntro]);

	// Reset slide index when leaving home view
	useEffect(() => {
		if (!showHomeIntro) setCurrentSlide(0);
	}, [showHomeIntro]);

	const handlePrev = () => setCurrentSlide((c) => (c - 1 + slides.length) % slides.length);
	const handleNext = () => setCurrentSlide((c) => (c + 1) % slides.length);

	return (
		<>
			{showHomeIntro && (
				<>
					{/* ── Hero Slider ── */}
					<HeroSliderRoot data-store-reveal>
						<HeroSliderMain>
							<HeroSliderTrack slide={currentSlide}>
								{slides.map((slide) => (
									<HeroSlide
										key={slide.id}
										bg={slide.bg}
									>
										<span className="hero-contrast" aria-hidden="true" />
										<HeroSlideContent>
											<em>{slide.subtitle}</em>
											<h2>{slide.title}</h2>
											<p>{slide.description}</p>
											{'dealTitle' in slide && slide.dealTitle && (
												<HeroSlideDeal>
													<strong>{slide.dealTitle}</strong>
													{slide.dealSubtitle && <span>{slide.dealSubtitle}</span>}
												</HeroSlideDeal>
											)}
											<button
												type="button"
												onClick={() => onViewAll(slide.category || 'Todos')}
											>
												{slide.cta}
												<ArrowForwardRoundedIcon fontSize="small" />
											</button>
										</HeroSlideContent>
										<div>
											<img
												src={storeImageSrc(slide.image, slide.title)}
												alt={slide.title}
											/>
										</div>
									</HeroSlide>
								))}
							</HeroSliderTrack>

							{slides.length > 1 && (
								<>
									<HeroSliderArrow
										direction="prev"
										type="button"
										aria-label="Anterior"
										onClick={handlePrev}
									>
										<ChevronLeftRoundedIcon />
									</HeroSliderArrow>
									<HeroSliderArrow
										direction="next"
										type="button"
										aria-label="Siguiente"
										onClick={handleNext}
									>
										<ChevronRightRoundedIcon />
									</HeroSliderArrow>
									{(storeConfig.layout.showCarouselProgress ?? true) && (
										<HeroDotBar>
											{slides.map((slide, i) => (
												<HeroDot
													key={slide.id}
													type="button"
													active={i === currentSlide}
													aria-label={`Slide ${i + 1}`}
													onClick={() => setCurrentSlide(i)}
												/>
											))}
										</HeroDotBar>
									)}
								</>
							)}
						</HeroSliderMain>
					</HeroSliderRoot>

					{asideCards.length > 0 && (
						<HeroAsideColumn data-store-reveal>
							{asideCards.map((cat) => {
									const minPrice = minPriceByCategory[cat.name];
									return (
										<HeroAsideCard key={cat.name}>
											<header>
												<em>LO MÁS VENDIDO</em>
												<strong>
													<span>{cat.name}</span>
												</strong>
												<small>Disponibles ahora!</small>
											</header>
											<div>
												<img
													src={storeImageSrc(cat.image, cat.name)}
													alt={cat.name}
												/>
											</div>
											<footer>
												<div>
													{minPrice !== undefined ? (
														<>
															<span>Empezando desde</span>
															<strong>{formatPrice(minPrice)}</strong>
														</>
													) : (
														<span>Coleccion especial</span>
													)}
												</div>
												<button
													type="button"
													onClick={() => onViewAll(cat.name)}
												>
													VER COLECCIÓN <ArrowForwardRoundedIcon />
												</button>
											</footer>
										</HeroAsideCard>
									);
							})}
						</HeroAsideColumn>
					)}

					{/* ── Bottom Category Banners ── */}
					{bottomBanners.length > 0 && (
						<HeroBannerRow data-store-reveal>
							{bottomBanners.map((cat, i) => (
								<HeroBannerCard
									key={cat.name}
									type="button"
									style={{
										background: BANNER_COLORS[i] ?? 'var(--store-primary)'
									}}
									onClick={() => onViewAll(cat.name)}
								>
									<div>
										<em>MEJOR SELECCION</em>
										<strong>{cat.name}</strong>
										<span>OFERTA ESPECIAL</span>
									</div>
									<img
										src={storeImageSrc(cat.image, cat.name)}
										alt={cat.name}
									/>
								</HeroBannerCard>
							))}
						</HeroBannerRow>
					)}
				</>
			)}

				<CatalogLayout
					data-no-sidebar={!showSidePanel ? 'true' : undefined}
				>
					{showSidePanel && (
						<SidePanel data-shop-by={isCategoryLanding ? 'true' : undefined} data-collapsed={isFilterView && !mobileFiltersOpen ? 'true' : undefined}>
						{isFilterView && (
							<FilterToggle className="filter-toggle" type="button" aria-expanded={mobileFiltersOpen} onClick={() => setMobileFiltersOpen((open) => !open)}>
								<TuneIcon fontSize="small" />
								{mobileFiltersOpen ? 'Ocultar filtros' : 'Filtros'}
							</FilterToggle>
						)}
					{(isCategoryLanding || (showFilterPanel && !showHomeIntro)) && (
						<ShopByFilterGroup data-sidebar-search="true">
							<strong>Buscar</strong>
							<ShopBySearch>
								<input
									type="search"
									placeholder="Buscar"
									value={query}
									onChange={(event) => onSetQuery(event.target.value)}
								/>
								<button type="button" aria-label="Buscar">
									<SearchRoundedIcon fontSize="small" />
								</button>
							</ShopBySearch>
						</ShopByFilterGroup>
					)}
					{isCategoryLanding ? (
						<ShopByPanel>
							<ShopByHeader>Comprar por</ShopByHeader>
							{subcategoryItems.length > 0 && (
								<ShopByFilterGroup>
									<strong>Subcategoría</strong>
									<ShopBySubcategoryList>
										{subcategoryItems.map((item) => (
											<label key={item.name}>
												<input
													type="checkbox"
													checked={selectedSubcategories.includes(item.name)}
													onChange={() => onToggleSubcategory(item.name)}
												/>
												<span>{item.name} ({item.count})</span>
											</label>
										))}
									</ShopBySubcategoryList>
								</ShopByFilterGroup>
							)}
							<ShopByFilterGroup>
								<strong>Marca</strong>
								<ShopBySubcategoryList>
									{categoryBrands.map((brand) => (
										<label key={brand}>
											<input
												type="checkbox"
												checked={selectedBrands.includes(brand)}
												onChange={() => onToggleBrand(brand)}
											/>
											<span>{brand}</span>
										</label>
									))}
								</ShopBySubcategoryList>
							</ShopByFilterGroup>
							<ShopByFilterGroup>
								<strong>Precio</strong>
								<div>
									<small>Rango:</small>
									<span>{formatPrice(minCategoryPrice)}</span>
									<span>-</span>
									<span>{formatPrice(maxCategoryPrice)}</span>
								</div>
								<Slider
									value={maxPrice}
									min={0}
									max={priceRangeMax}
									step={5000}
									valueLabelDisplay="auto"
									valueLabelFormat={formatPrice}
									onChange={(_, value) => onSetMaxPrice(value as number)}
									sx={{ color: 'var(--store-primary)' }}
								/>
							</ShopByFilterGroup>
							<ShopByResetButton
								type="button"
								onClick={onResetCatalogFilters}
							>
								Limpiar filtros
							</ShopByResetButton>
						</ShopByPanel>
					) : showFilterPanel && !showHomeIntro ? (
						<>
							<FilterTitle>
								<TuneIcon fontSize="small" />
								<span>{hasGlobalSearch ? 'Refinar búsqueda' : 'Filtrar por'}</span>
							</FilterTitle>
							{hasGlobalSearch && (
								<SearchContext>
									Resultados para <strong>{query.trim()}</strong>
								</SearchContext>
							)}
							<div>
								<FilterLabel>Categorías</FilterLabel>
								<CategoryList>
									{categories.map((item) => (
										<Chip
											key={item}
											label={item}
											color={category === item ? 'primary' : 'default'}
											variant={category === item ? 'filled' : 'outlined'}
											onClick={() => onSetCategory(item)}
										/>
									))}
								</CategoryList>
							</div>
							<div>
								<FilterLabel>Precio máximo</FilterLabel>
								<Slider
									value={maxPrice}
									min={0}
									max={priceRangeMax}
									step={5000}
									valueLabelDisplay="auto"
									valueLabelFormat={formatPrice}
									onChange={(_, value) => onSetMaxPrice(value as number)}
									sx={{ color: 'var(--store-primary)' }}
								/>
								<FilterValue>{formatPrice(maxPrice)}</FilterValue>
							</div>
							<PromoPanel>
								<strong>{texts.b2bPanelTitle}</strong>
								<span>{texts.b2bPanelSubtitle}</span>
							</PromoPanel>
						</>
					) : (
						<>
							<NewsHeader>
								<span>
									<CampaignRoundedIcon fontSize="small" />
								</span>
								<div>
									<strong>{texts.novedadesTitle}</strong>
									<small>{texts.novedadesSubtitle}</small>
								</div>
							</NewsHeader>
							<NewsList>
								{sortedNews.map((item) => (
									<NewsCard
										key={item.id}
										type="button"
										data-news={item.type}
										onClick={() => item.targetCategory && onSetCategory(item.targetCategory)}
									>
										<img
											src={storeImageSrc(item.image, item.title)}
											alt={item.title}
										/>
										<div>
											<NewsTag>
												<NewsIcon type={item.type} />
												{item.tag}
											</NewsTag>
											<strong>{item.title}</strong>
											<span>{item.description}</span>
											<NewsAction>
												{item.ctaLabel}
												<ArrowForwardRoundedIcon fontSize="small" />
											</NewsAction>
										</div>
									</NewsCard>
								))}
							</NewsList>
						</>
					)}
						</SidePanel>
					)}

				<Catalog>
					{hasGlobalSearch && (
						<SearchFeedback aria-live="polite">
							<div>
								{searchLoading ? (
									<>Buscando productos para <strong>{query.trim()}</strong>…</>
								) : searchResponse?.unavailableProductName ? (
									<>
										<strong>{searchResponse.unavailableProductName}</strong> no está disponible. Mostramos{' '}
										productos similares con stock.
									</>
								) : searchResponse?.matchType === 'fuzzy' ? (
									<>No encontramos una coincidencia exacta; mostramos los productos más parecidos.</>
								) : (
									<>Resultados para <strong>{query.trim()}</strong></>
								)}
							</div>
							{!searchLoading && searchResponse?.matchType === 'fuzzy' && searchResponse.suggestedQuery && (
								<button
									type="button"
									onClick={() => onSetQuery(searchResponse.suggestedQuery!)}
								>
									¿Quisiste decir {searchResponse.suggestedQuery}?
								</button>
							)}
						</SearchFeedback>
					)}

					{isCategoryLanding && (
						<>
							<CatalogBreadcrumb>
								<button
									type="button"
									onClick={onGoHome}
									aria-label="Ir al inicio de la tienda"
								>
									<HomeRoundedIcon fontSize="small" />
								</button>
								<ChevronRightRoundedIcon fontSize="small" />
								<span>{category}</span>
							</CatalogBreadcrumb>
							{categoryFeature && (
								<CategoryBanner data-landing="true">
									<div>
										<h2>
											{category.includes(' ') ? (
												<>
													{category.split(' ').slice(0, -1).join(' ')}{' '}
													<em>{category.split(' ').slice(-1)[0]}</em>
												</>
											) : (
												<>
													{category} <em>{texts.categoryBannerTitleSuffix}</em>
												</>
											)}
										</h2>
										<p>
											{texts.categoryBannerDescription.replace(
												'{categoria}',
												category.toLowerCase(),
											)}
										</p>
									</div>
									<img
										src={storeImageSrc(categoryFeature.image, category)}
										alt={category}
									/>
								</CategoryBanner>
							)}
							{subcategoryItems.length > 0 && (
								<SubcategoryPreviewGrid>
									{subcategoryItems.map((item) => (
										<SubcategoryPreviewCard
											key={item.name}
											type="button"
											onClick={() => onSetCategory(item.name)}
										>
											<img
												src={storeImageSrc(item.image, item.name)}
												alt={item.name}
											/>
											<span>{item.name}</span>
										</SubcategoryPreviewCard>
									))}
								</SubcategoryPreviewGrid>
							)}
						</>
					)}

					{!showCategoryCarousels && (
						<CatalogHeader>
							<span>{filteredProducts.length}</span>
							<strong>productos</strong>
							<div />
						</CatalogHeader>
					)}

					{showCategoryCarousels ? (
						<CategoryCatalog>
							{catalogSections.map((section) => {
								const sortKey = categorySort[section.name] ?? 'oferta';
								const sortedProducts = sortCategoryProducts(section.products, sortKey);
								return (
								<CategoryProductSection key={section.name} data-store-reveal>
									<CategoryProductHeader>
										<CategoryRibbon>
											<CategoryRoundedIcon fontSize="small" />
											<span>{section.name}</span>
										</CategoryRibbon>
										<CategoryHeaderLine />
										<CategoryHeaderActions>
											{CATEGORY_SORT_TABS.map((tab) => (
												<CategorySortLink
													key={tab.key}
													type="button"
													data-active={sortKey === tab.key}
													onClick={() => setCategorySort((prev) => ({ ...prev, [section.name]: tab.key }))}
												>
													{tab.label}
												</CategorySortLink>
											))}
											<CategoryViewAll
												type="button"
												onClick={() => onViewAll(section.name)}
											>
												Ver todo
												<ArrowForwardRoundedIcon fontSize="small" />
											</CategoryViewAll>
										</CategoryHeaderActions>
									</CategoryProductHeader>
									<CategoryProductBody>
										<CategoryShowcaseLayout>
											<CategoryFeatureAside>
												<img
													src={storeImageSrc(
														categoryImages[section.name] ||
															featuredCategories.find((item) => item.name === section.name)?.image,
														section.name,
													)}
													alt={section.name}
												/>
												{/* Antes listaba los mismos 5 primeros productos que la vitrina de al
												    lado. Ahora sólo los que no entraron en la vitrina; si no hay, no se
												    muestra la lista. */}
												{(() => {
													const enVitrina = new Set(sortedProducts.slice(0, 6).map((p) => p.id));
													const otros = section.products.filter((p) => !enVitrina.has(p.id)).slice(0, 5);
													return otros.length > 0 ? (
												<CategoryHotList>
													<strong>{texts.mostViewedLabel}</strong>
													{otros.map((product) => (
														<button
															key={product.id}
															type="button"
															onClick={() => onOpenDetail(product)}
														>
															{product.name}
														</button>
													))}
												</CategoryHotList>
													) : null;
												})()}
											</CategoryFeatureAside>
											<CategoryShowcaseMain>
												{sortedProducts
													.slice(0, 6)
													.map((product) => (
														<StoreShowcaseCard
															key={product.id}
															product={product}
															showPromotionBadge={catalog.showPromotionBadge}
															showBrand={catalog.showBrand}
															showStock={catalog.showStock}
															showCategory={catalog.showCategory}
															formatPrice={formatPrice}
															onOpenDetail={onOpenDetail}
															onAddToCart={onAddToCart}
															onQuickView={onQuickView}
															isFavorite={wishlistIds?.has(product.id) ?? false}
															onToggleWishlist={onToggleWishlist}
														/>
													))}
											</CategoryShowcaseMain>
										</CategoryShowcaseLayout>
									</CategoryProductBody>
								</CategoryProductSection>
							);
						})}
						</CategoryCatalog>
					) : (
						<>
							<CatalogToolbar>
								<Tooltip
									title="Vista grilla"
									arrow
								>
									<CatalogViewButton
										type="button"
										active={!listView}
										aria-label="Vista grilla"
										onClick={() => setListView(false)}
									>
										<GridViewRoundedIcon />
									</CatalogViewButton>
								</Tooltip>
								<Tooltip
									title="Vista lista"
									arrow
								>
									<CatalogViewButton
										type="button"
										active={listView}
										aria-label="Vista lista"
										onClick={() => setListView(true)}
									>
										<ViewListRoundedIcon />
									</CatalogViewButton>
								</Tooltip>
								<CatalogToolbarLabel>Ordenar por:</CatalogToolbarLabel>
								<select
									aria-label="Ordenar por"
									value={catalogSort}
									onChange={(event) => onSetCatalogSort(event.target.value as CatalogSort)}
								>
									<option value="default">Predeterminado</option>
									<option value="priceAsc">Precio: menor a mayor</option>
									<option value="priceDesc">Precio: mayor a menor</option>
									<option value="rating">Mejor valorados</option>
									<option value="newest">Novedades</option>
								</select>
								<CatalogToolbarLabel style={{ marginLeft: 'auto' }}>Mostrar:</CatalogToolbarLabel>
								<select
									aria-label="Productos por página"
									value={catalogPageSize}
									onChange={(event) => onSetCatalogPageSize(Number(event.target.value))}
								>
									{Array.from(new Set([catalog.pageSize, 12, 24, 48]))
										.sort((a, b) => a - b)
										.map((size) => (
											<option
												key={size}
												value={size}
											>
												{size}
											</option>
										))}
								</select>
							</CatalogToolbar>

							{!searchLoading && paginatedProducts.length === 0 ? (
								<SearchEmptyState>
									<SearchRoundedIcon />
									<strong>No encontramos productos</strong>
									<span>Probá con otra palabra, marca o categoría.</span>
								</SearchEmptyState>
							) : listView ? (
								<ProductListGrid>
									{paginatedProducts.map((product) => (
										<ProductListRow
											key={product.id}
											role="button"
											tabIndex={0}
											onClick={() => onOpenDetail(product)}
											onKeyDown={(e) => {
												if (e.key === 'Enter' || e.key === ' ') {
													e.preventDefault();
													onOpenDetail(product);
												}
											}}
										>
											<div>
												<img
													src={storeImageSrc(product.image, product.name)}
													alt={product.name}
												/>
												{catalog.showPromotionBadge && product.badges[0] && (
													<BadgeStack>
														<span>{product.badges[0]}</span>
													</BadgeStack>
												)}
											</div>
											<ProductListRowBody>
												<div>
													{(product.reviewCount ?? 0) > 0 && (
														<Rating>
															<StarRoundedIcon fontSize="inherit" />
															{product.rating} ({product.reviewCount})
														</Rating>
													)}
												</div>
												<h3>{product.name}</h3>
												<p>{product.description}</p>
												<PriceRow>
													<strong>{precioProducto(product.price, formatPrice)}</strong>
													{product.oldPrice && <del>{formatPrice(product.oldPrice)}</del>}
												</PriceRow>
												<ProductActions data-list-view="true">
													<Tooltip
														title="Agregar al carrito"
														arrow
														enterDelay={250}
													>
														<PrimaryIconAction
															aria-label={`Agregar ${product.name} al carrito`}
															onClick={(e) => {
																e.stopPropagation();
																onAddToCart(product);
															}}
														>
															<ShoppingCartRoundedIcon fontSize="small" />
														</PrimaryIconAction>
													</Tooltip>
													<Tooltip
														title="Ver detalle"
														arrow
														enterDelay={250}
													>
														<IconAction
															aria-label={`Ver detalle de ${product.name}`}
															data-action="view"
															onClick={(e) => {
																e.stopPropagation();
																onQuickView(product);
															}}
														>
															<VisibilityRoundedIcon fontSize="small" />
														</IconAction>
													</Tooltip>
													<Tooltip
														title="Agregar a favoritos"
														arrow
														enterDelay={250}
													>
														<IconAction
															aria-label={`Agregar ${product.name} a favoritos`}
															data-action="favorite"
															onClick={(e) => e.stopPropagation()}
														>
															<FavoriteRoundedIcon fontSize="small" />
														</IconAction>
													</Tooltip>
													{/* Comparar: oculto hasta la próxima etapa (falta implementar la comparación de productos) */}
												</ProductActions>
											</ProductListRowBody>
										</ProductListRow>
									))}
								</ProductListGrid>
							) : (
								<ProductGrid>
									{paginatedProducts.map((product) => (
										<StoreProductCard
											key={product.id}
											product={product}
											showBrand={catalog.showBrand}
											showStock={catalog.showStock}
											showCategory={catalog.showCategory}
											showPromotionBadge={catalog.showPromotionBadge}
											isFavorite={wishlistIds?.has(product.id) ?? false}
											formatPrice={formatPrice}
											onOpenDetail={onOpenDetail}
											onAddToCart={onAddToCart}
											onQuickView={onQuickView}
											onToggleWishlist={onToggleWishlist}
										/>
									))}
								</ProductGrid>
							)}

							{totalPages > 1 && (
								<PaginationBar>
									<Button
										variant="outlined"
										size="small"
										disabled={catalogPage === 1}
										onClick={() => onSetCatalogPage((current) => Math.max(1, current - 1))}
									>
										Anterior
									</Button>
									{getPaginationItems(catalogPage, totalPages).map((item) =>
										typeof item === 'number' ? (
											<Button
												key={item}
												data-pagination-page
												aria-label={`Ir a la página ${item}`}
												aria-current={item === catalogPage ? 'page' : undefined}
												variant={item === catalogPage ? 'contained' : 'outlined'}
												size="small"
												onClick={() => onSetCatalogPage(item)}
											>
												{item}
											</Button>
										) : (
											<span
												key={item}
												aria-hidden="true"
												data-pagination-ellipsis
											>
												…
											</span>
										)
									)}
									<Button
										variant="contained"
										size="small"
										disabled={catalogPage === totalPages}
										onClick={() => onSetCatalogPage((current) => Math.min(totalPages, current + 1))}
									>
										Siguiente
									</Button>
								</PaginationBar>
							)}
						</>
					)}
				</Catalog>
			</CatalogLayout>
		</>
	);
}
