import type { LucideIcon } from 'lucide-react';
import { ArrowRight, ListChecks, Scale, Target, TrendingUp } from 'lucide-react';
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;
  /** Set on the gallery/overview page, where the four boxes are context rather
   *  than the lesson, to drop the closing line and tighten the type. */
  compact?: boolean;
  className?: string;
}

interface Box {
  key: keyof Anatomy;
  kicker: string;
  question: string;
  Icon: LucideIcon;
}

/**
 * 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 are deliberately generic. This object is the site's one piece of
 * transferable explanation: someone who learns the machine on a word game
 * should read the fraud demo as "same machine, different grader", and that only
 * works if the four labels never change between demos.
 */
const BOXES: Box[] = [
  { key: 'task', kicker: 'The task', question: 'What is the agent asked to do?', Icon: Target },
  {
    key: 'actions',
    kicker: 'Legal actions',
    question: 'What is it allowed to do?',
    Icon: ListChecks,
  },
  {
    key: 'grader',
    kicker: 'The grader',
    question: 'Who decides whether it was good?',
    Icon: Scale,
  },
  {
    key: 'score',
    kicker: 'The score that moves',
    question: 'What number does that produce?',
    Icon: TrendingUp,
  },
];

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, index) => (
          <li
            key={box.key}
            className="flex flex-col items-stretch lg:flex-1 lg:flex-row lg:items-center"
          >
            <div
              className={cn(
                'card flex flex-1 flex-col gap-2 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.
                box.key === 'grader' && 'border-brand/40 bg-accent-subtle/40',
              )}
            >
              <div className="flex items-center gap-2">
                <span className="grid h-8 w-8 shrink-0 place-items-center rounded-lg bg-accent-subtle text-accent-fg">
                  <box.Icon className="h-4 w-4" strokeWidth={2} aria-hidden="true" />
                </span>
                <div className="min-w-0">
                  <p className="text-sm font-semibold leading-tight">
                    <span className="nums mr-1.5 text-muted">{index + 1}</span>
                    {box.kicker}
                  </p>
                  {!compact ? (
                    <p className="text-xs leading-tight text-muted">{box.question}</p>
                  ) : null}
                </div>
              </div>
              <p className={cn('text-pretty text-fg', compact ? 'text-xs' : 'text-sm')}>
                {anatomy[box.key]}
              </p>
            </div>
            {index < BOXES.length - 1 ? (
              <div
                aria-hidden="true"
                className="flex items-center justify-center py-2 text-muted lg:px-2 lg:py-0"
              >
                <ArrowRight className="h-4 w-4 rotate-90 lg:rotate-0" />
              </div>
            ) : null}
          </li>
        ))}
      </ol>

      {rewardLine ? (
        <p className="text-sm text-muted">
          <span className="font-medium text-fg">This reward: </span>
          {rewardLine}
        </p>
      ) : null}

      {!compact ? (
        <p className="max-w-3xl text-pretty text-sm leading-relaxed text-muted">
          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>
  );
}
