/* global React, SFIcons, SectionHead */
const { Filter, ChevronDown } = SFIcons;
const { ProductCard: PC2 } = window.MADECIDesignSystem_419fb1;

function FilterGroup({ title, children, selected, open = false }) {
  const [o, setO] = React.useState(open);
  // Al elegir una opción concreta, el grupo se cierra solo y deja ver solo lo elegido.
  // Para cambiarla, el cliente vuelve a abrir el desplegable.
  const prev = React.useRef(selected);
  React.useEffect(() => {
    if (selected !== prev.current) {
      prev.current = selected;
      if (selected) setO(false);
    }
  }, [selected]);
  return (
    <div style={{ borderBottom: '1px solid var(--border-subtle)', padding: '16px 0' }}>
      <button onClick={() => setO(!o)} style={{ width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10, background: 'none', border: 'none', cursor: 'pointer', padding: 0 }}>
        <span style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 14, letterSpacing: '.02em', color: 'var(--text-strong)', textTransform: 'uppercase', flex: 'none' }}>{title}</span>
        <span style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }}>
          {selected && !o && (
            <span style={{ fontFamily: 'var(--font-body)', fontSize: 13, fontWeight: 600, color: 'var(--madeci-red)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{selected}</span>
          )}
          <ChevronDown size={16} stroke="var(--text-muted)" style={{ flex: 'none', transform: o ? 'none' : 'rotate(-90deg)', transition: 'transform .15s' }} />
        </span>
      </button>
      {o && <div style={{ marginTop: 12, display: 'flex', flexDirection: 'column', gap: 9 }}>{children}</div>}
    </div>
  );
}

// Single-select radio row
function Radio({ label, count, selected, onSelect }) {
  return (
    <label onClick={onSelect} style={{ display: 'flex', alignItems: 'center', gap: 10, cursor: 'pointer', fontFamily: 'var(--font-body)', fontSize: 14, color: selected ? 'var(--text-strong)' : 'var(--text-body)', fontWeight: selected ? 600 : 400 }}>
      <span style={{ width: 18, height: 18, borderRadius: 999, border: `1.5px solid ${selected ? 'var(--madeci-red)' : 'var(--border-strong)'}`, background: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 'none' }}>
        {selected && <span style={{ width: 9, height: 9, borderRadius: 999, background: 'var(--madeci-red)' }} />}
      </span>
      <span style={{ flex: 1 }}>{label}</span>
      {count != null && <span style={{ fontFamily: 'var(--font-data)', fontSize: 12.5, color: 'var(--text-subtle)' }}>{count}</span>}
    </label>
  );
}

// Convierte una capacidad ("600cc", "1.5L", "20L") a cc, solo para ordenar de menor a mayor.
const capCC = (s) => {
  if (!s) return 0;
  const m = String(s).match(/^([\d.,]+)\s*(cc|ml|l)$/i);
  if (!m) return 0;
  let v = parseFloat(m[1].replace(',', '.'));
  if (/^l$/i.test(m[2])) v *= 1000;
  return v;
};

// Orden lógico de las cepas en el filtro de Vinos: primero las cepas puras
// (tintas y luego blancas), después los estilos, y "Otras cepas" al final.
const CEPA_ORDEN = [
  'Cabernet Sauvignon', 'Carmenere', 'Merlot', 'Syrah', 'Malbec', 'Pinot Noir', 'Ensamblaje',
  'Sauvignon Blanc', 'Chardonnay',
  'Tinto', 'Blanco', 'Rosé', 'Late Harvest', 'Sangría y cocteles', 'Pipeño y chicha', 'Otras cepas',
];
const cepaOrden = (v) => { const i = CEPA_ORDEN.indexOf(v); return i === -1 ? 999 : i; };

// Arma una selección variada de "destacados": prioriza los que tienen stock y
// mezcla categorías para que no salgan todos de la misma (mejor primera impresión).
function destacadosDe(lista, max) {
  const enStock = lista.filter((p) => p.stockStatus === 'in');
  const pool = enStock.length ? enStock : lista;
  const porCat = {};
  for (const p of pool) (porCat[p.category] = porCat[p.category] || []).push(p);
  const cats = Object.keys(porCat);
  const res = [];
  let i = 0, restantes = pool.length;
  while (res.length < max && restantes > 0) {
    const arr = porCat[cats[i % cats.length]];
    if (arr && arr.length) { res.push(arr.shift()); restantes--; }
    i++;
  }
  return res;
}

function Sidebar({ categories, cat, setCat, formato, setFormato, cap, setCap, brand, setBrand, cepa, setCepa,
                   formatos, caps, marcas, cepas, optsFormato, optsCap, optsBrand, optsCepa }) {
  // Cada opción muestra cuántos productos quedarían si se selecciona (según los otros filtros ya activos).
  const countF = (v) => optsFormato.filter((p) => p.formato === v).length;
  const countC = (v) => optsCap.filter((p) => p.capacidad === v).length;
  const countB = (v) => optsBrand.filter((p) => p.brand === v).length;
  const countCe = (v) => optsCepa.filter((p) => p.cepa === v).length;
  return (
    <aside className="sf-side" style={{ width: 248, flex: 'none' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 16, color: 'var(--text-strong)' }}>
        <Filter size={18} stroke="var(--madeci-red)" /> Filtros
      </div>
      <FilterGroup title="Categoría" selected={cat === 'all' ? null : cat}>
        <Radio label="Todas las categorías" selected={cat === 'all'} onSelect={() => setCat('all')} />
        {categories.map((c) => <Radio key={c.id} label={c.name} count={c.count} selected={cat === c.name} onSelect={() => setCat(c.name)} />)}
      </FilterGroup>
      {/* Cepa: solo en Vinos (Random no la tiene; la derivamos del nombre). */}
      {cat === 'Vinos' && cepas.length > 0 && (
        <FilterGroup title="Cepa" selected={cepa === 'all' ? null : cepa}>
          <Radio label="Todas" selected={cepa === 'all'} onSelect={() => setCepa('all')} />
          {cepas.map((v) => <Radio key={v} label={v} count={countCe(v)} selected={cepa === v} onSelect={() => setCepa(cepa === v ? 'all' : v)} />)}
        </FilterGroup>
      )}
      {marcas.length > 0 && (
        <FilterGroup title="Marca" selected={brand === 'all' ? null : brand}>
          <Radio label="Todas" selected={brand === 'all'} onSelect={() => setBrand('all')} />
          {marcas.map((b) => <Radio key={b} label={b} count={countB(b)} selected={brand === b} onSelect={() => setBrand(brand === b ? 'all' : b)} />)}
        </FilterGroup>
      )}
      {formatos.length > 0 && (
        <FilterGroup title="Formato" selected={formato === 'all' ? null : formato}>
          <Radio label="Todos" selected={formato === 'all'} onSelect={() => setFormato('all')} />
          {formatos.map((f) => <Radio key={f} label={f} count={countF(f)} selected={formato === f} onSelect={() => setFormato(formato === f ? 'all' : f)} />)}
        </FilterGroup>
      )}
      {caps.length > 0 && (
        <FilterGroup title="Capacidad" selected={cap === 'all' ? null : cap}>
          <Radio label="Todas" selected={cap === 'all'} onSelect={() => setCap('all')} />
          {caps.map((v) => <Radio key={v} label={v} count={countC(v)} selected={cap === v} onSelect={() => setCap(cap === v ? 'all' : v)} />)}
        </FilterGroup>
      )}
    </aside>
  );
}

function CatalogView({ products, categories, onAdd, qtyEnCarrito, onView, query, setQuery, initialCat, loggedIn, onLogin }) {
  const [sort, setSort] = React.useState('Relevancia');
  const [cat, setCat] = React.useState(initialCat || 'all');
  const [formato, setFormato] = React.useState('all');
  const [brand, setBrand] = React.useState('all');
  const [cap, setCap] = React.useState('all');
  const [cepa, setCepa] = React.useState('all'); // solo aplica en Vinos
  const [visibles, setVisibles] = React.useState(24); // cuántos productos se muestran (para "ver más")

  // Sync when a category is chosen from the top nav
  const prevInit = React.useRef(initialCat);
  React.useEffect(() => {
    if (initialCat !== prevInit.current) {
      prevInit.current = initialCat;
      setCat(initialCat || 'all'); setFormato('all'); setBrand('all'); setCap('all'); setCepa('all');
    }
  }, [initialCat]);

  // When category changes, reset dependent filters so they reflect the new category
  const setCategory = (c) => { setCat(c); setFormato('all'); setBrand('all'); setCap('all'); setCepa('all'); if (query) setQuery(''); };

  // A new search should look across ALL categories, not stay pinned to the current one.
  const prevQuery = React.useRef(query);
  React.useEffect(() => {
    if (query !== prevQuery.current) {
      prevQuery.current = query;
      if (query) { setCat('all'); setFormato('all'); setBrand('all'); setCap('all'); setCepa('all'); }
    }
  }, [query]);

  const searched = query
    ? products.filter((p) => (p.name + p.brand + p.category).toLowerCase().includes(query.toLowerCase()))
    : products;
  const base = cat === 'all' ? searched : searched.filter((p) => p.category === cat);

  // Filtros en cascada: las opciones de cada filtro dependen de los OTROS filtros activos.
  // matchExcept(p, saltar) aplica todos los filtros menos el indicado (para poder cambiar dentro de ese).
  const matchExcept = (p, saltar) =>
    (saltar === 'formato' || formato === 'all' || p.formato === formato) &&
    (saltar === 'cap'     || cap === 'all'     || p.capacidad === cap) &&
    (saltar === 'brand'   || brand === 'all'   || p.brand === brand) &&
    (saltar === 'cepa'    || cepa === 'all'    || p.cepa === cepa);

  const optsFormato = base.filter((p) => matchExcept(p, 'formato'));
  const optsCap     = base.filter((p) => matchExcept(p, 'cap'));
  const optsBrand   = base.filter((p) => matchExcept(p, 'brand'));
  const optsCepa    = base.filter((p) => matchExcept(p, 'cepa'));
  const filtered    = base.filter((p) => matchExcept(p, null));

  const formatos = [...new Set(optsFormato.map((p) => p.formato).filter(Boolean))].sort((a, b) => a.localeCompare(b));
  const caps     = [...new Set(optsCap.map((p) => p.capacidad).filter(Boolean))].sort((a, b) => capCC(a) - capCC(b));
  const marcas   = [...new Set(optsBrand.map((p) => p.brand).filter(Boolean))].sort((a, b) => a.localeCompare(b));
  const cepas    = [...new Set(optsCepa.map((p) => p.cepa).filter(Boolean))].sort((a, b) => cepaOrden(a) - cepaOrden(b));

  // Si un filtro seleccionado deja de existir tras cambiar otro, se limpia solo (no quedan filtros "fantasma").
  React.useEffect(() => {
    if (formato !== 'all' && !formatos.includes(formato)) setFormato('all');
    if (cap !== 'all' && !caps.includes(cap)) setCap('all');
    if (brand !== 'all' && !marcas.includes(brand)) setBrand('all');
    if (cepa !== 'all' && !cepas.includes(cepa)) setCepa('all');
  }, [formato, cap, brand, cepa, cat, formatos.join('|'), caps.join('|'), marcas.join('|'), cepas.join('|')]);

  // Sin ningún filtro ni búsqueda mostramos una SELECCIÓN de destacados (no los ~1900, sería lento).
  const sinFiltros = cat === 'all' && formato === 'all' && cap === 'all' && brand === 'all' && cepa === 'all' && !query;
  const destacados = React.useMemo(() => (sinFiltros ? destacadosDe(products, 24) : []), [sinFiltros, products]);

  // Al cambiar de vista (categoría, filtro o búsqueda) reiniciamos el "ver más".
  React.useEffect(() => { setVisibles(24); }, [cat, formato, cap, brand, cepa, query]);

  const lista = sinFiltros ? destacados : filtered.slice(0, visibles);
  const hayMas = !sinFiltros && filtered.length > visibles;

  const titulo = query ? `Resultados para “${query}”` : (cat !== 'all' ? cat : 'Productos destacados');
  const bajada = sinFiltros
    ? 'Una selección para empezar — elige una categoría, filtra o busca lo que necesitas'
    : `${filtered.length} producto${filtered.length === 1 ? '' : 's'}${cat !== 'all' && !query ? ` en ${cat}` : ''} · precios con IVA incluido`;
  const crumb = query ? 'Búsqueda' : (cat === 'all' ? 'Destacados' : cat);

  return (
    <div className="sf-shell" style={{ maxWidth: 1280, margin: '0 auto', padding: '28px 24px 72px' }}>
      <div style={{ fontFamily: 'var(--font-body)', fontSize: 13, color: 'var(--text-muted)', marginBottom: 8 }}>Inicio · Catálogo · <span style={{ color: 'var(--text-strong)' }}>{crumb}</span></div>
      <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', marginBottom: 22 }}>
        <div>
          <h1 style={{ fontSize: 36, fontWeight: 800, letterSpacing: '-.02em' }}>{titulo}</h1>
          <p style={{ fontFamily: 'var(--font-body)', color: 'var(--text-muted)', marginTop: 4 }}>{bajada}</p>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, height: 42, padding: '0 14px', border: '1px solid var(--border-default)', borderRadius: 'var(--radius-sm)', background: '#fff', fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 14 }}>
          Ordenar: <span style={{ color: 'var(--madeci-red)' }}>{sort}</span> <SFIcons.ChevronDown size={16} />
        </div>
      </div>
      <div className="sf-stack" style={{ display: 'flex', gap: 28, alignItems: 'flex-start' }}>
        <Sidebar categories={categories} cat={cat} setCat={setCategory} formato={formato} setFormato={setFormato} brand={brand} setBrand={setBrand} cap={cap} setCap={setCap} cepa={cepa} setCepa={setCepa}
                 formatos={formatos} caps={caps} marcas={marcas} cepas={cepas} optsFormato={optsFormato} optsCap={optsCap} optsBrand={optsBrand} optsCepa={optsCepa} />
        <div style={{ flex: 1 }}>
          {filtered.length === 0 ? (
            <div style={{ padding: '60px 24px', textAlign: 'center', fontFamily: 'var(--font-body)', color: 'var(--text-muted)', border: '1px dashed var(--border-default)', borderRadius: 'var(--radius-lg)' }}>No hay productos que coincidan con estos filtros.</div>
          ) : (
            <React.Fragment>
              <div className="sf-cols-3" style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 18 }}>
                {lista.map((p) => loggedIn ? (
                  <div key={p.id} onClick={(e) => { if (e.target.closest('button')) return; onView(p); }} style={{ cursor: 'pointer', height: '100%' }}>
                    <PC2 {...p} cartQty={qtyEnCarrito ? { CJ: qtyEnCarrito(p.sku, 'CJ'), UN: qtyEnCarrito(p.sku, 'UN') } : undefined} onAdd={(q, modo) => onAdd(p, q, modo)} style={{ height: '100%' }} />
                  </div>
                ) : (
                  <GuestProductCard key={p.id} product={p} onLogin={onLogin} />
                ))}
              </div>
              {hayMas && (
                <div style={{ textAlign: 'center', marginTop: 30 }}>
                  <button onClick={() => setVisibles((v) => v + 24)} style={{ height: 46, padding: '0 26px', borderRadius: 'var(--radius-sm)', border: '1.5px solid var(--border-strong)', background: '#fff', cursor: 'pointer', fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 14.5, color: 'var(--text-strong)' }}>
                    Ver más productos · quedan {filtered.length - visibles}
                  </button>
                </div>
              )}
              {sinFiltros && (
                <div style={{ textAlign: 'center', marginTop: 22, fontFamily: 'var(--font-body)', fontSize: 13.5, color: 'var(--text-muted)' }}>
                  Estás viendo una selección. Elige una categoría o busca para ver el catálogo completo ({products.length} productos).
                </div>
              )}
            </React.Fragment>
          )}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { CatalogView, destacadosDe });
