// app.jsx — Desk Genie early-bird landing
// Sections: nav, hero (with email capture + buddy), live status demo, how it works, footer.

const { useState, useEffect, useRef, useCallback } = React;
const STATES = window.BUDDY_STATES;
const PADS = window.BUDDY_PADS;
const PRESETS = window.STATE_PRESETS;

// ─────────────────────────────────────────────────────────────────────────────
// Tiny utility: monospace marquee of coordinates / clock — pure ornament.
function MonoMeta({ accent }) {
  const [t, setT] = useState(() => new Date());
  useEffect(() => {
    const id = setInterval(() => setT(new Date()), 1000);
    return () => clearInterval(id);
  }, []);
  const pad = (n) => String(n).padStart(2, '0');
  const time = `${pad(t.getUTCHours())}:${pad(t.getUTCMinutes())}:${pad(t.getUTCSeconds())} UTC`;
  return (
    <div className="mono-meta">
      <span>[ DG-001 / EARLY_BIRD_OPEN ]</span>
      <span className="dot" style={{ background: accent }} />
      <span>{time}</span>
      <span className="dot" />
      <span>BATCH 0001 · 488 / 1000 LEFT</span>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
function Nav({ accent }) {
  return (
    <nav className="nav">
      <div className="nav-inner">
        <a href="#" className="brand">
          <span className="brand-mark" style={{ background: accent }} />
          <span className="brand-name">desk genie</span>
          <span className="brand-tag">/ status_buddy</span>
        </a>
        <div className="nav-links">
          <a href="#media">demo_video</a>
          <a href="#demo">live_demo</a>
          <a href="#how">how_it_works</a>
          <a href="#signup">early_bird</a>
        </div>
        <a href="#signup" className="nav-cta">
          [ reserve · 20% off ]
        </a>
      </div>
    </nav>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
function EmailCapture({ accent, variant = 'hero' }) {
  const [email, setEmail] = useState('');
  const [status, setStatus] = useState('idle'); // idle | error | submitting | done
  const [error, setError] = useState('');
  const ref = useRef(null);

  const SCRIPT_URL = 'https://script.google.com/macros/s/AKfycbw8zdUbe-8tcrrysJ4hfCC-_nn2mrIZAWZTh7z49PfgBVM1lOXoeJ8CoLIkdzhZBkRqkA/exec';

  function validate(v) {
    return /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(v.trim());
  }

  async function submit(e) {
    e.preventDefault();
    if (!validate(email)) {
      setStatus('error');
      setError('that email looks off. mind another go?');
      return;
    }
    setStatus('submitting');
    setError('');
    try {
      await fetch(SCRIPT_URL, {
        method: 'POST',
        mode: 'no-cors',
        body: new URLSearchParams({ email }),
      });
      setStatus('done');
    } catch {
      setStatus('error');
      setError('something went wrong. please try again.');
    }
  }

  if (status === 'done') {
    return (
      <div className={`capture capture-${variant} capture-done`}>
        <div className="capture-done-row">
          <span className="check" style={{ background: accent }}>✓</span>
          <div>
            <div className="capture-done-title">you're on the list.</div>
            <div className="capture-done-sub">spot reserved for <b>{email}</b> · batch 0001 · ships fall 2026</div>
          </div>
        </div>
        <div className="capture-perks">
          <span>[ -20% launch price ]</span>
          <span>[ +1 free pet ]</span>
          <span>[ early shipping wave ]</span>
        </div>
      </div>
    );
  }

  return (
    <form className={`capture capture-${variant} ${status === 'error' ? 'has-error' : ''}`} onSubmit={submit} noValidate>
      <div className="capture-row">
        <label className="capture-label" htmlFor={`email-${variant}`}>
          <span className="bracket">[</span> EMAIL <span className="bracket">]</span>
        </label>
        <input
          id={`email-${variant}`}
          ref={ref}
          type="email"
          inputMode="email"
          autoComplete="email"
          placeholder="you@studio.com"
          value={email}
          onChange={(e) => { setEmail(e.target.value); if (status === 'error') setStatus('idle'); }}
          spellCheck={false}
        />
        <button type="submit" className="capture-btn" style={{ background: accent }} disabled={status === 'submitting'}>
          {status === 'submitting' ? (
            <span className="btn-loading">
              <span className="btn-dot" /><span className="btn-dot" /><span className="btn-dot" />
            </span>
          ) : (
            <>reserve →</>
          )}
        </button>
      </div>
      {status === 'error' && (
        <div className="capture-error">! {error}</div>
      )}
    </form>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
function Hero({ padId, setPadId, accent }) {
  const Buddy = window.Buddy;
  // Gentle ambient state cycle for hero buddy — different than the demo cycle.
  const [heroState, setHeroState] = useState('thinking');
  useEffect(() => {
    const order = ['thinking', 'done', 'waiting'];
    let i = 0;
    const id = setInterval(() => {
      i = (i + 1) % order.length;
      setHeroState(order[i]);
    }, 3200);
    return () => clearInterval(id);
  }, []);

  return (
    <section className="hero" data-screen-label="01 Hero">
      <div className="hero-grid">
        <div className="hero-copy">
          <div className="eyebrow">
            <span className="eyebrow-dot" style={{ background: accent }} />
            <span>NOW BOARDING · BATCH 0001 · EARLY_BIRD</span>
          </div>
          <h1 className="hero-title">
            a tiny desk pet<br />
            that <span className="hero-em" style={{ color: accent }}>shows you</span><br />
            what your AI is doing.
          </h1>
          <p className="hero-sub">
            desk genie sits on your desk and glows, blinks, and jumps as your AI
            agent thinks, finishes a task, or needs your input. swap its pad to
            change the look in one click.
          </p>

          <div id="signup" className="hero-cta">
            <EmailCapture accent={accent} variant="hero" />
          </div>

          <div className="hero-perks">
            <div className="perks-head">
              <span>[ SIGN UP &amp; UNLOCK THESE PERKS ]</span>
              <span className="perks-hr" />
            </div>
            <div className="hero-strip">
              <div className="strip-item">
                <div className="strip-num">20%</div>
                <div className="strip-cap">off launch price</div>
              </div>
              <div className="strip-divider" />
              <div className="strip-item">
                <div className="strip-num">+1</div>
                <div className="strip-cap">free swap-pet</div>
              </div>
              <div className="strip-divider" />
              <div className="strip-item">
                <div className="strip-num">488</div>
                <div className="strip-cap">of 1000 left</div>
              </div>
            </div>
          </div>
        </div>

        <div className="hero-visual">
          <div className="hero-stage">
            <div className="stage-corner stage-tl">+</div>
            <div className="stage-corner stage-tr">+</div>
            <div className="stage-corner stage-bl">+</div>
            <div className="stage-corner stage-br">+</div>
            <div className="stage-meta-tl">DG-001 · {heroState.toUpperCase()}</div>
            <div className="stage-meta-tr">62 × 62 × 92 mm</div>
            <div className="stage-meta-br">PAD: {padId.toUpperCase()}</div>

            <Buddy state={heroState} padId={padId} size={360} accent={accent} />

            <div className="stage-pads">
              <div className="pads-label">[ SWAP_PAD ]</div>
              <div className="pads-row">
                {PADS.map((p) => (
                  <button
                    key={p.id}
                    type="button"
                    className={`pad-chip ${padId === p.id ? 'pad-active' : ''}`}
                    onClick={() => setPadId(p.id)}
                    aria-label={`Swap to ${p.name} pad`}
                  >
                    <span className="pad-dot" style={{ background: p.fill, borderColor: p.stroke }} />
                    <span className="pad-name">{p.name}</span>
                  </button>
                ))}
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// Media — edit the paths below to add your files.
// Paths are relative to index.html (e.g. 'media/demo.mp4').
// Leave a value as null to show a placeholder until you have the file ready.
const MEDIA = {
  video:           null,  // 'media/demo.mp4'
  productFront:    null,  // 'media/product-front.jpg'
  productPads:     null,  // 'media/product-pads.jpg'
  lifestyleDesk:   null,  // 'media/desk.jpg'
  lifestyleHand:   null,  // 'media/hand.jpg'
  lifestyleDetail: null,  // 'media/detail.jpg'
};

function Slot({ src, label, className }) {
  return (
    <div className={`media-slot ${className || ''}`}>
      {src
        ? <img src={src} alt={label} />
        : <div className="media-slot-label">{label}</div>
      }
    </div>
  );
}

function VideoSlot({ src }) {
  return (
    <div className="media-slot video-area">
      {src
        ? <video src={src} autoPlay muted loop playsInline />
        : <div className="media-slot-label">demo_video · .mp4 / .webm / .mov</div>
      }
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
function MediaShowcase({ accent }) {
  return (
    <section className="media" id="media" data-screen-label="02 Media">
      <div className="section-head">
        <div className="section-eyebrow">
          <span>02 / SEE_IT_LIVE</span>
          <span className="hr" />
        </div>
        <h2 className="section-title">
          watch it <span style={{ color: accent }}>actually do the thing.</span>
        </h2>
        <p className="section-sub">
          a 30-second loop of desk genie reacting to claude finishing a task,
          and a few studio shots of the device + pads.
        </p>
      </div>

      <div className="media-grid">
        <VideoSlot src={MEDIA.video} />

        <div className="media-photos">
          <div className="photo-frame photo-portrait">
            <Slot src={MEDIA.productFront} label="Product · front 3/4" />
          </div>
          <div className="photo-frame photo-portrait">
            <Slot src={MEDIA.productPads} label="Pad lineup · top-down" />
          </div>
        </div>
      </div>

      <div className="media-strip">
        <div className="photo-frame photo-landscape">
          <Slot src={MEDIA.lifestyleDesk} label="On-desk lifestyle" />
        </div>
        <div className="photo-frame photo-landscape">
          <Slot src={MEDIA.lifestyleHand} label="In-hand scale shot" />
        </div>
        <div className="photo-frame photo-landscape">
          <Slot src={MEDIA.lifestyleDetail} label="Detail · LED ring close-up" />
        </div>
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
function StatusDemo({ padId, cycleSpeed, accent }) {
  const Buddy = window.Buddy;
  const [active, setActive] = useState('thinking');
  const [auto, setAuto] = useState(true);
  const [jump, setJump] = useState(false);

  // Auto-cycle through all 5 states
  useEffect(() => {
    if (!auto) return;
    let i = STATES.indexOf(active);
    const id = setInterval(() => {
      i = (i + 1) % STATES.length;
      setActive(STATES[i]);
    }, cycleSpeed);
    return () => clearInterval(id);
  }, [auto, cycleSpeed]); // eslint-disable-line

  // On 'done', trigger a tiny jump
  useEffect(() => {
    if (active === 'done') {
      setJump(true);
      const id = setTimeout(() => setJump(false), 700);
      return () => clearTimeout(id);
    }
  }, [active]);

  const preset = PRESETS[active];

  return (
    <section className="demo" id="demo" data-screen-label="02 Live demo">
      <div className="section-head">
        <div className="section-eyebrow">
          <span>03 / LIVE_STATUS_DEMO</span>
          <span className="hr" />
        </div>
        <h2 className="section-title">
          five glances. <span style={{ color: accent }}>zero context-switches.</span>
        </h2>
        <p className="section-sub">
          desk genie speaks in light, motion and a face. you read its state
          without touching the keyboard.
        </p>
      </div>

      <div className="demo-grid">
        <div className="demo-stage">
          <div className="stage-corner stage-tl">+</div>
          <div className="stage-corner stage-tr">+</div>
          <div className="stage-corner stage-bl">+</div>
          <div className="stage-corner stage-br">+</div>

          <div className="demo-readout">
            <div className="readout-row">
              <span className="readout-key">STATE</span>
              <span className="readout-val" style={{ color: preset.accent }}>
                {preset.label}
              </span>
            </div>
            <div className="readout-row">
              <span className="readout-key">CODE</span>
              <span className="readout-val">{preset.code}</span>
            </div>
            <div className="readout-row">
              <span className="readout-key">MSG</span>
              <span className="readout-val">{preset.msg}</span>
            </div>
          </div>

          <Buddy state={active} padId={padId} size={300} jump={jump} accent={accent} />

          <div className="demo-controls">
            <button
              className={`auto-btn ${auto ? 'auto-on' : ''}`}
              onClick={() => setAuto((a) => !a)}
              type="button"
            >
              <span className="auto-led" style={{ background: auto ? preset.accent : 'transparent' }} />
              {auto ? 'AUTO_CYCLE · ON' : 'AUTO_CYCLE · OFF'}
            </button>
          </div>
        </div>

        <div className="demo-states">
          {STATES.map((s, i) => {
            const p = PRESETS[s];
            return (
              <button
                key={s}
                className={`state-card ${active === s ? 'state-active' : ''}`}
                onClick={() => { setAuto(false); setActive(s); }}
                type="button"
              >
                <div className="state-head">
                  <span className="state-num">{String(i + 1).padStart(2, '0')}</span>
                  <span className="state-led" style={{ background: p.accent }} />
                </div>
                <div className="state-label">{p.label}</div>
                <div className="state-msg">{p.msg}</div>
                <div className="state-foot">
                  <span>{p.code}</span>
                  <span className="state-arrow">→</span>
                </div>
              </button>
            );
          })}
        </div>
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
function HowItWorks({ accent }) {
  const steps = [
    {
      n: '01',
      title: 'plug it in.',
      body: 'usb-c into your laptop or any 5v adapter. desk genie wakes up and pairs in under 6 seconds.',
      meta: 'SETUP · ~6s',
    },
    {
      n: '02',
      title: 'connect your agent.',
      body: 'works with claude desktop, cursor, openai api, n8n, raycast, and a small open-source webhook for everything else.',
      meta: 'INTEGRATIONS · 12+',
    },
    {
      n: '03',
      title: 'glance, don\'t stare.',
      body: 'no more cmd-tabbing to check if it\'s done thinking. desk genie tells you across the room.',
      meta: 'CONTEXT_SWITCHES · −∞',
    },
  ];
  return (
    <section className="how" id="how" data-screen-label="03 How it works">
      <div className="section-head">
        <div className="section-eyebrow">
          <span>04 / HOW_IT_WORKS</span>
          <span className="hr" />
        </div>
        <h2 className="section-title">
          three steps. <span style={{ color: accent }}>one tiny friend.</span>
        </h2>
      </div>

      <div className="how-grid">
        {steps.map((s, i) => (
          <div key={s.n} className="step">
            <div className="step-top">
              <span className="step-num">{s.n}</span>
              <span className="step-meta">{s.meta}</span>
            </div>
            <div className="step-rule" />
            <div className="step-title">{s.title}</div>
            <div className="step-body">{s.body}</div>
            {i < steps.length - 1 ? <div className="step-arrow">→</div> : null}
          </div>
        ))}
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
function Footer({ accent }) {
  return (
    <footer className="footer">
      <div className="footer-grid">
        <div className="footer-brand">
          <div className="brand">
            <span className="brand-mark" style={{ background: accent }} />
            <span className="brand-name">desk genie</span>
          </div>
          <div className="footer-tag">a tiny pet for the agent era. designed in oakland, ca.</div>
        </div>
        <div className="footer-meta">
          <div>[ © 2026 GENIE LABS, INC. ]</div>
          <div>[ SHIPPING FALL 2026 · BATCH 0001 ]</div>
          <div>[ HELLO@DESKGENIE.CO ]</div>
        </div>
      </div>
    </footer>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
const SITE_DEFAULTS = {
  "accent": "#ff5c1a",
  "padId": "oat",
  "cycleSpeed": 2400
};

function App() {
  const [settings, setSettings] = useState(SITE_DEFAULTS);
  const setPadId = useCallback((padId) => {
    setSettings((prev) => ({ ...prev, padId }));
  }, []);

  // Keep the CSS accent in sync with the configured launch color.
  useEffect(() => {
    document.documentElement.style.setProperty('--accent', settings.accent);
  }, [settings.accent]);

  return (
    <div className="page">
      <Nav accent={settings.accent} />
      <Hero padId={settings.padId} setPadId={setPadId} accent={settings.accent} />
      <MediaShowcase accent={settings.accent} />
      <StatusDemo padId={settings.padId} cycleSpeed={settings.cycleSpeed} accent={settings.accent} />
      <HowItWorks accent={settings.accent} />
      <Footer accent={settings.accent} />
    </div>
  );
}

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