/* IMACX pages — Home, Catalog, Product, Request (quote), Confirmation */

function HomePage({ go, openProduct }) {
  return (
    <div className="wrapx">
      <section className="hero">
        <span className="eyebrow">Brindes corporativos personalizados</span>
        <h1>Não somos apenas mais uma empresa de <span className="ac">brindes</span>.</h1>
        <p>Criamos, produzimos e acompanhamos brindes corporativos para empresas, campanhas, eventos e ativações de marca. De 10 a 10.000 unidades, com o mesmo rigor do briefing à entrega.</p>
        <div className="hero-cta">
          <button className="btn-accent btn-lg" onClick={() => go("catalog")}>Explorar produtos {Icons.arrow}</button>
          <button className="btn btn-lg" onClick={() => go("request")}>Pedir orçamento</button>
        </div>
      </section>

      <section style={{ marginTop: 24 }}>
        <div className="sec-hd">
          <h2>Encontre o brinde certo para a sua campanha</h2>
          <a className="more" onClick={() => go("catalog")} style={{ cursor: "pointer" }}>Ver todo o catálogo {Icons.arrow}</a>
        </div>
        <div className="fam-grid">
          {FAMILIES.filter((f) => f.displayInPrimaryNav !== false).slice(0, 6).map(f => (
            <div className="fam-card" key={f.id} onClick={() => go("catalog")}>
              <Placeholder ratio="16/10" label={f.name} />
              <div className="fc-top">
                <span className="fc-name">{f.name}</span>
                <span className="fc-n">{f.n}</span>
              </div>
              <span className="go">Ver família {Icons.arrow}</span>
            </div>
          ))}
        </div>
      </section>

      <section className="trust">
        {[
          ["Proposta", "Mais do que produzir. Propomos.", "Conhecemos catálogos, fornecedores, materiais e técnicas. Transformamos o briefing numa proposta alinhada com a marca, o orçamento e o prazo."],
          ["Escala", "10 ou 10.000. O mesmo cuidado.", "Acompanhamos encomendas pequenas, médias e grandes com o mesmo rigor: produto, validação de marcação, amostras, produção e entrega."],
          ["Capacidade", "Equipa interna. Velocidade real.", "Acabamentos, embalagem e personalização manual com mais controlo operacional, menos subcontratação e mais segurança nos prazos."],
        ].map(([n, h, p], i) => (
          <div className="t" key={i}>
            <div className="n">{n}</div>
            <h3>{h}</h3>
            <p>{p}</p>
          </div>
        ))}
      </section>

      <section>
        <div className="sec-hd">
          <h2>Mais pedidos esta época</h2>
          <a className="more" onClick={() => go("catalog")} style={{ cursor: "pointer" }}>Ver mais {Icons.arrow}</a>
        </div>
        <div className="pgrid" data-cols="4" style={{ marginTop: 0 }}>
          {PRODUCTS.slice(0, 4).map(p => <ProductCard key={p.id} p={p} onOpen={openProduct} />)}
        </div>
      </section>
    </div>
  );
}

function CatalogPage({ go, openProduct, cols }) {
  const [selected, setSelected] = useState({});
  const [sort, setSort] = useState("rel");
  const toggle = (g, id) => setSelected(s => {
    const cur = s[g] || [];
    return { ...s, [g]: cur.includes(id) ? cur.filter(x => x !== id) : [...cur, id] };
  });
  const clear = (g) => setSelected(s => ({ ...s, [g]: [] }));
  const clearAll = () => setSelected({});

  const filtered = useMemo(() => {
    let r = PRODUCTS.filter(p => {
      if (selected.fam?.length && !selected.fam.includes(p.fam)) return false;
      if (selected.tech?.length && !selected.tech.some(t => p.techs.includes(t))) return false;
      if (selected.color?.length && !selected.color.some(c => p.colors.includes(c))) return false;
      if (selected.material?.length && !selected.material.includes(p.material)) return false;
      if (selected.eco?.length && !p.eco) return false;
      if (selected.minq?.length) {
        const ok = selected.minq.some(m => (m === "lt50" && p.minq < 50) || (m === "lt100" && p.minq < 100) || (m === "lt250" && p.minq < 250));
        if (!ok) return false;
      }
      return true;
    });
    if (sort === "price") r = [...r].sort((a, b) => a.base - b.base);
    if (sort === "rating") r = [...r].sort((a, b) => b.rating - a.rating);
    return r;
  }, [selected, sort]);

  const activeChips = [];
  Object.entries(selected).forEach(([g, ids]) => (ids || []).forEach(id => {
    const grp = FACET_GROUPS.find(x => x.id === g);
    const opt = grp?.options.find(o => o.id === id);
    if (opt) activeChips.push({ g, id, label: opt.label || opt.name });
  }));

  return (
    <div className="wrapx">
      <div className="crumbs">
        <a onClick={() => go("home")} style={{ cursor: "pointer" }}>Início</a>
        <span className="sep">/</span><span>Catálogo</span>
      </div>
      <div className="cat-head">
        <div>
          <span className="eyebrow">Catálogo</span>
          <h2 style={{ fontSize: "var(--t-h3)", fontWeight: 600, letterSpacing: "-.02em", margin: "10px 0 0" }}>Todos os produtos</h2>
        </div>
        <span className="muted num">{filtered.length} produtos</span>
      </div>
      <div className="cat-layout">
        <FacetSidebar groups={FACET_GROUPS} selected={selected} onToggle={toggle} onClear={clear} />
        <div>
          <div className="cat-toolbar">
            {activeChips.length ? (
              <div className="active-facets">
                {activeChips.map((c, i) => (
                  <span className="pill" key={i} onClick={() => toggle(c.g, c.id)}>{c.label} {Icons.x}</span>
                ))}
                <a className="muted" style={{ cursor: "pointer", fontSize: "var(--t-body-s)" }} onClick={clearAll}>Limpar tudo</a>
              </div>
            ) : <span className="muted" style={{ fontSize: "var(--t-body-s)" }}>Filtre por família, técnica, cor, material…</span>}
            <select className="selectx" style={{ marginLeft: "auto" }} value={sort} onChange={(e) => setSort(e.target.value)}>
              <option value="rel">Relevância</option>
              <option value="price">Preço (menor)</option>
              <option value="rating">Avaliação</option>
            </select>
          </div>
          {filtered.length ? (
            <div className="pgrid" data-cols={cols}>
              {filtered.map(p => <ProductCard key={p.id} p={p} onOpen={openProduct} />)}
            </div>
          ) : (
            <div className="empty"><div className="big">Nenhum produto encontrado</div><p>Ajuste os filtros para ver mais resultados.</p><button className="btn" style={{ marginTop: 16 }} onClick={clearAll}>Limpar filtros</button></div>
          )}
        </div>
      </div>
    </div>
  );
}

function ProductPage({ product, go, addToQuote, openProduct }) {
  const p = product;
  const productQtyTiers = quantityTiersFor(p);
  const visibleQtyTiers = Array.from(new Set([p.minq, ...productQtyTiers.filter(t => t >= p.minq)])).sort((a, b) => a - b);
  const defaultPrintId = (p.printOptions?.find(o => o.id === "nenhuma") || PRINT_OPTIONS.find(o => o.id === "nenhuma") || p.printOptions?.[0] || PRINT_OPTIONS[0]).id;
  const [color, setColor] = useState(p.colors[0]);
  const [print, setPrint] = useState(defaultPrintId);
  const [printColors, setPrintColors] = useState(1);
  const [qty, setQty] = useState(p.minq);
  const [ship, setShip] = useState(SHIPPING[0].id);
  const [thumb, setThumb] = useState(0);
  const [openStep, setOpenStep] = useState(1);
  const toggleStep = (s) => setOpenStep(o => (o === s ? 0 : s));
  const fam = FAMILIES.find(f => f.id === p.fam);
  const det = detailsFor(p);
  const gallery = p.gallery?.length ? p.gallery : (p.img ? [{ src: p.img, color: p.colors[0], size: "S/T" }] : []);
  const currentImage = gallery[thumb] || gallery[0];
  const selectColor = (nextColor) => {
    setColor(nextColor);
    const nextThumb = gallery.findIndex((item) => item.color === nextColor);
    if (nextThumb >= 0) setThumb(nextThumb);
    setOpenStep(2);
  };
  const selectThumb = (item, index) => {
    setThumb(index);
    if (item?.color) setColor(item.color);
  };

  const productPrintOptions = p.printOptions?.length ? p.printOptions : PRINT_OPTIONS;
  const printObj = productPrintOptions.find(o => o.id === print) || productPrintOptions[0];
  const printColorChoices = availablePrintColorsFor(printObj);
  const shipObj = SHIPPING.find(s => s.id === ship);
  const priceOnRequest = !!p.priceOnRequest;
  const unit = priceOnRequest ? 0 : (p.tiers[nearestTier(qty, p)] || p.base);
  const priceValues = Object.values(p.tiers || {}).filter(v => Number(v) > 0);
  const fromPrice = priceValues.length ? Math.min(...priceValues) : 0;
  const prod = unit * qty;
  const selectedPrintColors = printColorChoices.length ? normalizePrintColorCount(printObj, printColors) : 1;
  const printPricing = calculatePrintPricing(p, print, qty, selectedPrintColors);
  const printHasColorChoices = printColorChoices.length > 1;
  const hasSelectedPrint = printObj && printObj.id !== "nenhuma";
  const printSummaryStatus = hasSelectedPrint ? "Impressão selecionada" : "Sem impressão";
  const printSummaryDetail = hasSelectedPrint
    ? `${printObj?.name}${printObj?.colors > 1 ? ` · ${selectedPrintColors} cor${selectedPrintColors === 1 ? "" : "es"}` : ""}`
    : "Produto em branco";
  const printCost = printPricing.total;
  const quoteOnlyTotal = priceOnRequest || printPricing.quoteOnly;
  const shipCost = shipObj.price;
  const subtotal = prod + printCost + shipCost;
  const printUnit = printCost && qty ? printCost / qty : 0;
  const subtotalUnit = subtotal && qty ? subtotal / qty : 0;

  const colorObj = COLORS.find(c => c.id === color) || { id: color, name: color || "Consultar", hex: "#e5e7eb" };
  const colorOptions = p.colors.map(c => COLORS.find(x => x.id === c) || { id: c, name: c || "Consultar", hex: "#e5e7eb" });
  const selectedStockRows = det.stock.filter((s) => s.colorId === color);
  const selectedStock = selectedStockRows.find((s) => s.restock === "immediately") || selectedStockRows[0];
  const related = PRODUCTS.filter(x => x.fam === p.fam && x.id !== p.id);
  const moreLike = (related.length >= 4 ? related : [...related, ...PRODUCTS.filter(x => x.id !== p.id && x.fam !== p.fam)]).slice(0, 4);
  const isBest = p.badge === "Best-seller";

  useEffect(() => {
    setColor(p.colors[0] || "");
    setPrint((p.printOptions?.find(o => o.id === "nenhuma") || PRINT_OPTIONS.find(o => o.id === "nenhuma") || p.printOptions?.[0] || PRINT_OPTIONS[0]).id);
    setPrintColors(1);
    setThumb(0);
    setOpenStep(1);
  }, [p.id]);

  return (
    <div className="wrapx">
      <div className="crumbs">
        <a onClick={() => go("home")} style={{ cursor: "pointer" }}>Início</a><span className="sep">/</span>
        <a onClick={() => go("catalog")} style={{ cursor: "pointer" }}>{fam?.name}</a><span className="sep">/</span>
        <span>{p.name}</span>
      </div>
      <div className="pdp">
        <div className="gallery">
          <div className="main">
            {currentImage?.src ?
            <img src={currentImage.src} alt={`${p.name} · referência ${p.supplierRef || det.code}`} loading="eager" /> :
            <Placeholder ratio="1/1" label={`${p.name} · vista ${thumb + 1}`} />}
          </div>
          <div className="thumbs">
            {(gallery.length ? gallery : [0,1,2,3]).map((item, i) => (
              <div className="t" key={i} data-on={thumb === i} onClick={() => selectThumb(item, i)}>
                {item?.src ?
                <img src={item.src} alt={`${p.name} · imagem ${i + 1}`} loading="lazy" /> :
                <Placeholder ratio="1/1" label={`0${i+1}`} />}
              </div>
            ))}
          </div>
        </div>

        <div className="pdp-info">
          <div className="pdp-fam">
            <span className="eyebrow">{fam?.name}</span>
            {isBest ? <Badge tone="solid">★ Mais vendido</Badge> : (p.badge ? <Badge>{p.badge}</Badge> : null)}
            {p.eco && !p.badge ? <Badge tone="line">Eco</Badge> : null}
          </div>
          <div className="pdp-title-row">
            <h1 className="pdp-title">{p.name}</h1>
            <div className="price-from">
              <span>Preço desde</span>
              <b>{priceOnRequest ? "Sob orçamento" : eur(fromPrice || p.base)}{priceOnRequest ? null : <em>/un</em>}</b>
              <small>Sem IVA</small>
            </div>
          </div>
          <div className="pdp-meta">
            {p.rating ? <Rating value={p.rating} count={p.cnt} /> : null}
            <span className="muted">Ref. {p.supplierRef || det.code} · Mín. {p.minq} un</span>
          </div>
          <p className="pdp-sub">{p.blurb}</p>
          <div className="pdp-jump">
            <a href="#descricao">+ Descrição</a>
            <a href="#detalhes">+ Detalhes & especificações</a>
          </div>
          <SelectedStock color={colorObj} stock={selectedStock} count={selectedStockRows.length} />

          {/* ---- Step-by-step configuration (Passo 1–4) — accordion ---- */}
          <div className="steps-stack">
            <StepCard n="1" title="Selecione a cor do produto" hint={colorObj?.name}
                      open={openStep === 1} onToggle={() => toggleStep(1)}>
              <OptionSelector swatch options={colorOptions} value={color}
                              onChange={selectColor} />
            </StepCard>

            <StepCard n="2" title="Selecione a técnica de marcação" hint={printObj?.name}
                      open={openStep === 2} onToggle={() => toggleStep(2)}>
              <div className="print-opts">
                {productPrintOptions.map(o => (
                  <button key={o.id} className="print-opt" data-on={print === o.id}
                          onClick={() => {
                            const colorChoices = availablePrintColorsFor(o);
                            setPrint(o.id);
                            setPrintColors(colorChoices[0] || 1);
                            setOpenStep(colorChoices.length > 1 ? 2 : 3);
                          }}>
                    <span className="po-radio" />
                    <span className="po-text">
                      <b>{o.name}</b>
                      {o.sub ? <em>{o.sub}</em> : null}
                    </span>
                    {printIconColorCount(o) ? <Droplets n={printIconColorCount(o)} /> : null}
                  </button>
                ))}
              </div>
              {printHasColorChoices ? (
                <div className="color-count">
                  <span>Número de cores</span>
                  <div className="opts">
                    {printColorChoices.map(n => (
                      <button key={n} className="opt" data-on={selectedPrintColors === n} onClick={() => setPrintColors(n)}>{n}</button>
                    ))}
                  </div>
                </div>
              ) : null}
            </StepCard>

            <StepCard n="3" title="Indique a quantidade" hint={priceOnRequest ? "preço sob orçamento" : `escalão ${nearestTier(qty, p)} un · ${eur(unit)}/un`}
                      open={openStep === 3} onToggle={() => toggleStep(3)}>
              <div className="qty-row">
                <QuantityStepper value={qty} onChange={(v) => setQty(Math.max(p.minq, v))} />
                <div className="opts">
                  {visibleQtyTiers.map(t => (
                    <button key={t} className="opt" data-on={qty === t}
                            onClick={() => { setQty(t); setOpenStep(4); }}>{t}</button>
                  ))}
                </div>
              </div>
              <div className="tier-table" aria-label="Preços produto por quantidade">
                <div className="tier-table-hd">
                  <span>Escalões produto</span>
                  <span>Produto sem impressão · sem IVA</span>
                </div>
                <div className="tier-grid">
                  {visibleQtyTiers.map(t => (
                    <button key={t} className="tier-cell" data-on={qty === t}
                            onClick={() => setQty(t)}>
                      <span className="tier-q num">{t} un</span>
                      <span className="tier-p num">{priceOnRequest ? "Sob orçamento" : `${eur(p.tiers[nearestTier(t, p)] || p.base)}/un`}</span>
                    </button>
                  ))}
                </div>
              </div>
            </StepCard>

            <StepCard n="4" title="Selecione o método de envio" hint={shipObj.name}
                      open={openStep === 4} onToggle={() => toggleStep(4)}>
              <RadioRows value={ship} onChange={setShip}
                options={SHIPPING.map(s => ({ id: s.id, label: `${s.name}: ${s.days}`, sub: "para Portugal Continental",
                  right: s.price ? eur(s.price) : "Gratuito" }))} />
            </StepCard>
          </div>

          {/* ---- Live budget ---- */}
          <div className="qbox" aria-label="Resumo do pedido">
            <div className="qbox-hd"><span>Resumo do pedido</span><span className="num">{qty} unidades</span></div>
            <div className="row"><span className="k">{p.name}</span><span className="v price-pair"><span className="num">{priceOnRequest ? "Sob orçamento" : eur(prod)}</span>{!priceOnRequest ? <span className="unit-note num">{eur(unit)}/un</span> : null}</span></div>
            <div className="row"><span className="k"><span className="tag-split">{printSummaryStatus}</span> {printSummaryDetail}</span><span className="v price-pair accent"><span className="num">{printPricing.quoteOnly ? "Sob orçamento" : (printCost ? eur(printCost) : "—")}</span>{printUnit ? <span className="unit-note num">{eur(printUnit)}/un</span> : null}</span></div>
            <div className="row"><span className="k">Envio · {shipObj.name}</span><span className="v num">{shipCost ? eur(shipCost) : "Não calculado"}</span></div>
            <div className="row total"><span className="k">Total</span><span className="v price-pair"><span className="num">{quoteOnlyTotal ? "Sob orçamento" : eur(subtotal)}</span>{!quoteOnlyTotal && subtotalUnit ? <span className="unit-note num">{eur(subtotalUnit)}/un</span> : null}</span></div>
            <p className="estimate-notice">{window.ESTIMATED_PRICE_NOTICE}</p>
          </div>

          <button className="btn-accent btn-lg btn-block pdp-add"
                  onClick={() => addToQuote({ product: p, color, print, printColors: selectedPrintColors, qty, ship })}>
            Adicionar ao carrinho {Icons.plus}
          </button>
          <p className="pdp-ship-note">{Icons.spark} Entrega com impressão em {shipObj.days} · amostras disponíveis sob pedido</p>
        </div>
      </div>

      {/* ---- Long description ---- */}
      <section id="descricao" className="pdp-desc">
        <h2>Descrição</h2>
        <p className="lede">{p.blurb}</p>
        <div className="pdp-desc-grid">
          <div>
            <h4>Características principais</h4>
            <ul className="ticks">
              {keyFeatures(p, det).map((f, i) => <li key={i}>{f}</li>)}
            </ul>
          </div>
        </div>
      </section>

      {/* ---- Detail tabs ---- */}
      <section id="detalhes" className="pdp-tabs-wrap">
        <Tabs tabs={[
          { label: "Informação geral", body: <InfoGeneralTab p={p} det={det} go={go} /> },
          { label: "Detalhes de impressão", body: <PrintAreasTab p={p} det={det} /> },
          { label: "Disponibilidade", body: <StockTab p={p} det={det} selectedColor={color} /> },
          { label: "Envio", body: <ShippingTab /> },
        ]} />
      </section>

      <section style={{ marginBottom: 40 }}>
        <div className="sec-hd"><h2 style={{ fontSize: "var(--t-h4)" }}>Produtos relacionados</h2><a className="more" onClick={() => go("catalog")} style={{ cursor: "pointer" }}>Ver catálogo {Icons.arrow}</a></div>
        <div className="pgrid" data-cols="4">
          {moreLike.map(r => <ProductCard key={r.id} p={r} onOpen={openProduct} />)}
        </div>
      </section>
    </div>
  );
}

/* ---- Long-description copy helpers ---- */
function descHeadline(p) {
  const m = {
    "artigos-sustentaveis": "Uma opção de brinde com foco responsável",
    sacos: "Logótipo visível, em qualquer lado",
    garrafas: "Hidratação de marca, todos os dias",
    textil: "A base perfeita para vestir a sua marca",
    escrita: "O brinde de alto volume que toda a gente usa",
    escritorio: "Presença de marca em cima da secretária",
    tecnologia: "Um brinde útil que fica na mão do cliente",
    outdoor: "Visibilidade de marca ao ar livre",
    eventos: "Identidade coerente em feiras e congressos",
  };
  return m[p.fam] || `${(FAMILIES.find(f => f.id === p.fam)?.name) || "Produto personalizado"} para campanhas corporativas`;
}
function keyFeatures(p, det) {
  const features = [`Código do produto: ${det.code || p.supplierRef || p.id}`];
  if (det.material && det.material !== "Consultar") features.push(`Material: ${det.material}`);
  if (det.dims && det.dims !== "Consultar") features.push(`Dimensões: ${det.dims}`);
  if (det.weight && det.weight !== "Consultar") features.push(`Peso: ${det.weight}`);
  if (det.areas?.length) features.push(`Áreas de marcação: ${det.areas.map(a => a.pos).join(" · ")}`);
  features.push(`Pedido mínimo de ${p.minq} unidades`);
  return features;
}

/* ---- Tab bodies ---- */
function SpecRow({ k, v }) {
  if (v == null || v === "" || v === "Consultar") return null;
  return <div className="spec-row"><span className="sk">{k}</span><span className="sv num">{v}</span></div>;
}
function ConsultSpecRow({ k, v }) {
  return <div className="spec-row"><span className="sk">{k}</span><span className="sv num">{v || "Consultar"}</span></div>;
}

function stockStatus(stock) {
  if (!stock) return { available: "Consultar", restock: "Stock por confirmar", next: "" };
  const qty = Number(stock.available || 0);
  const immediate = stock.restock === "immediately";
  const next = stock.arrivals?.length ? `Próxima chegada +${stock.arrivals[0].qty} em ${stock.arrivals[0].date}` : "";
  return {
    available: Number.isFinite(qty) ? qty : "Consultar",
    restock: qty > 0 || immediate ? "Disponível imediato" : stock.restock === "confirmar" ? "Reposição a confirmar" : `Reposição ${stock.restock || "a confirmar"}`,
    next,
  };
}

function SelectedStock({ color, stock, count }) {
  const status = stockStatus(stock);
  const qty = Number(status.available || 0);
  const availableLabel = stock ? (qty > 0 ? `${status.available} un disponíveis` : "Sem stock imediato") : "Stock por confirmar";
  return (
    <div className="stock-choice">
      <span className="stock-dot" data-ok={!!stock} />
      <div>
        <b>{availableLabel}</b>
        <span>{color.name} · {status.restock}{status.next ? ` · ${status.next}` : ""}{count > 1 ? ` · ${count} movimentos` : ""}</span>
      </div>
    </div>
  );
}

function PackLine({ label, children }) {
  return (
    <div className="pack-line">
      <span className="pack-label">{label}</span>
      <span className="pack-value">{children}</span>
    </div>
  );
}

function PackagingBlock({ det }) {
  const pack = det.packaging;
  if (!pack) {
    return (
      <div className="info-cols">
        <div>
          <SpecRow k="Embalagem intermédia" v={det.pack.inner} />
          <SpecRow k="Medidas da caixa exterior" v={det.pack.boxDims} />
          <SpecRow k="Volume da caixa exterior" v={det.pack.volume} />
          <SpecRow k="Peso do produto" v={det.pack.productWeight} />
        </div>
        <div>
          <SpecRow k="Peso da caixa exterior" v={det.pack.boxWeight} />
          <SpecRow k="Quantidade por caixa" v={det.pack.perBox} />
          <SpecRow k="Taric" v={det.pack.taric} />
        </div>
      </div>
    );
  }
  return (
    <div className="pack-list">
      <PackLine label={pack.final.label}>{pack.final.units} · {pack.final.description}</PackLine>
      {pack.intermediate1?.units ? <PackLine label={pack.intermediate1.label}>{pack.intermediate1.units} pcs/ {pack.intermediate1.description}</PackLine> : null}
      {Number(pack.intermediate2?.units || 0) > 0 ? <PackLine label={pack.intermediate2.label}>{pack.intermediate2.units} pcs/ {pack.intermediate2.description}</PackLine> : null}
      <PackLine label={pack.master.label}>
        {pack.master.units} un · Alto: {pack.master.height || "Consultar"} cm / Largura: {pack.master.width || "Consultar"} cm / Longo: {pack.master.length || "Consultar"} cm / Peso: {pack.master.weight || "Consultar"} kg
      </PackLine>
      <PackLine label={pack.pallet.label}>
        {pack.pallet.units} un · Pacotes: {pack.pallet.boxes} · Peso sobre: {pack.pallet.weight} kg
      </PackLine>
    </div>
  );
}

function InfoGeneralTab({ p, det, go }) {
  return (
    <div className="tab-info">
      <div className="info-cols">
        <div>
          <h4>Características</h4>
          <SpecRow k="Código do produto" v={det.code} />
          <SpecRow k="Pedido mínimo" v={`${p.minq} unidades`} />
          <ConsultSpecRow k="Venda em múltiplos de" v={det.minMultiple} />
          <SpecRow k="Dimensões" v={det.dims} />
          <SpecRow k="Peso" v={det.weight} />
          <SpecRow k="Código de impressão" v={det.printCode || "Consultar"} />
        </div>
        <div>
          <h4>&nbsp;</h4>
          <SpecRow k="Material" v={det.material} />
          <SpecRow k="País de origem" v={det.origin} />
          <SpecRow k={det.taric ? "Taric" : "Código Intrastat"} v={det.taric || det.intrastat} />
          <SpecRow k="País de expedição" v={det.expedition} />
        </div>
      </div>

      <div className="info-cols info-cols-lower">
        <div>
          <h4>Embalagem</h4>
          <PackagingBlock det={det} />
        </div>
        <div>
          <h4>Também pode encontrá-lo em</h4>
          <ul className="alsoin">
            {det.alsoIn.map((l, i) => <li key={i}><a onClick={() => go("catalog")} style={{ cursor: "pointer" }}>{l}</a></li>)}
          </ul>
        </div>
      </div>
    </div>
  );
}
function PrintAreasTab({ p, det }) {
  return (
    <div className="tab-print">
      <h4>Áreas de impressão disponíveis</h4>
      <div className="area-grid">
        {det.areas.map((a, i) => (
          <div className="area-card" key={i}>
            {a.areaImageUrl ? (
              <figure className="area-source area-source-img">
                <img src={a.areaImageUrl} alt={`${p.name} · área de impressão ${a.pos}`} loading="lazy" />
                <figcaption>
                  <strong>{a.areaImg}</strong>
                  <span>{a.id ? `Área ${a.id}` : "Área por confirmar"}</span>
                </figcaption>
              </figure>
            ) : (
              <div className="area-source">
                <span className="area-source-k">Imagem da área</span>
                <strong>{a.areaImg || "Sem imagem pública"}</strong>
                <span>{a.id ? `Área ${a.id}` : "Área por confirmar"}</span>
              </div>
            )}
            <div className="area-specs">
              <SpecRow k="Posição" v={a.pos} />
              <SpecRow k="Tamanho máx." v={a.size} />
              <div className="tech-list">
                {(a.techniques || []).map((t) => (
                  <div className="tech-line" key={t.id}>
                    <span>{t.name}</span>
                    <b>{t.maxColors === "1" ? "máx. 1 cor" : t.maxColors ? `máx. ${t.maxColors} cores` : "consultar"}</b>
                  </div>
                ))}
              </div>
            </div>
          </div>
        ))}
      </div>
      <p className="tab-note">Áreas, dimensões máximas, códigos técnicos e técnicas recomendadas. As imagens de área só aparecem quando houver imagem pública confirmada.</p>
    </div>
  );
}
function StockTab({ p, det, selectedColor }) {
  return (
    <div className="tab-stock">
      <div className="stock-table">
        <div className="st-head"><span>Cor</span><span>Stock disponível</span><span>Próximas reposições *</span></div>
        {det.stock.map((s, i) => {
          const c = COLORS.find(x => x.id === s.colorId) || { name: s.colorId || "Consultar", hex: "#e5e7eb" };
          const status = stockStatus(s);
          return (
            <div className="st-row" key={i} data-selected={s.colorId === selectedColor}>
              <span className="st-color"><span className="sw" style={{ background: c?.hex }} />{c?.name}</span>
              <span className="num">{Number(status.available || 0) > 0 ? `+ ${status.available}` : "0"}</span>
              <span className="num">{s.arrivals?.length ? s.arrivals.map(a => `+ ${a.qty} · ${a.date}`).join(" / ") : "Sem reposição indicada"}</span>
            </div>
          );
        })}
      </div>
      <p className="tab-note">* As datas são estimadas e podem estar sujeitas a alterações.</p>
    </div>
  );
}
function ShippingTab() {
  return (
    <div className="tab-ship">
      <h4>Tempo de entrega <span className="muted" style={{ fontWeight: 400 }}>(dias úteis)</span></h4>
      <div className="ship-table-wrap">
        <table className="ship-table">
          <thead>
            <tr><th>Envio Standard</th>{SHIP_TABLE_COLS.map((c, i) => <th key={i} className="num">{c}</th>)}</tr>
          </thead>
          <tbody>
            {SHIP_TABLE_ROWS.map((r, i) => (
              <tr key={i}><th>{r.tech}</th>{r.d.map((d, j) => <td key={j} className="num">{d}</td>)}</tr>
            ))}
          </tbody>
        </table>
      </div>
      <p className="tab-note">Os dias contam a partir do pagamento (encomendas sem impressão) ou da aprovação da prova + pagamento (pedidos impressos). As quantidades correspondem ao número de impressões: 500 sacos impressos só na frente são 500 impressões; frente e verso são 1000.</p>
    </div>
  );
}

function RequestPage({ items, go, onSubmit, multiStep }) {
  const [step, setStep] = useState(0);
  const [form, setForm] = useState({
    companyName: "",
    taxId: "",
    contactName: "",
    role: "",
    email: "",
    phone: "",
    campaign: "",
    desiredDeadline: "",
    briefing: "",
    website: "",
  });
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState("");
  const steps = ["Empresa", "Briefing", "Confirmar"];
  const single = !multiStep;
  const update = (field) => (event) => setForm((current) => ({ ...current, [field]: event.target.value }));
  const submit = async () => {
    setError("");
    if (form.companyName.trim().length < 2 || form.contactName.trim().length < 2 || !/^\S+@\S+\.\S+$/.test(form.email.trim())) {
      setError("Preencha empresa, pessoa de contacto e um email válido.");
      return;
    }
    if (!items.length && form.briefing.trim().length < 10) {
      setError("Adicione pelo menos um produto ou descreva o pedido no briefing.");
      return;
    }
    setSubmitting(true);
    try {
      await onSubmit(form);
    } catch (submitError) {
      setError(submitError?.message || "Não foi possível enviar o pedido. Tente novamente.");
    } finally {
      setSubmitting(false);
    }
  };
  return (
    <div className="wrapx">
      <div className="crumbs"><a onClick={() => go("catalog")} style={{ cursor: "pointer" }}>Catálogo</a><span className="sep">/</span><span>Pedir orçamento</span></div>
      <div className="cat-head"><div><span className="eyebrow">Pedido de orçamento</span><h2 style={{ fontSize: "var(--t-h3)", fontWeight: 600, letterSpacing: "-.02em", margin: "10px 0 0" }}>Conte-nos o que precisa</h2></div></div>
      <div className="req">
        <div>
          {multiStep ? (
            <div className="steps">
              {steps.map((s, i) => (
                <div className="step" key={i} data-on={i <= step}><span className="n">{i < step ? Icons.check : i + 1}</span>{s}</div>
              ))}
            </div>
          ) : null}

          {(single || step === 0) ? (
            <div>
              <div className="field-row">
                <div className="field"><label className="label" htmlFor="quote-company">Empresa *</label><input id="quote-company" value={form.companyName} onChange={update("companyName")} autoComplete="organization" placeholder="Nome da empresa" /></div>
                <div className="field"><label className="label" htmlFor="quote-tax-id">NIF</label><input id="quote-tax-id" value={form.taxId} onChange={update("taxId")} inputMode="numeric" placeholder="000 000 000" /></div>
              </div>
              <div className="field-row">
                <div className="field"><label className="label" htmlFor="quote-contact">Pessoa de contacto *</label><input id="quote-contact" value={form.contactName} onChange={update("contactName")} autoComplete="name" placeholder="Nome próprio e apelido" /></div>
                <div className="field"><label className="label" htmlFor="quote-role">Cargo / departamento</label><input id="quote-role" value={form.role} onChange={update("role")} autoComplete="organization-title" placeholder="Ex.: Marketing" /></div>
              </div>
              <div className="field-row">
                <div className="field"><label className="label" htmlFor="quote-email">Email *</label><input id="quote-email" type="email" value={form.email} onChange={update("email")} autoComplete="email" placeholder="nome@empresa.pt" /></div>
                <div className="field"><label className="label" htmlFor="quote-phone">Telefone</label><input id="quote-phone" type="tel" value={form.phone} onChange={update("phone")} autoComplete="tel" placeholder="+351 ___ ___ ___" /></div>
              </div>
              <div aria-hidden="true" style={{ position: "absolute", left: "-10000px", width: 1, height: 1, overflow: "hidden" }}><label htmlFor="quote-website">Website</label><input id="quote-website" value={form.website} onChange={update("website")} tabIndex={-1} autoComplete="off" /></div>
            </div>
          ) : null}

          {(single || step === 1) ? (
            <div style={{ marginTop: single ? 8 : 0 }}>
              <div className="field-row">
                <div className="field"><label className="label" htmlFor="quote-campaign">Campanha / ocasião</label><input id="quote-campaign" value={form.campaign} onChange={update("campaign")} placeholder="Ex.: kit onboarding, feira, Natal" /></div>
                <div className="field"><label className="label" htmlFor="quote-deadline">Prazo desejado</label><input id="quote-deadline" value={form.desiredDeadline} onChange={update("desiredDeadline")} placeholder="Ex.: 3 semanas" /></div>
              </div>
              <div className="field"><label className="label" htmlFor="quote-briefing">Briefing {items.length ? null : "*"}</label><textarea id="quote-briefing" value={form.briefing} onChange={update("briefing")} placeholder="Conte-nos o que precisa: produtos, quantidades, públicos e qualquer requisito de marca." /></div>
              <div className="field" style={{ borderBottom: 0 }}>
                <span className="label">Logótipo / arte</span>
                <div className="dropzone">{Icons.upload}<div style={{ marginTop: 8, fontSize: "var(--t-body-s)" }}>Depois de enviar o pedido, responda ao email de confirmação com o logótipo ou arte final (AI, PDF, SVG ou PNG).</div></div>
              </div>
            </div>
          ) : null}

          {(single || step === 2) ? (
            <div style={{ marginTop: single ? 24 : 0 }}>
              {single ? <h3 style={{ fontSize: "var(--t-h5)", fontWeight: 600, margin: "0 0 14px" }}>Itens no orçamento</h3> : null}
              {items.length ? items.map(it => (
                <div className="line" key={it.uid} style={{ paddingInline: 0 }}>
      {it.product.img ?
      <div className="ph has-img" style={{ aspectRatio: "1/1", backgroundImage: `url(${it.product.img})`, backgroundSize: "cover", backgroundPosition: "center" }} /> :
      <Placeholder ratio="1/1" label={it.product.name.split(" ")[0]} />}
                  <div>
                    <div className="li-name">{it.product.name}</div>
                    <div className="li-spec">{(COLORS.find(c=>c.id===it.color)?.name || it.color || "Consultar")} · {findPrintOption(it.product, it.print)?.name || "Sem impressão"} · {it.qty} un</div>
                  </div>
                </div>
              )) : <p className="muted">Sem itens — pode descrever o pedido no briefing acima.</p>}
            </div>
          ) : null}

          <div style={{ display: "flex", gap: 12, marginTop: 28 }}>
            {multiStep && step > 0 ? <button className="btn btn-lg" onClick={() => setStep(step - 1)}>Voltar</button> : null}
            {multiStep && step < 2 ? (
              <button className="btn-accent btn-lg" onClick={() => setStep(step + 1)}>Continuar {Icons.arrow}</button>
            ) : (
              <button className="btn-accent btn-lg" onClick={submit} disabled={submitting}>{submitting ? "A guardar pedido…" : "Enviar pedido de orçamento"} {submitting ? null : Icons.arrow}</button>
            )}
          </div>
          {error ? <p role="alert" style={{ marginTop: 14, color: "#b42318", fontWeight: 600 }}>{error}</p> : null}
        </div>

        <aside className="req-aside">
          <div className="ahd">Resumo do orçamento <span className="muted num">{items.length} {items.length === 1 ? "item" : "itens"}</span></div>
          <div className="abody">
            {items.length ? items.map(it => (
              <div className="arow" key={it.uid}>
                <Placeholder ratio="1/1" label={it.product.name.split(" ")[0]} />
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: "var(--t-body-s)", fontWeight: 500, lineHeight: 1.3 }}>{it.product.name}</div>
                  <div className="muted" style={{ fontSize: "var(--t-label)", marginTop: 3 }}>{it.qty} un · {findPrintOption(it.product, it.print)?.name || "Sem impressão"}</div>
                </div>
              </div>
            )) : <p className="muted" style={{ fontSize: "var(--t-body-s)", padding: "10px 0" }}>Sem itens adicionados.</p>}
          </div>
          <div className="afoot">
            <QuoteSummary items={items} />
            <p className="muted" style={{ fontSize: "var(--t-label)", marginTop: 14, lineHeight: 1.5, textTransform: "uppercase", letterSpacing: ".06em" }}>
              {window.ESTIMATED_PRICE_NOTICE}
            </p>
          </div>
        </aside>
      </div>
    </div>
  );
}

function ConfirmationPage({ go, quote }) {
  return (
    <div className="wrapx">
      <div className="confirm">
        <div className="mark">{Icons.check}</div>
        <h1>Pedido de orçamento enviado</h1>
        <p>Obrigado. A equipa IMACX vai analisar o seu pedido e responder com uma proposta ajustada à sua campanha — com produto e personalização discriminados, prazo e amostras quando fizer sentido.</p>
        <div className="ref"><span className="muted" style={{ textTransform: "uppercase", letterSpacing: ".08em", fontSize: "var(--t-label)" }}>Referência guardada</span> <b className="num">{quote.reference}</b></div>
        <p className="muted" style={{ marginTop: 12 }}>Guarde esta referência para qualquer contacto com a equipa IMACX.</p>
        <div style={{ display: "flex", gap: 12, justifyContent: "center", marginTop: 36 }}>
          <button className="btn-accent btn-lg" onClick={() => go("catalog")}>Continuar a explorar {Icons.arrow}</button>
          <button className="btn btn-lg" onClick={() => go("home")}>Voltar ao início</button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { HomePage, CatalogPage, ProductPage, RequestPage, ConfirmationPage });
