import type { ReactNode } from 'react';
import { Link } from 'react-router-dom';
import { ArrowUpRight } from 'lucide-react';

import {
  helloWorldCitations,
  optimalPlay,
  poolComparison,
  reproduce,
  trainingResult,
  wordList,
} from '@/content/evidence';
import { REPO_URL, routes } from '@/content/lineup';
import { PROPOSAL_NOTICE } from '@/content/verticals';
import { pageTitle, useSeo } from '@/lib/seo';
import * as s from '@/content/styles';

/** External link with the new-tab affordance and the announcement to match. */
function Out({ children, href }: { children: ReactNode; href: string }) {
  return (
    <a className={s.link} href={href} rel="noreferrer noopener" target="_blank">
      {children}
      <ArrowUpRight aria-hidden="true" className="ml-0.5 inline size-3.5 align-[-0.1em]" />
      <span className="sr-only"> (opens in a new tab)</span>
    </a>
  );
}

function Heading({ children, id }: { children: ReactNode; id: string }) {
  return (
    <h2 className={`${s.h2} scroll-mt-[calc(var(--app-header-h)+1rem)]`} id={id}>
      {children}
    </h2>
  );
}

const CONTENTS: readonly { id: string; label: string }[] = [
  { id: 'measured', label: 'What we measured ourselves' },
  { id: 'cited', label: 'What we cite from elsewhere' },
  { id: 'recorded', label: 'The rollouts are recorded' },
  { id: 'editor', label: 'The reward editor does not train' },
  { id: 'proposals', label: 'The verticals are proposals' },
  { id: 'words', label: 'The word list is ours' },
  { id: 'harder', label: 'This game is harder than the original' },
  { id: 'unmeasured', label: 'What we have not measured' },
];

export default function Honesty() {
  useSeo({
    title: pageTitle('Honesty'),
    description:
      'What is measured here, what is cited from elsewhere, and what we have deliberately not measured — including where our own word list makes the game easier than the original.',
    canonical: routes.honesty,
    ogImage: '/og/honesty.png',
  });

  return (
    <main className={`${s.shell} py-10 sm:py-16`}>
      <p className={s.eyebrow}>Honesty</p>
      <h1 className={`${s.h1} mt-3 max-w-3xl`}>What is measured, what is cited, and what is not.</h1>
      <p className={`${s.lede} mt-5 max-w-2xl`}>
        This site argues that a number you can check beats a claim you have to trust. That argument
        only works if we hold our own numbers to it. So here is every claim on the site, sorted by
        how much weight it can carry.
      </p>

      <nav aria-label="On this page" className="card mt-8 p-5">
        <p className={s.eyebrow}>On this page</p>
        <ul className="mt-3 grid gap-x-6 gap-y-2 sm:grid-cols-2">
          {CONTENTS.map((item) => (
            <li key={item.id}>
              <a className={`${s.link} text-sm`} href={`#${item.id}`}>
                {item.label}
              </a>
            </li>
          ))}
        </ul>
      </nav>

      {/* ── Measured ───────────────────────────────────────────────────── */}
      <section className="mt-12 max-w-3xl">
        <Heading id="measured">What we measured ourselves</Heading>
        <p className={`${s.prose} mt-4`}>
          Everything in this section is reproducible from a clone of this repository, offline, with
          no account and no key. If any of it does not reproduce, that is a bug and we want the
          issue.
        </p>
        <ul className={`${s.prose} mt-4 space-y-4`}>
          <li>
            <strong className="text-fg">The environment runs.</strong> The word game is a real
            environment in this repository, not a mock behind the page. Three commands score a model
            with it:
            <pre className={`${s.codeBlock} mt-2`}>
              <code>
                {reproduce.clone}
                {'\n'}
                {reproduce.install}
                {'\n'}
                {reproduce.evaluate}
              </code>
            </pre>
          </li>
          <li>
            <strong className="text-fg">The word lists rebuild byte for byte.</strong> Both source
            dictionaries are committed beside the script that filters them, so{' '}
            <code className="font-mono text-fg">{wordList.rebuild}</code> produces the same{' '}
            <span className="nums">{wordList.answers.toLocaleString('en-US')}</span> answers and{' '}
            <span className="nums">{wordList.guesses.toLocaleString('en-US')}</span> legal guesses on
            any machine.
          </li>
          <li>
            <strong className="text-fg">The two implementations of the rules agree.</strong> The
            grader exists twice — once in Python for the environment, once in TypeScript for the
            board in your browser. Continuous integration scores every ordered pair of words in the
            answer list through both, about{' '}
            <span className="nums">21.2 million</span> feedback patterns, and compares a hash. A
            divergence fails the build rather than showing you one result and scoring another.
          </li>
          <li>
            <strong className="text-fg">The scores on a recorded run are re-derived, not
            recited.</strong> Where a demo ships a verifier, the page recomputes the reward in your
            browser from the recorded turns instead of printing a number stored in the file. If a
            trace is truncated, it renders as unverifiable — never as zero.
          </li>
        </ul>
      </section>

      {/* ── Cited ──────────────────────────────────────────────────────── */}
      <section className="mt-12 max-w-3xl">
        <Heading id="cited">What we cite from elsewhere</Heading>
        <p className={`${s.prose} mt-4`}>
          Three claims on this site are not ours. They are linked so you can go and check them
          instead of taking them from us.
        </p>

        <div className="card mt-5 p-5">
          <h3 className={s.h3}>
            {trainingResult.model}: {trainingResult.before} → {trainingResult.after}{' '}
            {trainingResult.metric}
          </h3>
          <p className={`${s.prose} mt-2`}>
            Published by Prime Intellect, measured on {trainingResult.evalDescription}, after{' '}
            {trainingResult.method}. Both checkpoints are on Hugging Face, so you can run the eval
            yourself: <Out href={trainingResult.checkpoints[0].href}>the SFT checkpoint</Out> and{' '}
            <Out href={trainingResult.checkpoints[1].href}>the RL checkpoint</Out>, with{' '}
            <Out href={trainingResult.source.href}>the write-up</Out>.
          </p>
          <p className={`${s.prose} mt-3`}>
            We quote the win rate and nothing else. The same write-up gives average-reward figures
            for those runs; we leave them out because the reward function has changed across
            versions of that environment and the two figures were never re-measured together. A win
            rate survives a reward change. An average reward does not. We have also not reproduced
            this result: their environment and word list are not ours, and a number measured on a
            different task list is not a number about this one.
          </p>
        </div>

        <div className="card mt-4 p-5">
          <h3 className={s.h3}>Wordle is Prime Intellect’s own hello-world</h3>
          <p className={`${s.prose} mt-2`}>
            We say this because a demo picked to flatter itself is worth nothing. It appears in three
            places in their stack:
          </p>
          <ul className={`${s.prose} mt-3 space-y-2`}>
            {helloWorldCitations.map((c) => (
              <li key={c.href}>
                <Out href={c.href}>{c.label}</Out> — {c.claim}
              </li>
            ))}
          </ul>
        </div>

        <div className="card mt-4 p-5">
          <h3 className={s.h3}>{optimalPlay.average} is not our number</h3>
          <p className={`${s.prose} mt-2`}>
            The famous optimum is <Out href={optimalPlay.href}>{optimalPlay.label}</Out>. It belongs
            to that list and that solver. It is not the optimum for our list, we have not computed
            ours, and you should not read it as a bar this environment is being measured against.
          </p>
        </div>
      </section>

      {/* ── Recorded ───────────────────────────────────────────────────── */}
      <section className="mt-12 max-w-3xl">
        <Heading id="recorded">Every rollout on this site is recorded, not live</Heading>
        <p className={`${s.prose} mt-4`}>
          When you watch a model play here, you are watching a file. No model is called while you
          read this page. That is a choice, and these are the reasons for it:
        </p>
        <ul className={`${s.prose} mt-4 list-disc space-y-3 pl-5`}>
          <li>
            <strong className="text-fg">The argument is about determinism.</strong> A page whose
            model says something different on every reload cannot be used to make the case that the
            grader stays put. The demo has to behave like the thing it is describing.
          </li>
          <li>
            <strong className="text-fg">There is nowhere to hide a cherry-pick.</strong> Every run is
            a file in the repository carrying its model, its seed and the date it was captured. A bad
            run is in there being bad. A live demo lets you re-roll until it looks good and tell
            nobody.
          </li>
          <li>
            <strong className="text-fg">It works.</strong> No key, no rate limit, no bill, no
            dependence on a provider being up during the ten minutes you are looking at it.
          </li>
        </ul>
        <p className={`${s.prose} mt-4`}>
          The cost is real: you cannot make a model react to a word you chose. If that is what you
          want, run the environment on your own machine against your own endpoint. It is three
          commands and the code is above.
        </p>
      </section>

      {/* ── Reward editor ──────────────────────────────────────────────── */}
      <section className="mt-12 max-w-3xl">
        <Heading id="editor">The reward editor re-scores. It does not train anything.</Heading>
        <p className={`${s.prose} mt-4`}>
          Moving a weight changes how the recorded attempts are scored, and the page recomputes and
          re-ranks them. That is the entire mechanism. Nothing is fine-tuned, no model is called, and
          nothing learns while you drag a slider.
        </p>
        <p className={`${s.prose} mt-4`}>
          What it is there to show is narrow and worth the space: two runs can swap places when you
          change what you are paying for. That is a fact about your definition of good, not about the
          models — and it is the reason the definition is worth an hour of your team’s attention
          before the training run is worth a GPU.
        </p>
        <p className={`${s.prose} mt-4`}>
          The other half — actually training against the reward you just wrote — takes GPUs and
          hours, and it does not belong in a browser tab. That is what a trainer like prime-rl is
          for, and the number at the top of the home page is what it produced.
        </p>
      </section>

      {/* ── Proposals ──────────────────────────────────────────────────── */}
      <section className="mt-12 max-w-3xl">
        <Heading id="proposals">The verticals are our proposals</Heading>
        <p className={`${s.prose} mt-4`}>
          Eleven of the twelve entries in the lineup describe environments that do not exist. They
          are labelled <span className="font-semibold text-fg">“{PROPOSAL_NOTICE}”</span> on every
          surface that shows them, and that label is the literal truth: we wrote them.
        </p>
        <ul className={`${s.prose} mt-4 list-disc space-y-3 pl-5`}>
          <li>They are not on Prime Intellect’s roadmap and we do not speak for Prime Intellect.</li>
          <li>
            No customer asked for any of them. No company appears anywhere on this site as a
            customer, a reference or a logo, because none is one.
          </li>
          <li>
            Where a page names a KPI, we are describing how that function usually measures itself. We
            are not reporting anyone’s numbers, and there are no numbers on those pages to report.
          </li>
        </ul>
        <p className={`${s.prose} mt-4`}>
          Two of them carry a standing caveat on their own page — the{' '}
          <Link className={s.link} to={routes.vertical('legal-playbook-redline')}>
            legal redline
          </Link>
          , where grading the drafting half collapses into an LLM judge, and{' '}
          <Link className={s.link} to={routes.vertical('semiconductor-ppa-closure')}>
            semiconductor timing closure
          </Link>
          , which has the best reward on the page and is the one thing here we are telling you we are
          not going to build.
        </p>
      </section>

      {/* ── Word list ──────────────────────────────────────────────────── */}
      <section className="mt-12 max-w-3xl">
        <Heading id="words">The word list is our own construction</Heading>
        <p className={`${s.prose} mt-4`}>
          We did not copy the original game’s word lists. Our answers are the intersection of two
          permissively-licensed sources — every five-letter headword in{' '}
          <Out href={wordList.sources[0].href}>{wordList.sources[0].label}</Out> that also appears in{' '}
          <Out href={wordList.sources[1].href}>{wordList.sources[1].label}</Out>, minus a short
          hand-written blocklist. Legal guesses are the whole five-letter Wordnik set.
        </p>
        <dl className="card mt-5 grid gap-4 p-5 sm:grid-cols-3">
          <div>
            <dt className={s.eyebrow}>Answers</dt>
            <dd className="nums mt-1 text-2xl font-bold text-fg">
              {wordList.answers.toLocaleString('en-US')}
            </dd>
          </div>
          <div>
            <dt className={s.eyebrow}>Legal guesses</dt>
            <dd className="nums mt-1 text-2xl font-bold text-fg">
              {wordList.guesses.toLocaleString('en-US')}
            </dd>
          </div>
          <div>
            <dt className={s.eyebrow}>Original game’s answers</dt>
            <dd className="nums mt-1 text-2xl font-bold text-muted">
              {wordList.originalAnswers.toLocaleString('en-US')}
            </dd>
          </div>
        </dl>
        <p className={`${s.prose} mt-4`}>
          The list is built by a stated rule from sources anyone can fetch, rather than lifted from
          somebody’s editorial selection. That is the point of it. It also means every comparison to
          the original game is a comparison between two different games.
        </p>
      </section>

      {/* ── Harder ────────────────────────────────────────────────────── */}
      <section className="mt-12 max-w-3xl">
        <Heading id="harder">This environment is harder than the original game</Heading>
        <p className={`${s.prose} mt-4`}>
          Two things pull in opposite directions here, so we measured rather than argued. Our answer
          pool comes from a dictionary rule, so it keeps the regular plurals and past tenses the
          original game’s editor removed by hand:{' '}
          <span className="nums font-semibold text-fg">{wordList.endsInS}</span> of our answers end
          in a plain <span className="font-mono">S</span> and{' '}
          <span className="nums font-semibold text-fg">{wordList.endsInEd}</span> in{' '}
          <span className="font-mono">-ED</span>. That is an exploitable regularity, and it makes our
          list easier. Our pool is also roughly twice the size, which makes it harder.
        </p>
        <p className={`${s.prose} mt-4`}>
          The net effect is the second one. We ran the same greedy solver over both pools, on{' '}
          <span className="nums font-semibold text-fg">{poolComparison.sampled}</span> sampled words
          each:
        </p>
        <div className="mt-4 overflow-x-auto">
          <table className="w-full min-w-[26rem] border-collapse text-sm">
            <thead>
              <tr className="border-b border-border text-left text-muted">
                <th className="py-2 pr-4 font-medium">Answer pool</th>
                <th className="py-2 pr-4 font-medium">Best opener</th>
                <th className="py-2 pr-4 font-medium">Mean guesses</th>
                <th className="py-2 font-medium">Worst case</th>
              </tr>
            </thead>
            <tbody className="nums">
              <tr className="border-b border-border">
                <td className="py-2 pr-4">Original, {poolComparison.original.size}</td>
                <td className="py-2 pr-4 font-mono">{poolComparison.original.opener}</td>
                <td className="py-2 pr-4">{poolComparison.original.mean}</td>
                <td className="py-2">{poolComparison.original.worst}</td>
              </tr>
              <tr>
                <td className="py-2 pr-4 font-semibold text-fg">Ours, {poolComparison.ours.size}</td>
                <td className="py-2 pr-4 font-mono">{poolComparison.ours.opener}</td>
                <td className="py-2 pr-4 font-semibold text-fg">{poolComparison.ours.mean}</td>
                <td className="py-2">{poolComparison.ours.worst}</td>
              </tr>
            </tbody>
          </table>
        </div>
        <p className={`${s.prose} mt-4`}>
          About a seventh of a guess harder, and one worse in the worst case. Both rows are the same
          algorithm, which is the only fair comparison available — setting our greedy number against
          the published{' '}
          <span className="nums">3.4212</span> optimum for the original list would be comparing two
          different algorithms and calling the difference a property of the words.
        </p>
        <p className={`${s.prose} mt-4`}>
          The practical instruction is unchanged: do not compare a guess count from this site to your
          own statistics from the original game. It is a different game with a different shape.
        </p>
      </section>

      {/* ── Unmeasured ─────────────────────────────────────────────────── */}
      <section className="mt-12 max-w-3xl">
        <Heading id="unmeasured">What we have not measured</Heading>
        <p className={`${s.prose} mt-4`}>
          This is the list we would want if we were the ones being sold to.
        </p>
        <ul className={`${s.prose} mt-4 list-disc space-y-3 pl-5`}>
          <li>
            <strong className="text-fg">Any training result of our own.</strong> We have not trained
            a model against this environment. The before-and-after number on the home page is Prime
            Intellect’s, measured on their word list, and we did not rerun it on ours.
          </li>
          <li>
            <strong className="text-fg">Variance.</strong> The recorded runs are individual seeds,
            not samples. There is no confidence interval anywhere on this site and no claim that a
            given run is typical. A demonstration with one seed is a demonstration, not evidence.
          </li>
          <li>
            <strong className="text-fg">An optimum, or a human baseline, for our list.</strong> We do
            not know how few guesses perfect play needs on our answers, and we have not asked people
            to play it.
          </li>
          <li>
            <strong className="text-fg">Cost and latency.</strong> No number here is a price, a
            token count you should budget from, or a wall-clock comparison between models. The
            durations shown in a trace are what that recording measured, on that day, on that
            endpoint.
          </li>
          <li>
            <strong className="text-fg">Anything at all about the eleven proposals.</strong> Nothing
            in those pages has been run. Every reward, counterweight and KPI there is a design.
          </li>
          <li>
            <strong className="text-fg">A full review of the answer list.</strong> We block a short
            hand-written set of words from ever being the hidden answer. We have not audited the
            remaining {wordList.answers.toLocaleString('en-US')} exhaustively, and a five-letter
            English dictionary contains words somebody will not want on a boardroom screen.
          </li>
        </ul>
      </section>

      <div className="card mt-14 p-5 sm:p-7">
        <h2 className={s.h3}>Found something on this site that is wrong?</h2>
        <p className={`${s.prose} mt-2 max-w-2xl`}>
          Every claim above is traceable to a file in the repository. If one of them does not hold,
          open an issue with the page and the sentence and we will fix the sentence or the code.
        </p>
        <div className="mt-5 flex flex-col gap-3 sm:flex-row">
          <a
            className={s.btnPrimary}
            href={REPO_URL}
            rel="noreferrer noopener"
            target="_blank"
          >
            Read the source
          </a>
          <Link className={s.btnSecondary} to={routes.home}>
            Back to the demo
          </Link>
        </div>
      </div>
    </main>
  );
}
