// ─────────────────────────────────────────────────────────────────
// ornaments.jsx — vocabulario grafico do casamento
//
// Tudo que e "identidade" mora aqui: a estampa completa, as molduras,
// as ilustracoes contextuais, o monograma, os icones de traco dourado e o divisor
// ──────── ✦ AM ✦ ────────. As secoes so compoem estes blocos.
//
// Os .webp sao gerados por scripts/optimize-assets.py a partir dos PNGs de
// producao em assets/brand/. Os PNGs seguem no repositorio como fallback.
// ─────────────────────────────────────────────────────────────────

const WEB = '/assets/brand/web/';
const RAW = '/assets/brand/';
const GENERATED = RAW + 'generated/';

// arte estrutural — tem fallback PNG e dimensoes intrinsecas para evitar CLS
const ART = {
  molduraCortina: { webp: WEB + 'moldura-cortina-1000.webp', png: RAW + 'moldura_cortina.png', width: 1000, height: 1414 },
  moldura:        { webp: WEB + 'moldura-1000.webp',         png: RAW + 'moldura.png',         width: 1000, height: 1414 },
  campo:          { webp: WEB + 'campo-1600.webp',           png: RAW + 'campo.png',           width: 1600, height: 1274 },
  garcom1:        { webp: WEB + 'garcom-1-560.webp',         png: RAW + 'garcom_1.png',        width: 382,  height: 809 },
  garcom2:        { webp: WEB + 'garcom-2-560.webp',         png: RAW + 'garcom_2.png',        width: 484,  height: 831 },
  routeService:   { webp: WEB + 'roteiro-servico-1200.webp', png: GENERATED + 'roteiro-servico.png', width: 1536, height: 1024 },
  hotelMessenger: { webp: WEB + 'hospedagem-mensageiro-700.webp', png: GENERATED + 'hospedagem-mensageiro.png', width: 887, height: 1774 },
  giftComposition:{ webp: WEB + 'presentes-composicao-1200.webp', png: GENERATED + 'presentes-composicao.png', width: 1536, height: 1024 },
  curtainPanoramic:{ webp: WEB + 'cortina-panoramica-1672.webp', png: GENERATED + 'cortina-panoramica-v2.png', width: 1672, height: 941 },
  fieldPanoramic:  { webp: WEB + 'campo-golfe-clube-1672.webp',  png: GENERATED + 'campo-golfe-clube-v3.png',  width: 1672, height: 941 },
  venueChapel:     { webp: WEB + 'capela-editorial-1536.webp',    png: GENERATED + 'capela-editorial-v1.png',    width: 1536, height: 1024 },
  venueHotel:      { webp: WEB + 'suryaa-editorial-1536.webp',    png: GENERATED + 'suryaa-editorial-v1.png',    width: 1536, height: 1024 },
};

const MONO = (variant, size) => {
  const hero = variant === 'verde' && size >= 640;
  return {
    webp: `${WEB}monograma-${variant}-${hero ? 1200 : size >= 240 ? 600 : 240}.webp`,
    png: `${RAW}monograma_${variant}.png`,
    width: hero ? 1200 : 745,
    height: hero ? 1165 : 713,
  };
};

// ornamento decorativo — sempre a estampa completa, sem recortes
const ORN = {
  full:      WEB + 'estampa-full-1400.webp',
  fullGold:  WEB + 'estampa-full-gold-1400.webp',
};

// ─── <Art> — imagem com webp + fallback png ───
function Art({ art, alt = '', eager = false, className, style, ...rest }) {
  return (
    <picture>
      <source srcSet={art.webp} type="image/webp" />
      <img
        src={art.png}
        width={art.width}
        height={art.height}
        alt={alt}
        className={className}
        style={style}
        loading={eager ? 'eager' : 'lazy'}
        decoding={eager ? 'sync' : 'async'}
        {...rest}
      />
    </picture>
  );
}

// ─── <Monogram> — o AM ───
function Monogram({ variant = 'dourado', size = 120, alt = 'Aura & Marcel', className, style, eager = false }) {
  return (
    <Art
      art={MONO(variant, size)}
      alt={alt}
      eager={eager}
      className={className}
      style={{ height: size, width: 'auto', ...style }}
      draggable="false"
    />
  );
}

// compat: o codigo antigo chamava <NavMark size=.. variant=.. />
function NavMark(props) { return <Monogram {...props} />; }

// ─── <Photo> — foto do casal, servida na versao leve quando existir ───
// O manifesto e gerado por scripts/optimize-photos.py. Sem manifesto, cai na
// URL original do Supabase — funciona igual, so mais pesado.
function photoSet(url) {
  const entry = (window.PHOTO_MANIFEST || {})[url];
  if (!entry) return { src: url, srcSet: undefined };
  const set = [];
  if (entry.w800) set.push(entry.w800 + ' 800w');
  if (entry.w1600) set.push(entry.w1600 + ' 1600w');
  return { src: entry.w1600 || entry.w800 || url, srcSet: set.length ? set.join(', ') : undefined };
}

function Photo({ url, alt = '', sizes, className, style, eager = false }) {
  const { src, srcSet } = photoSet(url);
  return (
    <img
      src={src}
      srcSet={srcSet}
      sizes={sizes}
      alt={alt}
      className={className}
      style={style}
      loading={eager ? 'eager' : 'lazy'}
      decoding="async"
    />
  );
}

// ─── <Estampa> — arte completa centralizada na secao ───
function Estampa({ tone = 'ink', className = '', style }) {
  return (
    <div className={`estampa ${className}`} style={style} aria-hidden="true">
      <img
        src={tone === 'gold' ? ORN.fullGold : ORN.full}
        width="800"
        height="800"
        alt=""
        loading="lazy"
        decoding="async"
      />
    </div>
  );
}

// ─── <Rule> — divisor linear simples ───
function Rule({ className = '', style }) {
  return <div className={`rule ${className}`} style={style} aria-hidden="true" />;
}

// ─── <Garcom> — o garcom ilustrado atravessando o layout ───
function Garcom({ n = 1, className = '', style, alt = '' }) {
  return (
    <Art
      art={n === 2 ? ART.garcom2 : ART.garcom1}
      alt={alt}
      className={`garcom ${className}`}
      style={style}
    />
  );
}

// ─── <ContextArt> — cenas criadas para o contexto de cada secao ───
function ContextArt({ kind, className = '', style, alt = '' }) {
  const art = {
    route: ART.routeService,
    hotel: ART.hotelMessenger,
    gifts: ART.giftComposition,
    chapel: ART.venueChapel,
    venueHotel: ART.venueHotel,
  }[kind];
  if (!art) return null;
  return <Art art={art} alt={alt} className={`context-art context-art--${kind} ${className}`} style={style} />;
}

// ─── <Panorama> — paisagem horizontal criada para secoes full-bleed ───
function Panorama({ curtains = false, className = '', alt = 'Paisagem do Suryaa ao entardecer' }) {
  return (
    <div className={`panorama ${className}`}>
      <Art art={ART.fieldPanoramic} alt={alt} className="panorama__land" />
      {curtains && (
        <Art art={ART.curtainPanoramic} alt="" className="panorama__curtain" aria-hidden="true" />
      )}
    </div>
  );
}

// ─── <Scene> — a paisagem vista pela abertura da moldura com cortina ───
function Scene({ className = '' }) {
  return (
    <div className={`scene ${className}`}>
      <Panorama curtains className="scene__wide" />
      <div className="scene__portrait">
        <div className="scene__land">
          <Art art={ART.fieldPanoramic} alt="Campo de golfe e casa do clube ao entardecer" />
        </div>
        <Art art={ART.molduraCortina} alt="" className="scene__frame" aria-hidden="true" />
      </div>
    </div>
  );
}

// ─── <Arch> — moldura limpa como fundo arquitetonico ───
function Arch({ className = '' }) {
  return (
    <div className={`arch ${className}`}>
      <Art art={ART.moldura} alt="" className="arch__frame" aria-hidden="true" />
    </div>
  );
}

// ─── <Arrow> — a seta dos links editoriais ───
function Arrow() {
  return (
    <svg viewBox="0 0 16 8" fill="none" stroke="currentColor" strokeWidth="1" aria-hidden="true">
      <path d="M0 4h14M11 1l3 3-3 3" />
    </svg>
  );
}

// ─── <LinkArrow> — VER NO MAPA → ───
function LinkArrow({ href, children, className = '', onClick }) {
  const Tag = href ? 'a' : 'button';
  const extra = href ? { href, target: '_blank', rel: 'noopener noreferrer' } : { type: 'button', onClick };
  return (
    <Tag className={`link-arrow ${className}`} {...extra}>
      {children} <Arrow />
    </Tag>
  );
}

// ─── <LineIcon> — icones de traco, no mesmo registro das ilustracoes ───
const LINE_ICONS = {
  chapel: (
    <g>
      <path d="M24 2.5v6M21 5h6" />
      <path d="M7.5 22.5 24 8.5l16.5 14" />
      <path d="M10.5 22.5V45M37.5 22.5V45M6 45h36" />
      <path d="M20 45V33.5a4 4 0 0 1 8 0V45" />
      <path d="M14.8 28.2a2.1 2.1 0 0 1 4.2 0v4.3h-4.2zM29 28.2a2.1 2.1 0 0 1 4.2 0v4.3H29z" />
    </g>
  ),
  toast: (
    <g>
      <g transform="rotate(-13 14 22)">
        <path d="M7 11h14l-2.2 7a4.9 4.9 0 0 1-9.6 0z" />
        <path d="M14 18.6V33M9.8 34h8.4" />
      </g>
      <g transform="rotate(13 34 22)">
        <path d="M27 11h14l-2.2 7a4.9 4.9 0 0 1-9.6 0z" />
        <path d="M34 18.6V33M29.8 34h8.4" />
      </g>
      <path d="M24 4v4M21.4 6.2l1.6 1.6M26.6 6.2 25 7.8" />
    </g>
  ),
  dinner: (
    <g>
      <circle cx="24" cy="25" r="12.5" />
      <circle cx="24" cy="25" r="8.6" />
      <path d="M6.5 10.5v7M9.5 10.5v7M12.5 10.5v7M6.5 17.5h6M9.5 17.5V39" />
      <path d="M38.5 39V25M35.5 25h6c0-7-1.2-11-3-13.5-1.8 2.5-3 6.5-3 13.5z" />
    </g>
  ),
  rooftop: (
    <g>
      <path d="M24 3.5v8" />
      <circle cx="24" cy="28" r="14" />
      <path d="M10 28h28M12.7 20.6h22.6M12.7 35.4h22.6" />
      <path d="M24 14c-4.6 4.2-4.6 23.8 0 28M24 14c4.6 4.2 4.6 23.8 0 28" />
      <path d="M17.2 15c-2.7 4.8-2.7 21.2 0 26M30.8 15c2.7 4.8 2.7 21.2 0 26" />
    </g>
  ),
  dress: (
    <g>
      <path d="M18 7.5 24 13l6-5.5" />
      <path d="M18 7.5c-5.2 1.7-7.8 4.3-7.8 8.4V43h27.6V15.9c0-4.1-2.6-6.7-7.8-8.4" />
      <path d="M18 7.5 24 16l-2.6 27M30 7.5 24 16l2.6 27" />
      <path d="M21 17.5 24 19.5l-3 2zM27 17.5 24 19.5l3 2z" />
    </g>
  ),
  parking: (
    <g>
      <path d="M6 34v-7.5l4-2 3.5-8.5h21l3.5 8.5 4 2V34" />
      <path d="M13.5 16h21l3 10.5H10.5z" />
      <path d="M6 34h36" />
      <circle cx="14.5" cy="34" r="3.4" />
      <circle cx="33.5" cy="34" r="3.4" />
    </g>
  ),
  stay: (
    <g>
      <path d="M5 40V25.5h38V40M5 33h38M5 40v3.5M43 40v3.5" />
      <path d="M11.5 25.5V17h25v8.5" />
      <path d="M15.5 21.5h6M26.5 21.5h6" />
      <path d="M24 6.5v6M21.5 9h5" />
    </g>
  ),
  hotel: (
    <g>
      <path d="M8 17h32v24H8z" />
      <path d="M19 17v-3.5a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2V17" />
      <path d="M8 25h32M8 33h32M24 17v24" />
    </g>
  ),
  kids: (
    <g>
      <path d="M24 3c7.2 0 12.5 6 12.5 13.6S31.2 30.5 24 30.5 11.5 24.2 11.5 16.6 16.8 3 24 3z" />
      <path d="M21.6 30.5 24 34.5l2.4-4" />
      <path d="M24 34.5c0 4.6-4 4.6-4 8s4 3.4 4 6.5" />
      <path d="M24 3c-3.4 4-3.4 23.5 0 27.5M24 3c3.4 4 3.4 23.5 0 27.5" />
    </g>
  ),
  beauty: (
    <g>
      <circle cx="20" cy="17" r="14" />
      <circle cx="20" cy="17" r="10" />
      <path d="M29.9 26.9 42 43M38.4 37.4l-3.6 3.6" />
      <path d="M39 6v6M36 9h6" />
    </g>
  ),
  ring: (
    <g>
      <circle cx="19" cy="27" r="10.5" />
      <circle cx="30" cy="27" r="10.5" />
      <path d="M30 12.5 27 8h6z" />
    </g>
  ),
};

function LineIcon({ kind, className = '', style }) {
  return (
    <svg
      viewBox="0 0 48 48"
      className={className}
      style={style}
      fill="none"
      stroke="currentColor"
      strokeWidth="1.1"
      strokeLinecap="round"
      strokeLinejoin="round"
      aria-hidden="true"
    >
      {LINE_ICONS[kind] || LINE_ICONS.ring}
    </svg>
  );
}

// ─── revelacao no scroll ───
// Um unico IntersectionObserver para toda a pagina. Reescaneia quando o React
// injeta conteudo assincrono (fotos, presentes, cards de informacao).
function initReveal() {
  if (window.__revealReady) return;
  window.__revealReady = true;

  const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  if (reduced) {
    const showAll = () => document.querySelectorAll('.reveal:not(.is-in)').forEach((el) => el.classList.add('is-in'));
    showAll();
    new MutationObserver(showAll).observe(document.body, { childList: true, subtree: true });
    return;
  }

  const io = new IntersectionObserver((entries) => {
    entries.forEach((entry) => {
      if (!entry.isIntersecting) return;
      entry.target.classList.add('is-in');
      io.unobserve(entry.target);
    });
  }, { rootMargin: '0px 0px -6% 0px', threshold: 0.05 });

  const scan = () => {
    document.querySelectorAll('.reveal:not(.is-in)').forEach((el) => {
      if (el.dataset.revealBound) return;
      el.dataset.revealBound = '1';
      io.observe(el);
    });
  };

  scan();
  new MutationObserver(scan).observe(document.body, { childList: true, subtree: true });
}

// atalho para escalonar um grupo de elementos revelados
const stagger = (i, step = 90) => ({ '--reveal-delay': `${i * step}ms` });

Object.assign(window, {
  ART, ORN, MONO,
  Art, Photo, photoSet, Monogram, NavMark, Estampa, Rule, Garcom, ContextArt, Scene, Arch,
  Arrow, LinkArrow, LineIcon, initReveal, stagger,
});
