/* global React, ReactDOM */
const { useState, useEffect, useRef } = React;

// ============================================================
// Hero copy variants — controllable via Tweaks
// ============================================================
const HERO_VARIANTS = {
  drift: {
    headline: ["We've been vibe coding all wrong."],
    sub: <>Sitting at our terminal, waiting for Claude to finish coding. Running, asking for a tweak, waiting.</>
  },
  lights: {
    headline: ["The factory runs", "in the dark.", <em key="e">We turned on the lights.</em>],
    sub: <>Code is being written faster than anyone can describe it. Product knowledge lives inside files no one reads. Saldor points at your repo, traces every flow, and emits a PRD — kept current by every PR that lands, so the dark factory has a paper trail again.</>
  },
  truth: {
    headline: ["The codebase is", "the spec.", <em key="e">Nobody can read it.</em>],
    sub: <>Vibe coding moved the source of truth into the source code. The doc your PM wrote at kickoff hasn't kept up. Saldor derives a living PRD from the repo — onboarding, audit, and decisions all reading from the same file the build runs on.</>
  }
};

// ============================================================
// Waitlist form
// ============================================================
function WaitlistForm() {
  const [status, setStatus] = useState("idle");

  async function handleSubmit(e) {
    e.preventDefault();
    setStatus("loading");
    const res = await fetch("https://formspree.io/f/mredlyyd", {
      method: "POST",
      body: new FormData(e.target),
      headers: { Accept: "application/json" },
    });
    setStatus(res.ok ? "done" : "error");
  }

  if (status === "done") {
    return <p className="waitlist-confirm">You're on the list. We'll be in touch.</p>;
  }

  return (
    <form className="waitlist-form" onSubmit={handleSubmit}>
      <input
        type="email"
        name="email"
        className="waitlist-input"
        placeholder="your@email.com"
        required
      />
      <button type="submit" className="btn btn-primary" disabled={status === "loading"}>
        {status === "loading" ? "Sending…" : "Request access →"}
      </button>
    </form>
  );
}

// ============================================================
// Top bar
// ============================================================
function TopBar() {
  return (
    <header className="topbar">
      <div className="topbar-inner">
        <a href="#top" className="brand">
          <span className="brand-mark">S</span>
          <span>Saldor</span>
        </a>
        <ul className="nav">
          <li><a href="#problem">Problem</a></li>
          <li><a href="#system">System</a></li>
          <li><a href="#roadmap">Roadmap</a></li>
          <li><a href="#contact">Contact</a></li>
        </ul>
      </div>
    </header>
  );
}

// ============================================================
// Hero
// ============================================================
function Hero({ variant }) {
  const v = HERO_VARIANTS[variant] || HERO_VARIANTS.drift;
  return (
    <section className="section hero" id="top" data-screen-label="01 Hero">
      <div className="content-col">
        <h1>
          {v.headline.map((part, i) =>
            <React.Fragment key={i}>{part}{i < v.headline.length - 1 ? " " : ""}</React.Fragment>
          )}
        </h1>
        <p className="hero-body">{v.sub}</p>

        <div className="kicker">Saldor is building the tools for a software dark factory.</div>

        <WaitlistForm />
      </div>
    </section>
  );
}

// ============================================================
// Problem section
// ============================================================
function Problem() {
  return (
    <section className="section" id="problem" data-screen-label="02 Problem">
      <div className="content-col">
        <div className="eyebrow"><span className="dash" />The first task</div>
        <h2>Maintain a live product spec</h2>
        <p className="lede" style={{ marginTop: 40 }}>{"The prompt you gave Claude 6 months ago to start the project is buried in code throughout the codebase. As are the refinements you made along the way, too.\n\nIf we are to let AI write and test software for us, we first need to be very clear about what we want. In order to do that, we need a high level document that we can review, collaborate on, and revise. Saldor's first product helps you do that."}</p>

        <p className="lede" style={{ marginTop: 32 }}>Here's what changes the day you have a live spec.</p>

        <div className="numbered">
          <div className="num-row">
            <div className="n">A</div>
            <div>
              <h3>Onboarding compresses from weeks to an afternoon.</h3>
              <p>New engineers don't need to spelunk through entire codebases anymore. But they do need to learn what the product does. With Saldor, they can read the PRD in their browser, and be productive on day 1.</p>
            </div>
          </div>

          <div className="num-row">
            <div className="n">B</div>
            <div>
              <h3>Decision makers are empowered.</h3>
              <p>
                Founders and PMs can audit the live product without booking time with engineers. When something
                looks wrong, they can hand the section to Claude Code and get a fix prompted in minutes.
              </p>
            </div>
          </div>

          <div className="num-row">
            <div className="n">C</div>
            <div>
              <h3>Unintended business logic surfaces for review.</h3>
              <p>
                The retry that fires on day 14. The archival that runs after downgrade. The discount that
                stacks with a partner code. Saldor flags the gap between what was built and what was specified.
              </p>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ============================================================
// PRD Preview — interactive mock
// ============================================================
function PrdPreview() {
  const [active, setActive] = useState("checkout");
  const [showDiff, setShowDiff] = useState(false);

  useEffect(() => {
    const t = setInterval(() => setShowDiff((s) => !s), 6500);
    return () => clearInterval(t);
  }, []);

  const sections = [
    { id: "auth", label: "Authentication" },
    { id: "billing", label: "Billing & plans" },
    { id: "checkout", label: "Checkout", updated: true },
    { id: "rate-limits", label: "Rate limits" },
    { id: "trials", label: "Trials & gating" },
    { id: "notifications", label: "Notifications" },
  ];

  return (
    <div className="prd-frame" role="region" aria-label="PRD preview">
      <div className="prd-tabs">
        <div className="prd-tab active">PRD.md</div>
        <div className="prd-tab-meta">
          <span className="dot" />
          Saldor agent is currently <span className="editing-pulse">&nbsp;editing</span>
        </div>
      </div>

      <aside className="prd-sidebar">
        <h4>Surfaces</h4>
        <ul>
          {sections.map((s) =>
            <li
              key={s.id}
              className={active === s.id ? "active" : ""}
              onClick={() => setActive(s.id)}>
              {s.label}
              {s.updated ? <span className="pill">PR #1247</span> : null}
            </li>
          )}
        </ul>
        <h4>Across surfaces</h4>
        <ul>
          <li>Permissions matrix</li>
          <li>Background jobs</li>
          <li>Feature flags <span className="pill">drift</span></li>
        </ul>
      </aside>

      <div className="prd-doc">
        <div className="doc-meta">
          <span>§ 03.04 — CHECKOUT</span>
          <span>Derived from: src/checkout/*, src/billing/stripe.ts</span>
          <span>Confidence: high</span>
        </div>
        <h5>Checkout — trial-to-paid conversion</h5>

        <p>
          When a user reaches day 14 of a Pro trial, a modal blocks the dashboard until they enter a payment
          method or downgrade. The modal cannot be dismissed; closing the tab and returning shows it again.
        </p>

        <div className={`updated ${showDiff ? "is-on" : ""}`}>
          <p style={{ margin: 0 }}>
            On day 14, users who created their account from a partner referral link skip the modal and are
            auto-converted to <ins>monthly Pro</ins> <del>annual Pro</del> with a 7-day refund window.
          </p>
        </div>

        <p>
          Users who downgrade during the modal flow are returned to Free <em>and</em> have their workspace
          archived after 24 hours of inactivity — including workspaces created during the trial. This was
          introduced in PR #1198 alongside the storage-cost work; no spec discussed it.
        </p>

        <p style={{ color: "var(--muted-2)", fontSize: 12.5, marginTop: 20 }}>
          ↳ Open in editor · Suggest revision · Generate PR (preview)
        </p>
      </div>
    </div>
  );
}

// ============================================================
// System section
// ============================================================
function System() {
  return (
    <section className="section" id="system" data-screen-label="03 System">
      <div className="content-col">
        <div className="eyebrow"><span className="dash" />Our solution</div>
        <h2>Connect Saldor to your repo. The PRD maintains itself.</h2>
        <p className="lede">Saldor reads every file, traces every flow, and emits a structured product document organized by surface. It does this once on connect, and again on every PR — so the doc you read today reflects the code that's deployed today.</p>

        <PrdPreview />
        <LogStream />
      </div>
    </section>
  );
}

// ============================================================
// PR feed — each row links to its PRD diff
// ============================================================
function LogStream() {
  const rows = [
    { num: "#1247", title: "checkout: skip modal for partner referrals", who: "kira", when: "2m", scope: "§ Checkout · 2 behavior changes" },
    { num: "#1246", title: "auth: drop magic link for SSO tenants", who: "jess", when: "13m", scope: "§ Authentication · 1 surface removed" },
    { num: "#1245", title: "billing: switch monthly to anchored renewals", who: "nico", when: "44m", scope: "§ Billing · pricing examples updated" },
    { num: "#1244", title: "notifications: digest opt-out for free plan", who: "tomas", when: "1h", scope: "§ Notifications · gating rule added" },
    { num: "#1243", title: "rate-limits: raise /search from 60 to 90 rpm", who: "kira", when: "2h", scope: "§ Rate limits · numeric change" },
  ];

  return (
    <div className="pr-feed" aria-label="Recent PRs and PRD diffs">
      <div className="pr-feed-head">
        <span>Recent PRs</span>
        <span className="pr-feed-hint">click a row to review the PRD diff →</span>
      </div>
      <ul className="pr-rows">
        {rows.map((r, i) =>
          <li key={i}>
            <a className="pr-row" href="#" onClick={(e) => e.preventDefault()}>
              <span className="pr-num">{r.num}</span>
              <span className="pr-title">{r.title}</span>
              <span className="pr-scope">{r.scope}</span>
              <span className="pr-meta">@{r.who} · {r.when}</span>
              <span className="pr-cta">review diff →</span>
            </a>
          </li>
        )}
      </ul>
    </div>
  );
}

// ============================================================
// Roadmap
// ============================================================
function Roadmap() {
  return (
    <section className="section" id="roadmap" data-screen-label="05 Roadmap">
      <div className="content-col">
        <div className="eyebrow"><span className="dash" />Roadmap</div>
        <h2>What comes next?</h2>
        <p className="lede">While valuable, a live product spec is just the first step. The product spec as the primary development interface is the goal — change the spec, and the code changes underneath. One hurdle to this is obviously trust. We're working on the testing layer to make it trustworthy.</p>
      </div>
    </section>
  );
}

// ============================================================
// Contact
// ============================================================
function Contact() {
  return (
    <section className="section" id="contact" data-screen-label="06 Contact">
      <div className="content-col">
        <div className="eyebrow"><span className="dash" />Talk to us</div>
        <h2>We'd like to help you.</h2>
        <p className="lede">We're working with a small group of teams in closed alpha. If your team ships with Claude, Cursor, or any of the rest of them, and you're shipping code faster than your team can keep up, let us help.</p>

        <WaitlistForm />
      </div>
    </section>
  );
}

// ============================================================
// Footer
// ============================================================
function Footer() {
  return (
    <footer>
      <span>Saldor · 2026</span>
      <span className="yc"><span className="y-mark">Y</span>Backed by Y Combinator</span>
      <span className="right"><a href="mailto:hello@saldor.com">HI@SALDOR.COM</a></span>
    </footer>
  );
}

// ============================================================
// Root app — Tweaks
// ============================================================
function App() {
  const [t, setTweak] = useTweaks(/*EDITMODE-BEGIN*/{
    "headline": "drift",
    "accent": "#D9591F",
    "bgTone": "cream",
    "dense": false
  }/*EDITMODE-END*/);

  useEffect(() => {
    document.documentElement.style.setProperty("--accent", t.accent);
    const bg = {
      cream: ["#EFECE3", "#E6E2D6"],
      paper: ["#F5F3EC", "#ECE9DF"],
      slate: ["#1A1F26", "#222933"]
    }[t.bgTone] || ["#EFECE3", "#E6E2D6"];
    document.documentElement.style.setProperty("--bg", bg[0]);
    document.documentElement.style.setProperty("--bg-2", bg[1]);
    if (t.bgTone === "slate") {
      document.documentElement.style.setProperty("--ink", "#E8E6DF");
      document.documentElement.style.setProperty("--ink-2", "#C7C4BB");
      document.documentElement.style.setProperty("--muted", "#7B8088");
      document.documentElement.style.setProperty("--muted-2", "#9CA1A8");
      document.documentElement.style.setProperty("--rule", "rgba(232, 230, 223, 0.14)");
      document.documentElement.style.setProperty("--rule-strong", "rgba(232, 230, 223, 0.28)");
    } else {
      document.documentElement.style.setProperty("--ink", "#0E1F2E");
      document.documentElement.style.setProperty("--ink-2", "#1A2E3F");
      document.documentElement.style.setProperty("--muted", "#8A9097");
      document.documentElement.style.setProperty("--muted-2", "#6A7079");
      document.documentElement.style.setProperty("--rule", "rgba(14, 31, 46, 0.12)");
      document.documentElement.style.setProperty("--rule-strong", "rgba(14, 31, 46, 0.28)");
    }
    document.documentElement.style.setProperty("--pad", t.dense ? "44px" : "56px");
  }, [t]);

  return (
    <>
      <TopBar />
      <main>
        <Hero variant={t.headline} />
        <Problem />
        <System />
        <Roadmap />
        <Contact />
      </main>
      <Footer />

      <TweaksPanel title="Tweaks">
        <TweakSection label="Hero copy">
          <TweakSelect
            label="Headline variant"
            value={t.headline}
            options={[
              { value: "drift", label: "Drift — apps drift from spec" },
              { value: "lights", label: "Lights — factory in the dark" },
              { value: "truth", label: "Truth — codebase is the spec" },
            ]}
            onChange={(v) => setTweak("headline", v)} />
        </TweakSection>

        <TweakSection label="Palette">
          <TweakColor
            label="Accent"
            value={t.accent}
            options={["#D9591F", "#1F6FD9", "#2E7D55", "#7A4FD9", "#0E1F2E"]}
            onChange={(v) => setTweak("accent", v)} />

          <TweakRadio
            label="Background tone"
            value={t.bgTone}
            options={[
              { value: "cream", label: "Cream" },
              { value: "paper", label: "Paper" },
              { value: "slate", label: "Slate" },
            ]}
            onChange={(v) => setTweak("bgTone", v)} />
        </TweakSection>

        <TweakSection label="Density">
          <TweakToggle
            label="Tighten layout"
            value={t.dense}
            onChange={(v) => setTweak("dense", v)} />
        </TweakSection>
      </TweaksPanel>
    </>
  );
}

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
