const { useEffect, useState } = React;

// Ícone por função do botão, desenhado em SVG inline: nada de arquivo externo e a
// cor vem do CSS via currentColor, que é o oposto da cor do botão.
const ICONES = {
  seta: <path d="M4 10h11M11 5l5 5-5 5" />,
  conversa: <path d="M17 11.5c0 3-2.7 5.4-6 5.4a7 7 0 0 1-2.4-.4L4 18l1.3-3.3A5.2 5.2 0 0 1 4 11.5C4 8.5 6.7 6 10 6s7 2.5 7 5.5Z" />,
  selo: <><circle cx="10" cy="8.5" r="4.5" /><path d="M7 12.5 6 18l4-2 4 2-1-5.5" /></>,
};

const GRAFISMOS = {
  quote: <path d="M8.6 5.5C5.5 7 4 9.8 4 13.8V18h6.3v-6.4H7.8c0-1.6.9-3 2.7-4.1L8.6 5.5Zm8.4 0c-3.1 1.5-4.6 4.3-4.6 8.3V18h6.3v-6.4h-2.5c0-1.6.9-3 2.7-4.1L17 5.5Z" />,
  caminho: <><path d="M5 17.5 9.2 13l3 2.6L19 8.5" /><circle cx="5" cy="17.5" r="1.5" /><circle cx="19" cy="8.5" r="1.5" /></>,
  livro: <><path d="M5 5.5h5.5c1.3 0 2.5.6 3.2 1.6.7-1 1.9-1.6 3.2-1.6H20v13h-3.1c-1.3 0-2.5.6-3.2 1.5-.7-.9-1.9-1.5-3.2-1.5H5v-13Z" /><path d="M13.7 7.1v12.6" /></>,
  pessoas: <><circle cx="9" cy="8" r="2.7" /><circle cx="16.5" cy="9" r="2.1" /><path d="M4.5 18c.4-3 2.2-4.6 4.5-4.6s4.1 1.6 4.5 4.6M14.2 14c2.8 0 4.4 1.3 4.8 4" /></>,
  selo: <><circle cx="12" cy="12" r="7.2" /><path d="m8.8 12 2.1 2.1 4.4-4.4M9.4 18.4l-1.2 2.1 3.8-1 3.8 1-1.2-2.1" /></>,
};

function Grafismo({ tipo = 'caminho', className = '' }) {
  return <svg className={`grafismo ${className}`} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.65" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">{GRAFISMOS[tipo]}</svg>;
}

function DisabledButton({ children, className = '', small = false, icone = 'seta', href = '' }) {
  const desenho = ICONES[icone];
  const conteudo = <><span>{children}</span>{desenho && <svg className="cta__icone" viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">{desenho}</svg>}</>;
  if (href) return <a className={`cta ${small ? 'cta--small' : ''} ${className}`} href={href} target="_blank" rel="noopener noreferrer">{conteudo}</a>;
  return <button className={`cta ${small ? 'cta--small' : ''} ${className}`} type="button" disabled aria-disabled="true" title="Destino de contato pendente no material de origem">
    {conteudo}
  </button>;
}

function Eyebrow({ children }) {
  return <p className="eyebrow" data-reveal="block">{children}</p>;
}

// `layout` decide a diagramação do cabeçalho da dobra:
//   'duplo'  título à esquerda, introdução à direita, alinhados pela base.
//   'centro' cabeçalho centrado, para dobra sem introdução.
//   padrão   empilhado, para quando a coluna ao lado já tem conteúdo.
// Existe porque 5 das 13 dobras usavam só 51% da calha na faixa do título.
function SectionTitle({ eyebrow, title, intro, light = false, layout = '' }) {
  const variante = layout ? `section-title--${layout}` : '';
  return <header className={`section-title ${light ? 'section-title--light' : ''} ${variante}`}>
    {eyebrow && <Eyebrow>{eyebrow}</Eyebrow>}
    <h2 data-reveal="words">{title}</h2>
    {intro && <p className="section-intro" data-reveal="block">{intro}</p>}
  </header>;
}

function Countdown({ deadline }) {
  const getRemaining = () => Math.max(0, new Date(deadline).getTime() - Date.now());
  const [remaining, setRemaining] = useState(getRemaining());
  useEffect(() => {
    const id = window.setInterval(() => setRemaining(getRemaining()), 1000);
    return () => window.clearInterval(id);
  }, [deadline]);
  const total = Math.floor(remaining / 1000);
  const days = Math.floor(total / 86400);
  const hours = Math.floor((total % 86400) / 3600);
  const minutes = Math.floor((total % 3600) / 60);
  const seconds = total % 60;
  return <div className="countdown" aria-label="Contagem regressiva até 31 de agosto">
    {[['dias', days], ['horas', hours], ['min', minutes], ['seg', seconds]].map(([label, value]) => <div className="countdown__cell" key={label}><b>{String(value).padStart(2, '0')}</b><span>{label}</span></div>)}
  </div>;
}

function TestimonialCard({ item, compact = false }) {
  const name = Array.isArray(item) ? item[0] : item.name;
  const quote = Array.isArray(item) ? item[1] : item.quote;
  return <figure className={`quote-card ${compact ? 'quote-card--compact' : ''}`} data-reveal="block">
    <Grafismo tipo="quote" className="quote-card__grafismo" />
    <blockquote>“{quote}”</blockquote>
    <figcaption>{name}</figcaption>
  </figure>;
}

function StatRibbon({ stats }) {
  const icones = ['livro', 'caminho', 'pessoas'];
  return <div className="stat-ribbon">{stats.map((stat, index) => <strong key={stat}><Grafismo tipo={icones[index % icones.length]} /><CountUpText>{stat}</CountUpText></strong>)}</div>;
}

// Um acordeão só serve o FAQ e a grade de módulos. `renderBody` deixa o corpo ser
// um parágrafo ou uma lista de tópicos sem duplicar estado, marcação e acesso.
function Accordion({ items, className = '', getKey, renderHead, renderBody, initialOpen = 0 }) {
  const [open, setOpen] = useState(initialOpen);
  const key = getKey || ((item) => item[0]);
  const head = renderHead || ((item) => <span>{item[0]}</span>);
  const body = renderBody || ((item) => <p>{item[1]}</p>);
  return <div className={`faq-list ${className}`}>
    {items.map((item, index) => {
      const isOpen = open === index;
      return <article className={`faq-item ${isOpen ? 'is-open' : ''}`} key={key(item)} data-reveal="block">
        <h3><button aria-expanded={isOpen} onClick={() => setOpen(isOpen ? -1 : index)}>{head(item)}<i aria-hidden="true">+</i></button></h3>
        <div className="faq-item__answer" hidden={!isOpen}>{body(item)}</div>
      </article>;
    })}
  </div>;
}

// Anima só o número que abre a frase e devolve o resto do texto intacto. Se a
// string não começar com número, renderiza verbatim e não faz nada.
function CountUpText({ children }) {
  const texto = String(children);
  const match = texto.match(/^([\d.]+)(\s[\s\S]*)$/);
  const alvo = match ? Number(match[1].replace(/\./g, '')) : null;
  const [valor, setValor] = useState(alvo);
  const ref = React.useRef(null);

  useEffect(() => {
    if (alvo === null || !ref.current) return;
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
    if (!('IntersectionObserver' in window)) return;
    let raf = 0;
    const observer = new IntersectionObserver((entries) => {
      if (!entries.some((e) => e.isIntersecting)) return;
      observer.disconnect();
      const inicio = performance.now();
      const passo = (agora) => {
        const t = Math.min(1, (agora - inicio) / 900);
        setValor(Math.round(alvo * (1 - Math.pow(1 - t, 3))));
        if (t < 1) raf = requestAnimationFrame(passo);
      };
      setValor(0);
      raf = requestAnimationFrame(passo);
    }, { threshold: 0.4 });
    observer.observe(ref.current);
    return () => { observer.disconnect(); cancelAnimationFrame(raf); };
  }, [alvo]);

  if (alvo === null) return <span ref={ref}>{texto}</span>;
  return <span ref={ref}>{valor.toLocaleString('pt-BR')}{match[2]}</span>;
}

// Vegetação em três planos de profundidade. A leitura de 3D vem de escala,
// sobreposição, sangria pela borda e velocidade de parallax distinta por plano.
// Nunca de opacidade reduzida nem de desfoque: planta apagada foi rejeitada.
function Flora({ plano = 'fundo', especie = 'monstera', pos = 'dir-topo', espelho = false }) {
  return <span
    className={`flora flora--${plano} flora--${pos} ${espelho ? 'flora--espelho' : ''}`}
    data-especie={especie}
    aria-hidden="true"
  />;
}

function TechnicalPlaceholder({ label, className = '' }) {
  return <div className={`technical-placeholder ${className}`} role="img" aria-label={label}><span>{label}</span></div>;
}
