/*
  app.jsx — composición + Tweaks
*/

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": ["#34c9ff", "#0a0a0a", "#ffffff"],
  "displayFont": "Instrument Sans",
  "displayWeight": 700,
  "heroMode": "frames",
  "aboutMode": "editorial",
  "lang": "es"
}/*EDITMODE-END*/;

const PALETTES = [
  { name: "Cian",      value: ["#34c9ff", "#0a0a0a", "#ffffff"] },
  { name: "Olivo",     value: ["#3f5240", "#1b1a17", "#f6f4ef"] },
  { name: "Terracota", value: ["#b5613e", "#1f1a16", "#f5f0e9"] },
  { name: "Marino",    value: ["#1f3a5f", "#15171b", "#f4f3ef"] },
  { name: "Bronce",    value: ["#8a6a3b", "#1a1813", "#f6f2ea"] },
];

// Tipografías para títulos. tracking se ajusta por familia para que cada una
// se vea bien sin tener que tunear el CSS a mano.
const DISPLAY_FONTS = [
  { value: "Instrument Sans",     label: "Instrument Sans",        tracking: "-0.035em" },
  { value: "Instrument Serif",    label: "Instrument Serif",       tracking: "-0.02em"  },
  { value: "Fraunces",            label: "Fraunces (serif)",       tracking: "-0.035em" },
  { value: "Playfair Display",    label: "Playfair (serif)",       tracking: "-0.025em" },
  { value: "DM Serif Display",    label: "DM Serif (display)",     tracking: "-0.02em"  },
  { value: "Bricolage Grotesque", label: "Bricolage (sans)",       tracking: "-0.035em" },
  { value: "Archivo",             label: "Archivo (sans)",         tracking: "-0.03em"  },
];

const WEIGHTS = [
  { value: 500, label: "Medio" },
  { value: 600, label: "Semi" },
  { value: 700, label: "Bold" },
  { value: 800, label: "Extra" },
];

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [lang, setLang] = React.useState(t.lang || 'es');
  const [modalService, setModalService] = React.useState(null);
  const [contactOpen, setContactOpen] = React.useState(false);
  const strings = window.STRINGS[lang] || window.STRINGS.es;

  // Aplicar variables CSS desde la paleta + tipografía
  React.useEffect(() => {
    const [accent, ink, bg] = t.palette;
    const root = document.documentElement;
    root.style.setProperty('--accent', accent);
    root.style.setProperty('--ink', ink);
    root.style.setProperty('--bg', bg);
    const font = DISPLAY_FONTS.find(f => f.value === t.displayFont) || DISPLAY_FONTS[0];
    root.style.setProperty('--display', `"${font.value}", Georgia, serif`);
    root.style.setProperty('--display-tracking', font.tracking);
    root.style.setProperty('--display-weight', String(t.displayWeight));
  }, [t.palette, t.displayFont, t.displayWeight]);

  // Sync lang con tweaks
  React.useEffect(() => { setTweak('lang', lang); /* persistir */ }, [lang]);

  // Parallax: ligero translateY al footer para acentuar contraste de movimiento.
  // Medimos el spacer (que SÍ scrollea con la página) — no el wrapper fixed,
  // cuyo rect es constante respecto al viewport.
  const footerRef = React.useRef(null);
  const spacerRef = React.useRef(null);
  React.useEffect(() => {
    const footerEl = footerRef.current;
    const spacerEl = spacerRef.current;
    if (!footerEl || !spacerEl) return;
    let raf = 0;
    const onScroll = () => {
      if (raf) return;
      raf = requestAnimationFrame(() => {
        raf = 0;
        // Atamos el desplazamiento al scroll RESTANTE hasta el fondo:
        //  · en el fondo del documento → offset 0 (footer revelado, SIN hueco)
        //  · al alejarte → crece hasta 80px (animación de subida al volver)
        const doc = document.documentElement;
        const maxScroll = Math.max(0, doc.scrollHeight - window.innerHeight);
        const remaining = maxScroll - window.scrollY;
        const offset = Math.max(0, Math.min(80, remaining));
        footerEl.style.setProperty('--footer-parallax', `${offset}px`);
      });
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll);
    onScroll();
    return () => {
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onScroll);
      if (raf) cancelAnimationFrame(raf);
    };
  }, []);

  // Sincroniza la altura del spacer con la altura REAL del footer, para que al
  // llegar al fondo el footer se revele completo sin dejar hueco blanco.
  React.useEffect(() => {
    const footerEl = footerRef.current;
    const spacerEl = spacerRef.current;
    if (!footerEl || !spacerEl) return;
    const sync = () => {
      const h = footerEl.querySelector('.footer');
      const fh = h ? h.offsetHeight : footerEl.offsetHeight;
      if (fh) spacerEl.style.height = fh + 'px';
    };
    sync();
    const ro = new ResizeObserver(sync);
    const inner = footerEl.querySelector('.footer') || footerEl;
    ro.observe(inner);
    window.addEventListener('resize', sync);
    window.addEventListener('load', sync);
    const tid = setTimeout(sync, 600);
    return () => {
      ro.disconnect();
      window.removeEventListener('resize', sync);
      window.removeEventListener('load', sync);
      clearTimeout(tid);
    };
  }, []);

  return (
    <>
      <Nav t={strings} lang={lang} setLang={setLang} />
      <div className="page-shell">
        {t.heroMode === 'frames'
          ? <HeroFrames t={strings} />
          : <Hero t={strings} lang={lang} mode={t.heroMode} />}
        <Featured t={strings} />
        <About t={strings} mode={t.aboutMode} />
        <SocialFeed t={strings} />
        <Services t={strings} onOpenContact={(_, s) => setModalService(s)} />
        <Blog t={strings} />
        <ContactHero t={strings} onContact={() => setContactOpen(true)} />
      </div>
      <div className="footer-reveal-space" ref={spacerRef} aria-hidden="true"></div>
      <div ref={footerRef} className="footer-parallax-wrap">
        <Footer t={strings} />
      </div>

      <a
        className="wa-float"
        href={strings.about.ctaUrl}
        target="_blank"
        rel="noopener noreferrer"
        aria-label="WhatsApp"
      >
        <svg width="30" height="30" viewBox="0 0 32 32" fill="none" aria-hidden="true">
          <path d="M16 3C8.8 3 3 8.8 3 16c0 2.3.6 4.5 1.7 6.4L3 29l6.8-1.8c1.8 1 3.9 1.5 6.2 1.5 7.2 0 13-5.8 13-13S23.2 3 16 3Z" fill="#fff"/>
          <path d="M12.3 9.4c-.3-.6-.5-.6-.8-.6h-.7c-.2 0-.6.1-.9.4-.3.3-1.2 1.2-1.2 2.9 0 1.7 1.2 3.3 1.4 3.6.2.2 2.4 3.8 6 5.2 3 1.2 3.6 1 4.2.9.6-.1 2-.8 2.3-1.6.3-.8.3-1.5.2-1.6-.1-.1-.3-.2-.6-.4-.3-.2-2-1-2.3-1.1-.3-.1-.5-.2-.8.2-.2.3-.9 1.1-1.1 1.3-.2.2-.4.3-.7.1-.3-.2-1.4-.5-2.7-1.7-1-.9-1.7-2-1.9-2.3-.2-.3 0-.5.1-.7.1-.1.3-.4.5-.6.2-.2.2-.3.3-.6.1-.2 0-.4 0-.6-.1-.2-.8-2-1.1-2.6Z" fill="#25d366"/>
        </svg>
      </a>
      <ContactModal
        open={!!modalService}
        onClose={() => setModalService(null)}
        service={modalService}
        t={strings}
      />
      <BasicContactModal
        open={contactOpen}
        onClose={() => setContactOpen(false)}
        t={strings}
      />

      <TweaksPanel title="Tweaks">
        <TweakSection label="Hero">
          <TweakSelect
            label="Efecto"
            value={t.heroMode}
            options={[
              { value: 'frames',  label: 'Video on scroll' },
              { value: 'classic', label: 'Parallax · Classic' },
              { value: 'zoom',    label: 'Parallax · Zoom' },
              { value: 'cinema',  label: 'Parallax · Cinema' },
            ]}
            onChange={(v) => setTweak('heroMode', v)}
          />
        </TweakSection>
        <TweakSection label="Sobre mí">
          <TweakRadio
            label="Estilo"
            value={t.aboutMode}
            options={[
              { value: 'editorial', label: 'Editorial' },
              { value: 'kinetic',   label: 'Movimiento' },
              { value: 'dossier',   label: 'Dossier' },
            ]}
            onChange={(v) => setTweak('aboutMode', v)}
          />
        </TweakSection>
        <TweakSection label="Paleta">
          <TweakColor
            label="Color"
            value={t.palette}
            options={PALETTES.map(p => p.value)}
            onChange={(v) => setTweak('palette', v)}
          />
        </TweakSection>
        <TweakSection label="Tipografía">
          <TweakSelect
            label="Familia"
            value={t.displayFont}
            options={DISPLAY_FONTS}
            onChange={(v) => setTweak('displayFont', v)}
          />
          <TweakSelect
            label="Peso"
            value={t.displayWeight}
            options={WEIGHTS.map(w => ({ value: w.value, label: w.label }))}
            onChange={(v) => setTweak('displayWeight', Number(v))}
          />
        </TweakSection>
        <TweakSection label="Idioma">
          <TweakRadio
            label="Lang"
            value={lang}
            options={[{ value: 'es', label: 'ES' }, { value: 'en', label: 'EN' }]}
            onChange={(v) => setLang(v)}
          />
        </TweakSection>
      </TweaksPanel>
    </>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
