// app.jsx — Grupo Térreo brand manual main app.
// Composes sections, sticky navigation, scroll-spy, and Tweaks panel.

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "fontMain": "Montserrat",
  "palette": ["#2D4A3E","#C8B89A","#FFFFFF","#6B7B8D","#1A1F1C"],
  "metaDensity": "media",
  "logoRoute": "sillar"
}/*EDITMODE-END*/;

const FONT_OPTIONS = [
  { id: "Montserrat",         label: "Montserrat",          stack: "'Montserrat', system-ui, sans-serif" },
  { id: "Manrope",            label: "Manrope",             stack: "'Manrope', system-ui, sans-serif" },
  { id: "Plus Jakarta Sans",  label: "Plus Jakarta Sans",   stack: "'Plus Jakarta Sans', system-ui, sans-serif" },
  { id: "Outfit",             label: "Outfit",              stack: "'Outfit', system-ui, sans-serif" },
];

const PALETTE_OPTIONS = [
  // [verde, arena, piedra, gris, carbon] · label
  { name: "Blanco",   value: ["#2D4A3E","#C8B89A","#FFFFFF","#6B7B8D","#1A1F1C"] },
  { name: "Bosque",   value: ["#2D4A3E","#C8B89A","#F2F2EF","#6B7B8D","#1A1F1C"] },
  { name: "Oliva",    value: ["#4A5D3A","#D4C4A4","#F3F3F0","#7A8174","#25281F"] },
  { name: "Salvia",   value: ["#5D7461","#DFD8C8","#F4F4F2","#8A9098","#1D2120"] },
  { name: "Arcilla",  value: ["#3A5045","#D8C2A0","#F2F1EE","#7A6F60","#1E1A14"] },
];

const NAV_ITEMS = [
  { id: "cover",     num: "00", label: "Portada" },
  { id: "concepto",  num: "01", label: "Concepto" },
  { id: "logotipo",  num: "02", label: "Logotipo" },
  { id: "paleta",    num: "03", label: "Paleta cromática" },
  { id: "tipografia",num: "04", label: "Tipografía" },
  { id: "editorial", num: "05", label: "Sistema editorial" },
  { id: "papeleria", num: "06", label: "Papelería" },
  { id: "web",       num: "07", label: "Web corporativa" },
  { id: "voz",       num: "08", label: "Tono y claim" },
];

function useScrollSpy(ids) {
  const [active, setActive] = useState(ids[0]);
  useEffect(() => {
    const observer = new IntersectionObserver(
      (entries) => {
        // Choose the entry closest to top among intersecting ones
        const visible = entries.filter(e => e.isIntersecting);
        if (visible.length) {
          visible.sort((a,b) => a.boundingClientRect.top - b.boundingClientRect.top);
          setActive(visible[0].target.id);
        }
      },
      { rootMargin: "-20% 0px -70% 0px", threshold: 0 }
    );
    ids.forEach(id => {
      const el = document.getElementById(id);
      if (el) observer.observe(el);
    });
    return () => observer.disconnect();
  }, [ids.join(",")]);
  return active;
}

function SideNav({ active, route }) {
  return (
    <aside className="sidenav">
      <div className="sidenav__brand">
        <LogoMark route={route} size={40} color="var(--verde)" />
        <div className="name">TÉRREO<span>GRUPO</span></div>
      </div>

      <div className="sidenav__label">Manual · v1.0 · 2026</div>
      <nav className="sidenav__list">
        {NAV_ITEMS.map((it) => (
          <a key={it.id} href={"#" + it.id} className={active === it.id ? "is-active" : ""}>
            <span className="num">{it.num}</span>
            <span>{it.label}</span>
          </a>
        ))}
      </nav>

      <div className="sidenav__foot">
        Promotora Inmobiliaria
      </div>
    </aside>
  );
}

function applyPalette(palette) {
  // palette: [verde, arena, piedra, gris, carbon]
  const [verde, arena, piedra, gris, carbon] = palette;
  const root = document.documentElement.style;
  root.setProperty("--verde",  verde);
  root.setProperty("--arena",  arena);
  root.setProperty("--piedra", piedra);
  root.setProperty("--gris",   gris);
  root.setProperty("--carbon", carbon);
  // Piedra-2 is a slightly lighter version of piedra
  root.setProperty("--piedra-2", lighten(piedra, 0.82));
  root.setProperty("--linea",      hexToRgba(verde, 0.18));
  root.setProperty("--linea-soft", hexToRgba(verde, 0.10));
}

function applyFont(fontId) {
  const opt = FONT_OPTIONS.find(f => f.id === fontId) || FONT_OPTIONS[0];
  document.documentElement.style.setProperty("--f-main", opt.stack);
}

// helpers
function hexToRgba(hex, a) {
  const m = hex.replace("#","");
  const bigint = parseInt(m.length === 3 ? m.split("").map(c => c+c).join("") : m, 16);
  const r = (bigint >> 16) & 255, g = (bigint >> 8) & 255, b = bigint & 255;
  return `rgba(${r},${g},${b},${a})`;
}
function lighten(hex, amt) {
  // mix hex with white by `amt` (0..1)
  const m = hex.replace("#","");
  const bigint = parseInt(m.length === 3 ? m.split("").map(c => c+c).join("") : m, 16);
  let r = (bigint >> 16) & 255, g = (bigint >> 8) & 255, b = bigint & 255;
  r = Math.round(r + (255 - r) * amt);
  g = Math.round(g + (255 - g) * amt);
  b = Math.round(b + (255 - b) * amt);
  return `rgb(${r},${g},${b})`;
}

function paletteEquals(a, b) {
  return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((v, i) => v === b[i]);
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const active = useScrollSpy(NAV_ITEMS.map(n => n.id));

  // Apply CSS variables whenever palette/font change
  useEffect(() => { applyPalette(t.palette); }, [t.palette]);
  useEffect(() => { applyFont(t.fontMain); }, [t.fontMain]);

  const fontStack = (FONT_OPTIONS.find(f => f.id === t.fontMain) || FONT_OPTIONS[0]).stack;

  return (
    <div className="shell">
      <SideNav active={active} route={t.logoRoute} />

      <main>
        <div id="cover" data-screen-label="00 Cover"><Hero route={t.logoRoute} /></div>
        <ConceptSection density={t.metaDensity} route={t.logoRoute} />
        <LogoSection route={t.logoRoute} setRoute={(v) => setTweak("logoRoute", v)} />
        <PaletteSection palette={{
          verde:  t.palette[0],
          arena:  t.palette[1],
          piedra: t.palette[2],
          gris:   t.palette[3],
          carbon: t.palette[4],
        }} />
        <TypeSection fontMain={fontStack} />
        <EditorialSection density={t.metaDensity} route={t.logoRoute} />
        <StationerySection route={t.logoRoute} />
        <WebSection density={t.metaDensity} route={t.logoRoute} />
        <VoiceSection />
        <Footer />
      </main>

      <TweaksPanel title="Tweaks">
        <TweakSection label="Ruta de marca" />
        <TweakRadio
          label="Logotipo"
          value={t.logoRoute}
          options={LOGO_ROUTES.map(r => r.id)}
          onChange={(v) => setTweak("logoRoute", v)}
        />
        <div style={{ fontFamily: "var(--f-mono)", fontSize: 9.5, color: "rgba(41,38,27,.5)", letterSpacing: 1.5, marginTop: -4 }}>
          {(LOGO_ROUTES.find(r => r.id === t.logoRoute) || {}).label || ""}
        </div>

        <TweakSection label="Paleta cromática" />
        <TweakColor
          label="Paleta"
          value={t.palette}
          options={PALETTE_OPTIONS.map(p => p.value)}
          onChange={(v) => setTweak("palette", v)}
        />
        <div style={{ fontFamily: "var(--f-mono)", fontSize: 9.5, color: "rgba(41,38,27,.5)", letterSpacing: 1.5, marginTop: -4 }}>
          {(PALETTE_OPTIONS.find(p => paletteEquals(p.value, t.palette)) || {}).name || "Personalizada"}
        </div>

        <TweakSection label="Tipografía" />
        <TweakSelect
          label="Principal"
          value={t.fontMain}
          options={FONT_OPTIONS.map(f => f.id)}
          onChange={(v) => setTweak("fontMain", v)}
        />

        <TweakSection label="Sistema editorial" />
        <TweakRadio
          label="Densidad sistema editorial"
          value={t.metaDensity}
          options={["minima","media","rica"]}
          onChange={(v) => setTweak("metaDensity", v)}
        />
      </TweaksPanel>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("app")).render(<App />);
