import { ArrowRight } from 'lucide-react';

import { anatomyTerm } from '@/content/anatomy';
import type { AnatomyKey } from '@/content/anatomy';
import type { DemoModule } from '@/lib/demo-kit/types';
import { cn } from '@/lib/utils';

export type Anatomy = DemoModule['anatomy'];

export interface EnvAnatomyProps {
  anatomy: Anatomy;
  /** `DemoMeta.rewardLine` — six words on what the reward pays for. */
  rewardLine?: string;
  /**
   * The Play-tab form: four boxes and their bodies, no questions and no closing
   * line, because the visitor has just acted and the boxes are a caption to
   * what they did rather than the lesson itself.
   */
  compact?: boolean;
  className?: string;
}

/**
 * The four boxes, in the order an executive builds the mental model: what is
 * being asked, what the agent is allowed to do, who decides whether it was
 * good, and what number that decision moves.
 *
 * The kickers come from `@/content/anatomy` — the SAME strings the landing's
 * definition strip renders. This object is the site's one piece of
 * transferable explanation: someone who learns the machine on a word game
 * should read the fraud screen as "same machine, different grader", and that
 * only works if the four labels never change between the landing and a demo.
 * The order is the contract's, whatever order the content file lists them in.
 */
const KEYS: readonly AnatomyKey[] = ['task', 'actions', 'grader', 'score'];
const BOXES = KEYS.map(anatomyTerm);

export function EnvAnatomy({ anatomy, rewardLine, compact = false, className }: EnvAnatomyProps) {
  return (
    <div className={cn('space-y-4', className)}>
      <ol className="flex flex-col lg:flex-row lg:items-stretch">
        {BOXES.map((box, position) => {
          const grader = box.key === 'grader';
          return (
            <li
              key={box.key}
              className="flex flex-col items-stretch lg:flex-1 lg:flex-row lg:items-stretch"
            >
              <div
                className={cn(
                  'flex flex-1 flex-col gap-2 rounded-xl border p-4',
                  // The grader is the box every later demo differs on. It is
                  // the one the eye should land on second, after the task.
                  grader ? 'border-accent-fg bg-accent-subtle' : 'border-border bg-surface',
                )}
              >
                <div className="flex items-baseline gap-2">
                  <span className="font-mono text-label text-muted" aria-hidden="true">
                    {box.index}
                  </span>
                  <p className="text-ui font-semibold leading-tight text-fg">{box.kicker}</p>
                </div>
                {!compact ? <p className="text-small text-muted">{box.question}</p> : null}
                <p className="text-pretty text-small text-fg-2">{anatomy[box.key]}</p>
              </div>
              {position < BOXES.length - 1 ? (
                <div
                  aria-hidden="true"
                  className="flex items-center justify-center py-1.5 text-border-strong lg:px-1.5 lg:py-0"
                >
                  <ArrowRight className="size-4 rotate-90 lg:rotate-0" />
                </div>
              ) : null}
            </li>
          );
        })}
      </ol>

      {rewardLine ? (
        <p className="text-ui text-muted">
          <span className="font-mono text-label uppercase tracking-label">This reward</span>{' '}
          <span className="text-fg-2">{rewardLine}</span>
        </p>
      ) : null}

      {!compact ? (
        <p className="max-w-measure text-pretty text-prose text-fg-2">
          Every demo on this site is that same machine. The task changes, the legal actions
          change, and the grader changes — but the grader is always code you can read, and the
          score is always a number you can watch move. That is what makes an environment
          different from an eval:{' '}
          <span className="font-medium text-fg">
            an environment is an eval you can take the gradient of.
          </span>
        </p>
      ) : null}
    </div>
  );
}
