// bakely-app.jsx
// Main app composition + Tweaks panel for palette swap.

const { useRef: useRefApp, useState: useStateApp, useEffect: useEffectApp } = React;

/* ------------------------------------------------------------------ */
/*  Palette presets                                                    */
/* ------------------------------------------------------------------ */

const PALETTES = {
  'Coral & Teal': {
    coral: '#E76F51',
    coralDeep: '#C9573A',
    teal: '#2C5F5D',
    tealDeep: '#1F4543',
    peach: '#FBDDD0',
    peachSoft: '#FDEADD',
    cream: '#FBF3EA',
    espresso: '#3D2818',
    espressoSoft: '#6B5544',
    sparkle: '#F2A28A',
  },
  'Honey & Sage': {
    coral: '#D4A05A',
    coralDeep: '#A87A38',
    teal: '#5D7A5A',
    tealDeep: '#3F5C3D',
    peach: '#F2E3C8',
    peachSoft: '#FAF1DE',
    cream: '#FBF6EA',
    espresso: '#3A2A18',
    espressoSoft: '#6E5A40',
    sparkle: '#E2BC78',
  },
  'Berry & Pine': {
    coral: '#C2466E',
    coralDeep: '#9B2F55',
    teal: '#2F5141',
    tealDeep: '#1D3A2C',
    peach: '#F2D4DD',
    peachSoft: '#FAE6EA',
    cream: '#F8F0EC',
    espresso: '#3B1E2A',
    espressoSoft: '#6E4B5C',
    sparkle: '#E08AA5',
  },
};

function applyPalette(p) {
  const root = document.documentElement;
  root.style.setProperty('--coral', p.coral);
  root.style.setProperty('--coral-deep', p.coralDeep);
  root.style.setProperty('--teal', p.teal);
  root.style.setProperty('--teal-deep', p.tealDeep);
  root.style.setProperty('--peach', p.peach);
  root.style.setProperty('--peach-soft', p.peachSoft);
  root.style.setProperty('--cream', p.cream);
  root.style.setProperty('--espresso', p.espresso);
  root.style.setProperty('--espresso-soft', p.espressoSoft);
  root.style.setProperty('--sparkle', p.sparkle);
}

/* ------------------------------------------------------------------ */
/*  🎉 Easter egg: sprinkle celebration on successful signup           */
/* ------------------------------------------------------------------ */

function sprinkleCelebration() {
  if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
  const canvas = document.createElement('canvas');
  canvas.style.cssText = 'position:fixed;inset:0;width:100%;height:100%;pointer-events:none;z-index:9999;';
  document.body.appendChild(canvas);
  const ctx = canvas.getContext('2d');
  const dpr = Math.min(window.devicePixelRatio || 1, 2);
  const resize = () => { canvas.width = innerWidth * dpr; canvas.height = innerHeight * dpr; ctx.setTransform(dpr, 0, 0, dpr, 0, 0); };
  resize();

  const cs = getComputedStyle(document.documentElement);
  const palette = ['--coral', '--teal', '--sparkle', '--coral-deep']
    .map(v => cs.getPropertyValue(v).trim() || '#E76F51')
    .concat(['#F6C453', '#ffffff']);

  const N = 90;
  const sprinkles = Array.from({ length: N }, () => ({
    x: innerWidth * (0.3 + Math.random() * 0.4),
    y: innerHeight * 0.35 + (Math.random() - 0.5) * 80,
    vx: (Math.random() - 0.5) * 9,
    vy: -8 - Math.random() * 9,
    w: 4 + Math.random() * 4,
    h: 9 + Math.random() * 7,
    rot: Math.random() * Math.PI,
    vr: (Math.random() - 0.5) * 0.4,
    color: palette[(Math.random() * palette.length) | 0],
  }));

  let frame = 0;
  const g = 0.32;
  const tick = () => {
    frame++;
    ctx.clearRect(0, 0, innerWidth, innerHeight);
    let alive = false;
    for (const s of sprinkles) {
      s.vy += g; s.x += s.vx; s.y += s.vy; s.vx *= 0.99; s.rot += s.vr;
      if (s.y < innerHeight + 30) alive = true;
      ctx.save();
      ctx.translate(s.x, s.y);
      ctx.rotate(s.rot);
      ctx.globalAlpha = Math.max(0, 1 - frame / 150);
      ctx.fillStyle = s.color;
      ctx.beginPath();
      const r = s.w / 2;
      ctx.roundRect ? ctx.roundRect(-s.w / 2, -s.h / 2, s.w, s.h, r) : ctx.rect(-s.w / 2, -s.h / 2, s.w, s.h);
      ctx.fill();
      ctx.restore();
    }
    if (alive && frame < 150) requestAnimationFrame(tick);
    else canvas.remove();
  };
  requestAnimationFrame(tick);
}

/* ------------------------------------------------------------------ */
/*  Default tweaks                                                     */
/* ------------------------------------------------------------------ */

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": "Coral & Teal"
}/*EDITMODE-END*/;

/* ------------------------------------------------------------------ */
/*  App                                                                */
/* ------------------------------------------------------------------ */

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  // form state (shared between hero and CTA forms)
  const [email, setEmail] = useStateApp('');
  const [name, setName] = useStateApp('');
  const [submitted, setSubmitted] = useStateApp(false);
  const [error, setError] = useStateApp(null);
  const [extra, setExtra] = useStateApp({ orders: '', pain: '', channels: [], phone: '' });
  const [activeSection, setActiveSection] = useStateApp('top');

  const ctaRef = useRefApp(null);

  // highlight active section in nav as the user scrolls
  useEffectApp(() => {
    const ids = ['diagram', 'features', 'about', 'contact'];
    const obs = new IntersectionObserver((entries) => {
      entries.forEach((en) => {
        if (en.isIntersecting) setActiveSection(en.target.id);
      });
    }, { rootMargin: '-45% 0px -45% 0px', threshold: 0 });
    ids.forEach((id) => {
      const el = document.getElementById(id);
      if (el) obs.observe(el);
    });
    return () => obs.disconnect();
  }, []);

  // apply palette
  useEffectApp(() => {
    const p = PALETTES[t.palette] || PALETTES['Coral & Teal'];
    applyPalette(p);
  }, [t.palette]);

  const onSubmitEmail = () => {
    setError(null);
    const ok = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
    if (!ok) {
      setError('Please pop in a valid email so we can find you.');
      return;
    }
    // simulated submit
    setSubmitted(true);
    sprinkleCelebration();
  };

  const scrollToWaitlist = () => {
    document.getElementById('contact')?.scrollIntoView({ behavior: 'smooth', block: 'start' });
  };

  // palette swatches for the tweak control
  const paletteOptions = Object.entries(PALETTES).map(([label, p]) => ({
    label,
    swatch: [p.coral, p.teal, p.peach, p.cream],
  }));

  return (
    <React.Fragment>
      <Nav onWaitlistClick={scrollToWaitlist} active={activeSection} />

      <Hero
        onSubmitEmail={onSubmitEmail}
        submitted={submitted}
        email={email} setEmail={setEmail}
        name={name} setName={setName}
        error={error}
        extra={extra} setExtra={setExtra}
      />
      <ScallopDivider from="var(--cream)" to="var(--peach-soft)" />

      <BeforeAfter />
      <ScallopDivider from="var(--peach-soft)" to="var(--cream)" />

      <Features />

      <FreePlan onCtaClick={scrollToWaitlist} />
      <ScallopDivider from="var(--cream)" to="var(--teal)" />

      <About />
      <ScallopDivider from="var(--teal)" to="var(--peach)" />

      <WaitlistCTA
        onSubmitEmail={onSubmitEmail}
        submitted={submitted}
        email={email} setEmail={setEmail}
        name={name} setName={setName}
        error={error}
        extra={extra} setExtra={setExtra}
        formRef={ctaRef}
      />

      <Footer />

      <TweaksPanel>
        <TweakSection label="Palette" />
        <PaletteSwatchPicker
          value={t.palette}
          options={paletteOptions}
          onChange={(label) => setTweak('palette', label)}
        />
        <div style={{
          marginTop: 10,
          fontSize: 11,
          lineHeight: 1.5,
          opacity: 0.65,
        }}>
          Three baked-goods palettes. Coral & Teal is the kitchen-friend default. Honey & Sage leans rustic & breadlike. Berry & Pine for moodier patisserie energy.
        </div>
      </TweaksPanel>
    </React.Fragment>
  );
}

/* ------------------------------------------------------------------ */
/*  Custom palette swatch picker (cleaner than four-color TweakColor)  */
/* ------------------------------------------------------------------ */

function PaletteSwatchPicker({ value, options, onChange }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
      {options.map((opt) => {
        const selected = opt.label === value;
        return (
          <button
            key={opt.label}
            onClick={() => onChange(opt.label)}
            style={{
              display: 'flex',
              alignItems: 'center',
              gap: 12,
              padding: '8px 10px',
              borderRadius: 10,
              border: selected ? '2px solid #fff' : '2px solid transparent',
              background: selected ? 'rgba(255,255,255,0.08)' : 'transparent',
              cursor: 'pointer',
              color: 'inherit',
              fontFamily: 'inherit',
              fontSize: 13,
              fontWeight: 500,
              textAlign: 'left',
              transition: 'background 0.12s, border-color 0.12s',
            }}
          >
            <div style={{ display: 'flex', borderRadius: 999, overflow: 'hidden', boxShadow: '0 0 0 1px rgba(255,255,255,0.15)' }}>
              {opt.swatch.map((c, i) => (
                <div key={i} style={{ width: 18, height: 18, background: c }} />
              ))}
            </div>
            <span>{opt.label}</span>
            {selected && <span style={{ marginLeft: 'auto', opacity: 0.7 }}>✓</span>}
          </button>
        );
      })}
    </div>
  );
}

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

/* 🎂 Easter egg: a friendly hello for the curious in the console */
(function () {
  const big = 'font-family:Georgia,serif;font-size:22px;font-weight:700;color:#E76F51;';
  const small = 'font-family:system-ui,sans-serif;font-size:13px;color:#6B5544;';
  console.log('%c🎂 Smells good in here.', big);
  console.log('%cYou found the kitchen. We bake software for SA bakers.\nLike building warm, useful things? Say hi → hello@bakely.co.za', small);
})();
