/* IMACX composite blocks — Header, Footer, ProductCard, FacetSidebar, QuoteLine, QuoteSummary, Drawer */

function familyMenuThumbnail(f) {
  return `/images/menu-thumbnails/${f.id}.webp`;
}

const MEGA_COLS = FAMILIES.map((f) => ({
  h: f.name,
  fam: f.id,
  img: familyMenuThumbnail(f),
  sub: [],
}));

const SEARCH_SUG = ["Garrafas", "Sacos", "Bordado", "Powerbank", "Canetas", "Bambu", "Lanyard", "Bonés"];

function Header({ route, go, goCatalog, quoteCount, onOpenQuote, quoteOpen, onSearch, searchQuery }) {
  const [mega, setMega] = useState(false);
  const [search, setSearch] = useState(false);
  const [searchTerm, setSearchTerm] = useState("");
  const [contact, setContact] = useState(false);
  const [menu, setMenu] = useState(false);
  const [mcat, setMcat] = useState(false);
  const nav = ["Catálogo", "Galeria", "Blog", "Sobre nós"];
  const navRoute = (label) => label === "Catálogo" ? "categories" : label === "Galeria" ? "gallery" : label === "Blog" ? "blog" : label === "Sobre nós" ? "about" : "catalog";

  useEffect(() => {
    const onKey = (e) => {if (e.key === "Escape") {setSearch(false);setMega(false);setContact(false);setMenu(false);}};
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  useEffect(() => {
    document.body.style.overflow = menu ? "hidden" : "";
    return () => { document.body.style.overflow = ""; };
  }, [menu]);

  useEffect(() => {
    if (search) setSearchTerm(searchQuery || "");
  }, [search, searchQuery]);

  const goClose = (r) => {setMega(false);setSearch(false);setMenu(false);go(r);};
  const goCat = (fam) => {setMega(false);setSearch(false);setMenu(false);goCatalog(fam);};
  const runSearch = (term) => {
    const q = String(term || "").trim();
    setMega(false);
    setSearch(false);
    setMenu(false);
    onSearch(q);
  };
  const submitSearch = (event) => {
    event.preventDefault();
    runSearch(searchTerm);
  };

  return (
    <>
      <div className="imacx-annc">
        <span><span className="dot" /> De 10 a 10.000 unidades — o mesmo rigor do briefing à entrega</span>
        <span className="num" style={{ opacity: .7 }}>· Amostras disponíveis</span>
      </div>
      <header className="imacx-hd" onMouseLeave={() => setMega(false)}>
        <div className="wrapx imacx-hd-row">
          <a className="imacx-logo" onClick={() => goClose("home")} style={{ cursor: "pointer" }} aria-label="IMACX — início">
            <BrandLogo className="brand-logo" />
          </a>
          <nav className="imacx-nav">
            {nav.map((label, i) =>
            <button
              key={i}
              data-on={i === 0 && (route === "catalog" || route === "categories") || label === "Galeria" && route === "gallery" || label === "Blog" && (route === "blog" || route === "blogpost") || label === "Sobre nós" && route === "about"}
              onMouseEnter={() => setMega(i === 0)}
              onClick={() => goClose(navRoute(label))}>
              
                {label}{i === 0 ? <span className="cv" aria-hidden="true">▾</span> : null}
              </button>
            )}
          </nav>
          <div className="imacx-hd-actions">
            <button className="hd-ic" data-on={search} onClick={() => setSearch((v) => !v)} aria-label="Procurar" aria-pressed={search}>
              {Icons.search}
            </button>
            <button className="hd-ic hd-ic--accent" data-on={quoteOpen} onClick={onOpenQuote} aria-label="Orçamento" aria-pressed={quoteOpen}>
              {Icons.cart}
              {quoteCount > 0 ? <span className="count num">{quoteCount}</span> : null}
            </button>
            <div className="hd-contact">
              <button className="hd-ic" data-on={contact} onClick={() => setContact((v) => !v)} aria-label="Contactos" aria-pressed={contact} aria-expanded={contact}>
                {Icons.phone}
              </button>
              {contact ?
              <>
                  <div className="hd-pop-scrim" onClick={() => setContact(false)} />
                  <div className="hd-pop" role="dialog" aria-label="Contactos">
                    <span className="e">Fale connosco</span>
                    <a className="hd-pop-tel" href="tel:+351210000000">+351 210 000 000</a>
                    <a className="hd-pop-mail" href="mailto:ola@imacx.pt">ola@imacx.pt</a>
                    <div className="hd-pop-row"><span>Segunda a sexta</span><span className="num">9:00 – 18:00</span></div>
                    <div className="hd-pop-cities">Lisboa · Porto</div>
                    <button className="btn-accent btn-block" onClick={() => {setContact(false);go("request");}}>Pedir orçamento {Icons.arrow}</button>
                  </div>
                </> :
              null}
            </div>
            <button className="hd-ic hd-burger" onClick={() => setMenu(true)} aria-label="Menu" aria-expanded={menu}>
              <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"><path d="M4 7h16M4 12h16M4 17h16"/></svg>
            </button>
          </div>
        </div>

        <div className={"imacx-mega" + (mega ? " is-open" : "")} onMouseEnter={() => setMega(true)}>
          <div className="wrapx imacx-mega-in">
            <div className="imacx-mega-cols">
              {MEGA_COLS.map((col, i) =>
              <button className="mega-col" key={i} onClick={() => goCat(col.fam)} type="button">
                  <span className="mega-thumb" aria-hidden="true">
                    {col.img ?
                    <img className="mega-thumb-img" src={col.img} alt="" loading="lazy" /> :
                    null
                    }
                  </span>
                  <span className="mega-h">{col.h}</span>
                </button>
              )}
            </div>
          </div>
        </div>
      </header>

      {search ?
      <div className="search-overlay" onClick={() => setSearch(false)}>
          <div className="search-box" onClick={(e) => e.stopPropagation()}>
            <form className="search-row" role="search" aria-label="Pesquisar produtos" onSubmit={submitSearch}>
              {Icons.search}
              <input autoFocus value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} placeholder="Procure por produto, campanha ou técnica de marcação…" />
              <button className="esc" type="button" onClick={() => setSearch(false)}>ESC</button>
            </form>
            <div className="search-sug">
              <span className="lab">Sugestões populares</span>
              <div className="chips">
                {SEARCH_SUG.map((s, i) =>
              <button className="chipx" key={i} onClick={() => runSearch(s)}>{s}</button>
              )}
              </div>
            </div>
          </div>
        </div> :
      null}

      <div className="mnav-scrim" data-open={menu} onClick={() => setMenu(false)} />
      <aside className="mnav" data-open={menu} aria-hidden={!menu}>
        <div className="mnav-hd">
          <a className="imacx-logo" onClick={() => goClose("home")} style={{ cursor: "pointer" }} aria-label="IMACX — início">
            <BrandLogo className="brand-logo" />
          </a>
          <button className="iconbtn" onClick={() => setMenu(false)} aria-label="Fechar">{Icons.x}</button>
        </div>
        <nav className="mnav-body">
          <button className="mnav-link mnav-link--toggle" data-open={mcat} onClick={() => setMcat((v) => !v)} aria-expanded={mcat}>
            <span>Catálogo</span>
            <span className="mnav-chev" aria-hidden="true">▾</span>
          </button>
          {mcat ?
          <div className="mnav-sub">
            <button className="mnav-sublink" onClick={() => goClose("categories")}>Todas as categorias</button>
            {MEGA_COLS.map((col, i) =>
            <button className="mnav-sublink" key={i} onClick={() => goCat(col.fam)}>{col.h}</button>
            )}
          </div> :
          null}
          <button className="mnav-link" onClick={() => goClose("gallery")}>Galeria</button>
          <button className="mnav-link" onClick={() => goClose("blog")}>Blog</button>
          <button className="mnav-link" onClick={() => goClose("about")}>Sobre nós</button>
        </nav>
        <div className="mnav-foot">
          <span className="e">Fale connosco</span>
          <a className="mnav-tel" href="tel:+351210000000">+351 210 000 000</a>
          <a className="mnav-mail" href="mailto:ola@imacx.pt">ola@imacx.pt</a>
          <button className="btn-accent btn-block" style={{ marginTop: 18 }} onClick={() => {setMenu(false);go("request");}}>Pedir orçamento {Icons.arrow}</button>
        </div>
      </aside>
    </>);

}

function Footer({ go, goCatalog }) {
  const COMPANY = ["Quem somos", "Sustentabilidade", "O nosso blog"];
  const LEGAL = ["Sobre nós", "Apoio ao cliente", "Termos e condições", "Avisos legais", "Política de privacidade", "Política de cookies", "Mapa do site"];

  return (
    <footer className="imacx-ft">
      <div className="wrapx">
        <div className="cols">
          <div className="ft-brand">
            <div className="imacx-logo"><BrandLogo className="brand-logo brand-logo--lg" /></div>
            <p>
              O parceiro estratégico das marcas que precisam de reputação, confiança e execução em brindes corporativos. De 10 a 10.000 unidades.
            </p>
            <button className="btn-accent" style={{ marginTop: 24 }} onClick={() => go("request")}>
              Pedir orçamento {Icons.arrow}
            </button>
          </div>
          <div className="ft-col">
            <h5>A IMACX</h5>
            {COMPANY.map((l, j) => <a key={j} onClick={() => go(l === "O nosso blog" ? "blog" : l === "Quem somos" ? "about" : l === "Sustentabilidade" ? "sustentabilidade" : "categories")} style={{ cursor: "pointer" }}>{l}</a>)}
          </div>
          <div className="ft-contact">
            <h5>Fale connosco</h5>
            <a className="ft-tel" href="tel:+351210000000">+351 210 000 000</a>
            <a className="ft-mail" href="mailto:ola@imacx.pt">ola@imacx.pt</a>
            <div className="ft-hours"><span>Segunda a sexta-feira</span><span>9:00 às 18:00</span></div>
            <div className="ft-cities">Lisboa · Porto</div>
          </div>
        </div>

        <div className="ft-legal">
          <nav className="ft-legal-nav">
            {LEGAL.map((l, j) => <a key={j} onClick={() => go(LEGAL_ROUTE[l] || "home")} style={{ cursor: "pointer" }}>{l}</a>)}
          </nav>
        </div>
        <div className="copy">
          <span>© 2026 IMACX® · Brindes corporativos personalizados · Todos os direitos reservados</span>
          <span>Lisboa</span>
        </div>
      </div>
    </footer>);

}

function ProductCard({ p, onOpen }) {
  const fam = FAMILIES.find((f) => f.id === p.fam);
  const fromPrice = productFromPrice(p);
  return (
    <div className="pcard" onClick={() => onOpen(p)}>
      <div className="media">
        {p.img ?
        <div className="ph has-img" style={{ aspectRatio: "1/1", backgroundImage: `url(${p.img})`, backgroundSize: "cover", backgroundPosition: "center" }} /> :
        <Placeholder ratio="1/1" label={p.name} />}
        {p.badge ? <div className="badges"><Badge>{p.badge}</Badge></div> : null}
      </div>
      <div>
        <div className="fam">{fam ? fam.name : p.fam}</div>
        <div className="name" style={{ marginTop: 5 }}>{p.name}</div>
      </div>
      <div className="foot">
        <div>
          <Price tiers={p.tiers} qty={p.minq} single={fromPrice} quoteOnly={p.priceOnRequest} />
          <div className="minq" style={{ marginTop: 6 }}>Mín. {p.minq} un</div>
        </div>
        <span className="config">Configurar {Icons.arrow}</span>
      </div>
    </div>);

}

function productFromPrice(product) {
  if (product?.priceOnRequest) return null;
  const values = Object.values(product?.tiers || {}).map(Number).filter((value) => value > 0);
  return values.length ? Math.min(...values) : product?.base || 0;
}

function FacetSidebar({ groups, selected, onToggle, onClear, priceValue, onPriceChange }) {
  return (
    <aside className="facets">
      {groups.map((g) =>
      <FacetGroup key={g.id} group={g} selected={selected} onToggle={onToggle} onClear={onClear}
      priceValue={priceValue} onPriceChange={onPriceChange} />
      )}
    </aside>);

}

/* cart/quote line item — separates produto + impressão */
function QuoteLine({ item, onQty, onRemove, compact }) {
  const p = item.product;
  const printPricing = calculatePrintPricing(p, item.print, item.qty, item.printColors);
  const quoteOnlyLine = p.priceOnRequest || printPricing.quoteOnly;
  const tech = printPricing.tech;
  const color = COLORS.find((c) => c.id === item.color) || { name: item.color || "Consultar" };
  const unit = p.tiers[nearestTier(item.qty, p)] || p.base;
  const prod = unit * item.qty;
  const print = printPricing.total;
  const lineUnit = item.qty ? (prod + print) / item.qty : 0;
  return (
    <div className="line">
      {p.img ?
      <div className="ph has-img" style={{ aspectRatio: "1/1", backgroundImage: `url(${p.img})`, backgroundSize: "cover", backgroundPosition: "center" }} /> :
      <Placeholder ratio="1/1" label={p.name.split(" ")[0]} />}
      <div>
        <div className="li-top">
          <div className="li-name">{p.name}</div>
          <button className="rm" onClick={onRemove}>{Icons.x}</button>
        </div>
        <div className="li-spec">
          {color ? <>Cor <b>{color.name}</b> · </> : null}
          Marcação <b>{tech ? tech.name : "—"}</b>
          {availablePrintColorsFor(tech).length > 1 ? <> · <b>{normalizePrintColorCount(tech, item.printColors)} cores</b></> : null}
          {item.size ? <> · Tamanho <b>{item.size}</b></> : null}
        </div>
        <div className="li-foot">
          <div className="mini-stepper">
            <button onClick={() => onQty(Math.max(p.minq, item.qty - 25))}>−</button>
            <span className="num">{item.qty}</span>
            <button onClick={() => onQty(item.qty + 25)}>+</button>
          </div>
          <div style={{ textAlign: "right" }}>
            <div className="num" style={{ fontWeight: 600 }}>{quoteOnlyLine ? "Sob orçamento" : eur(prod + print)}</div>
            {!quoteOnlyLine && lineUnit ? <div className="li-spec num" style={{ marginTop: 2 }}>{eur(lineUnit)}/un</div> : null}
            <div className="li-spec" style={{ marginTop: 2 }} title="produto + personalização">
              <span className="num">{p.priceOnRequest ? "Sob orçamento" : eur(prod)}</span> + <span className="accent num">{printPricing.quoteOnly ? "Sob orçamento" : eur(print)}</span>
            </div>
          </div>
        </div>
      </div>
    </div>);

}

function quantityTiersFor(product) {
  return product?.quantityTiers?.length ? product.quantityTiers : QTY_TIERS;
}

function nearestTierFromList(qty, tiers) {
  const values = (tiers || QTY_TIERS).map(Number).filter(Boolean).sort((a, b) => a - b);
  let best = values[0] || qty;
  for (const t of values) if (qty >= t) best = t;
  return best;
}

function nearestTier(qty, product) {
  return nearestTierFromList(qty, quantityTiersFor(product));
}

function findPrintOption(product, printId) {
  return product?.printOptions?.find((t) => t.id === printId) || PRINT_OPTIONS.find((t) => t.id === printId);
}

function priceRowsForTech(tech) {
  if (Array.isArray(tech?.priceRows) && tech.priceRows.length) return tech.priceRows;
  if (typeof PRINT_PRICE_TABLES === "undefined" || !tech?.priceTableKey) return [];
  return PRINT_PRICE_TABLES[tech.priceTableKey]?.priceRows || [];
}

function availablePrintColorsFor(tech) {
  const explicit = (tech?.availablePrintColors || []).map(Number).filter((value) => value > 0);
  if (explicit.length) return [...new Set(explicit)].sort((a, b) => a - b);
  const rowColors = priceRowsForTech(tech).map((row) => Number(row.colorCount || 0)).filter((value) => value > 0);
  return [...new Set(rowColors)].sort((a, b) => a - b);
}

function normalizePrintColorCount(tech, colorCount = 1) {
  const available = availablePrintColorsFor(tech);
  if (!available.length) return 0;
  const requested = Math.max(1, Number(colorCount) || available[0]);
  if (available.includes(requested)) return requested;
  return available.find((value) => value >= requested) || available[available.length - 1];
}

function printIconColorCount(tech) {
  if (!tech || tech.id === "nenhuma") return 0;
  const name = String(tech.name || "").toLowerCase();
  if (name === "dtf" || name.includes("dtf")) return 4;
  if (name.includes("uv digital")) return 4;
  const available = availablePrintColorsFor(tech);
  if (available.length) return available[available.length - 1];
  return Number(tech.colors || 0);
}

function printRowsForColor(tech, colorCount = 1) {
  const rows = priceRowsForTech(tech).filter((row) => Number(row.publicValue) > 0);
  if (!rows.length) return [];
  const colors = normalizePrintColorCount(tech, colorCount);
  const exact = rows.filter((row) => Number(row.colorCount || 0) === colors);
  if (exact.length) return exact;
  const fullColor = rows.filter((row) => Number(row.colorCount || 0) === 0);
  return fullColor.length ? fullColor : rows.filter((row) => Number(row.colorCount || 0) === 1);
}

function printRowForQuantity(tech, qty, colorCount = 1) {
  const rows = printRowsForColor(tech, colorCount).slice().sort((a, b) => Number(a.quantity) - Number(b.quantity));
  if (!rows.length) return null;
  return rows.find((row) => qty <= Number(row.quantity)) || rows[rows.length - 1];
}

function calculatePrintPricing(product, printId, qty, colorCount = 1) {
  const tech = findPrintOption(product, printId);
  if (!tech || tech.id === "nenhuma") {
    return { tech, total: 0, tableValue: 0, row: null, colors: 0, quoteOnly: false };
  }
  if (tech.quoteOnly) {
    return { tech, total: 0, tableValue: 0, row: null, colors: 0, quoteOnly: true };
  }
  const colors = normalizePrintColorCount(tech, colorCount);
  const row = printRowForQuantity(tech, qty, colors);
  if (!row) return { tech, total: 0, tableValue: 0, row: null, colors, quoteOnly: false };
  const tableValue = Number(row.publicValue || 0);
  const total = row.valueType === "fixed_total" ? tableValue : tableValue * qty;
  return { tech, total, tableValue, row, colors, quoteOnly: false };
}

function quoteTotals(items) {
  let prod = 0,print = 0,units = 0;
  items.forEach((it) => {
    const p = it.product;
    if (p.priceOnRequest) return;
    const unit = p.tiers[nearestTier(it.qty, p)] || p.base;
    prod += unit * it.qty;
    print += calculatePrintPricing(p, it.print, it.qty, it.printColors).total;
    units += it.qty;
  });
  return { prod, print, units, total: prod + print };
}

function QuoteSummary({ items, showButton, onRequest }) {
  const t = quoteTotals(items);
  const productUnit = t.units ? t.prod / t.units : 0;
  const printUnit = t.units ? t.print / t.units : 0;
  const totalUnit = t.units ? t.total / t.units : 0;
  return (
    <div className="qsum">
      <div className="split-note">Produto e personalização separados</div>
      <div className="row sub"><span>Subtotal produto</span><span className="v num">{eur(t.prod)}{productUnit ? <small className="unit-note num">{eur(productUnit)}/un</small> : null}</span></div>
      <div className="row sub"><span>Subtotal personalização</span><span className="v num accent">{eur(t.print)}{printUnit ? <small className="unit-note num">{eur(printUnit)}/un</small> : null}</span></div>
      <div className="row sub"><span>Unidades totais</span><span className="v num">{t.units}</span></div>
      <div className="row sub"><span>Prazo estimado</span><span className="v">10–15 dias úteis</span></div>
      <div className="grand">
        <div><div style={{ fontWeight: 600 }}>Total</div><div className="est">sem IVA · sujeito a proposta</div></div>
        <span className="v num">{eur(t.total)}{totalUnit ? <small className="unit-note num">{eur(totalUnit)}/un</small> : null}</span>
      </div>
      <p className="estimate-notice">{window.ESTIMATED_PRICE_NOTICE || "Preços estimativos sem IVA, peça um orçamento formal."}</p>
      {showButton ?
      <button className="btn-accent btn-block btn-lg" style={{ marginTop: 20 }} onClick={onRequest}>
          Pedir orçamento com a equipa {Icons.arrow}
        </button> :
      null}
    </div>);

}

function QuoteDrawer({ open, items, onClose, onQty, onRemove, go }) {
  return (
    <>
      <div className="drawer-scrim" data-open={open} onClick={onClose} />
      <aside className="drawer" data-open={open} aria-hidden={!open}>
        <div className="drawer-hd">
          <h3>O seu orçamento {items.length ? <span className="muted num">· {items.length}</span> : null}</h3>
          <button className="iconbtn" onClick={onClose} aria-label="Fechar">{Icons.x}</button>
        </div>
        <div className="drawer-body">
          {items.length === 0 ?
          <div className="empty">
              <div className="big">Orçamento vazio</div>
              <p>Configure produtos e adicione-os aqui. Pode juntar vários itens num único pedido.</p>
              <button className="btn" style={{ marginTop: 18 }} onClick={() => {onClose();go("catalog");}}>Explorar catálogo</button>
            </div> :
          items.map((it) =>
          <QuoteLine key={it.uid} item={it} onQty={(q) => onQty(it.uid, q)} onRemove={() => onRemove(it.uid)} />
          )}
        </div>
        {items.length > 0 ?
        <div className="drawer-foot">
            <QuoteSummary items={items} showButton onRequest={() => {onClose();go("request");}} />
          </div> :
        null}
      </aside>
    </>);

}

Object.assign(window, { Header, Footer, ProductCard, FacetSidebar, QuoteLine, QuoteSummary, QuoteDrawer, quoteTotals, quantityTiersFor, nearestTier, nearestTierFromList, findPrintOption, priceRowsForTech, availablePrintColorsFor, normalizePrintColorCount, printIconColorCount, printRowForQuantity, calculatePrintPricing });
