import type { ModelCall } from '@/lib/demo-kit/types';
import { cn } from '@/lib/utils';
import { DASH, formatInt, formatMs, humaniseToken } from './format';

export interface ModelCallPanelProps {
  call: ModelCall | null;
  className?: string;
  title?: string;
}

interface Row {
  label: string;
  value: string;
  hint?: string;
}

/**
 * The model call, straight off the trace.
 *
 * Nothing here is computed, averaged or estimated. Every field is a value the
 * recorder wrote down, and a field the recorder did not write down renders as
 * an em dash — never as zero, and never quietly omitted. A provider that does
 * not report reasoning tokens is a fact about the trace, and hiding the row
 * would turn "we do not know" into "there were none".
 */
export function ModelCallPanel({ call, className, title = 'Model call' }: ModelCallPanelProps) {
  const rows: Row[] = [
    {
      label: 'finish_reason',
      value: call?.finishReason ? humaniseToken(call.finishReason) : DASH,
      hint: 'Why the model stopped generating',
    },
    {
      label: 'Prompt tokens',
      value: formatInt(call?.promptTokens ?? null),
      hint: 'Everything sent in: system, board, history',
    },
    {
      label: 'Completion tokens',
      value: formatInt(call?.completionTokens ?? null),
      hint: 'The visible reply',
    },
    {
      label: 'Reasoning tokens',
      value: formatInt(call?.reasoningTokens ?? null),
      hint: 'Billed thinking, when the provider reports it',
    },
    {
      label: 'Latency',
      value: formatMs(call?.durationMs ?? null),
      hint: 'Real elapsed time when the run was recorded',
    },
  ];

  return (
    <section aria-label={title} className={cn('card overflow-hidden', className)}>
      <header className="border-b border-border px-3 py-2">
        <h3 className="text-sm font-semibold">{title}</h3>
      </header>
      {call === null ? (
        <p className="px-3 py-3 text-sm text-muted">
          This step did not involve a model call — it is a state change the environment made on
          its own.
        </p>
      ) : (
        <dl className="divide-y divide-border">
          {rows.map((row) => (
            <div key={row.label} className="flex items-baseline gap-3 px-3 py-2">
              <dt className="min-w-0 flex-1">
                <span className="block text-sm font-medium">{row.label}</span>
                {row.hint ? (
                  <span className="block text-xs leading-snug text-muted">{row.hint}</span>
                ) : null}
              </dt>
              <dd className="nums shrink-0 font-mono text-sm text-fg">{row.value}</dd>
            </div>
          ))}
        </dl>
      )}
    </section>
  );
}
