import { useState, useEffect, useCallback } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { apiGet, apiPost, apiPut, apiDelete, ApiError } from '../api/client';
import { Card, LoadingSpinner, StatusBadge } from '../components/ui';
import {
  LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid, Legend,
} from 'recharts';

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

interface Agent {
  id: string;
  name: string;
  slug: string;
  purpose: string;
  model_provider: string;
  model_name: string;
  system_prompt: string;
  user_prompt_template: string;
  prompt_version: string;
  schema_version: string;
  temperature: number;
  max_tokens: number;
  timeout_seconds: number;
  max_retries: number;
  active: boolean;
  source: string;
  created_at: string;
  updated_at: string;
}

interface AgentPerformance {
  total_invocations: number;
  successes: number;
  failures: number;
  avg_duration_ms: number | null;
  p95_duration_ms: number | null;
  avg_confidence: number | null;
  avg_retries: number | null;
  total_input_tokens: number | null;
  total_output_tokens: number | null;
  success_rate: number | null;
}

interface PerfHistoryPoint {
  hour: string;
  invocations: number;
  successes: number;
  avg_duration_ms: number;
  avg_confidence: number;
}

interface AgentVariant {
  id: string;
  agent_id: string;
  variant_name: string;
  variant_slug: string;
  description: string;
  model_provider: string;
  model_name: string;
  system_prompt: string;
  user_prompt_template: string;
  prompt_version: string;
  temperature: number;
  max_tokens: number;
  context_window: number;
  input_token_limit: number;
  token_budget: number;
  timeout_seconds: number;
  max_retries: number;
  is_active: boolean;
  created_at: string;
  updated_at: string;
}

// ---------------------------------------------------------------------------
// Hooks
// ---------------------------------------------------------------------------

function useAgents() {
  return useQuery<Agent[]>({
    queryKey: ['agents'],
    queryFn: () => apiGet<Agent[]>('query', '/api/agents'),
  });
}

function useAgentPerformance(agentId: string | undefined, hours = 24) {
  return useQuery<AgentPerformance>({
    queryKey: ['agent-performance', agentId, hours],
    queryFn: () => apiGet<AgentPerformance>('query', `/api/agents/${agentId}/performance?hours=${hours}`),
    enabled: !!agentId,
  });
}

function useAgentPerfHistory(agentId: string | undefined, hours = 24) {
  return useQuery<PerfHistoryPoint[]>({
    queryKey: ['agent-perf-history', agentId, hours],
    queryFn: () => apiGet<PerfHistoryPoint[]>('query', `/api/agents/${agentId}/performance/history?hours=${hours}`),
    enabled: !!agentId,
  });
}

// -- Variant query hooks --

function useAgentVariants(agentId: string | undefined) {
  return useQuery<AgentVariant[]>({
    queryKey: ['agent-variants', agentId],
    queryFn: () => apiGet<AgentVariant[]>('query', `/api/agents/${agentId}/variants`),
    enabled: !!agentId,
  });
}

export function useVariantPerformance(agentId: string, variantId: string, hours = 24) {
  return useQuery<AgentPerformance>({
    queryKey: ['variant-performance', agentId, variantId, hours],
    queryFn: () => apiGet<AgentPerformance>('query', `/api/agents/${agentId}/variants/${variantId}/performance?hours=${hours}`),
    enabled: !!agentId && !!variantId,
  });
}

export function useVariantPerfHistory(agentId: string, variantId: string, hours = 24) {
  return useQuery<PerfHistoryPoint[]>({
    queryKey: ['variant-perf-history', agentId, variantId, hours],
    queryFn: () => apiGet<PerfHistoryPoint[]>('query', `/api/agents/${agentId}/variants/${variantId}/performance/history?hours=${hours}`),
    enabled: !!agentId && !!variantId,
  });
}

// -- Variant mutation hooks --

function useCloneAgentAsVariant(agentId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (body: Record<string, unknown>) => apiPost<AgentVariant>('query', `/api/agents/${agentId}/clone`, body),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['agent-variants'] }); },
  });
}

export function useCreateVariant(agentId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (body: Record<string, unknown>) => apiPost<AgentVariant>('query', `/api/agents/${agentId}/variants`, body),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['agent-variants'] }); },
  });
}

function useUpdateVariant(agentId: string, variantId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (body: Record<string, unknown>) => apiPut<AgentVariant>('query', `/api/agents/${agentId}/variants/${variantId}`, body),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['agent-variants'] }); },
  });
}

function useDeleteVariant(agentId: string, variantId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: () => apiDelete<unknown>('query', `/api/agents/${agentId}/variants/${variantId}`),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['agent-variants'] }); },
  });
}

function useActivateVariant(agentId: string, variantId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: () => apiPost<AgentVariant>('query', `/api/agents/${agentId}/variants/${variantId}/activate`, {}),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['agent-variants'] }); },
  });
}

export function useDeactivateVariants(agentId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: () => apiPost<unknown>('query', `/api/agents/${agentId}/variants/deactivate`, {}),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['agent-variants'] }); },
  });
}

// ---------------------------------------------------------------------------
// Page Component
// ---------------------------------------------------------------------------

export function AgentsPage() {
  const qc = useQueryClient();
  const { data: agents, isLoading } = useAgents();
  const [selectedId, setSelectedId] = useState<string | undefined>(undefined);
  const [editing, setEditing] = useState(false);
  const [creating, setCreating] = useState(false);

  const selected = agents?.find((a) => a.id === selectedId);

  if (isLoading) return <LoadingSpinner />;

  return (
    <div className="flex gap-4 h-[calc(100vh-3rem)]">
      {/* Agent List Sidebar */}
      <div className="w-64 shrink-0 overflow-y-auto rounded-lg border border-surface-700 bg-surface-900 p-3 space-y-1">
        <div className="flex items-center justify-between mb-2">
          <h2 className="text-xs font-semibold uppercase tracking-wider text-gray-500">Agents</h2>
          <button
            onClick={() => { setCreating(true); setSelectedId(undefined); setEditing(false); }}
            className="rounded bg-brand-600 px-2 py-0.5 text-[10px] font-medium text-white hover:bg-brand-700"
          >
            + New
          </button>
        </div>
        {(agents ?? []).map((agent) => (
          <button
            key={agent.id}
            onClick={() => { setSelectedId(agent.id); setEditing(false); setCreating(false); }}
            className={`w-full rounded-md px-3 py-2 text-left text-sm transition-colors ${
              selectedId === agent.id
                ? 'bg-brand-600/20 border border-brand-500/50 text-brand-300'
                : 'text-gray-300 hover:bg-surface-800'
            }`}
          >
            <div className="flex items-center justify-between">
              <span className="font-medium truncate">{agent.name}</span>
              {!agent.active && <span className="text-[9px] text-gray-600">OFF</span>}
            </div>
            <div className="flex items-center gap-2 mt-0.5">
              <span className="text-[10px] text-gray-500">{agent.model_name}</span>
              <span className={`rounded px-1 py-0 text-[9px] ${agent.source === 'system' ? 'bg-blue-900/30 text-blue-400' : 'bg-emerald-900/30 text-emerald-400'}`}>
                {agent.source}
              </span>
            </div>
          </button>
        ))}
      </div>

      {/* Detail Panel */}
      <div className="flex-1 overflow-y-auto space-y-4">
        {creating ? (
          <CreateAgentForm
            onCreated={(id) => { qc.invalidateQueries({ queryKey: ['agents'] }); setSelectedId(id); setCreating(false); }}
            onCancel={() => setCreating(false)}
          />
        ) : selected ? (
          editing ? (
            <EditAgentForm agent={selected} onSaved={() => { qc.invalidateQueries({ queryKey: ['agents'] }); setEditing(false); }} onCancel={() => setEditing(false)} />
          ) : (
            <AgentDetail agent={selected} onEdit={() => setEditing(true)} onDeleted={() => { qc.invalidateQueries({ queryKey: ['agents'] }); setSelectedId(undefined); }} />
          )
        ) : (
          <Card>
            <p className="text-sm text-gray-500">Select an agent to view its configuration and performance, or create a new one.</p>
          </Card>
        )}
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Agent Detail View
// ---------------------------------------------------------------------------

function AgentDetail({ agent, onEdit, onDeleted }: { agent: Agent; onEdit: () => void; onDeleted: () => void }) {
  const qc = useQueryClient();
  const { data: perf } = useAgentPerformance(agent.id);
  const { data: history } = useAgentPerfHistory(agent.id);
  const { data: variants } = useAgentVariants(agent.id);

  // Variant UI state
  const [variantView, setVariantView] = useState<
    | { mode: 'list' }
    | { mode: 'clone-agent' }
    | { mode: 'clone-variant'; source: AgentVariant }
    | { mode: 'edit-variant'; variant: AgentVariant }
    | { mode: 'delete-confirm'; variant: AgentVariant }
  >({ mode: 'list' });

  // Comparison selection state
  const [selectedVariantIds, setSelectedVariantIds] = useState<Set<string>>(new Set());

  // Clear selection when variants change (e.g., after activation, deletion)
  useEffect(() => {
    setSelectedVariantIds(new Set());
  }, [variants]);

  const toggleVariantSelection = useCallback((variantId: string) => {
    setSelectedVariantIds((prev) => {
      const next = new Set(prev);
      if (next.has(variantId)) {
        next.delete(variantId);
      } else {
        next.add(variantId);
      }
      return next;
    });
  }, []);

  const deleteMut = useMutation({
    mutationFn: () => apiDelete<unknown>('query', `/api/agents/${agent.id}`),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['agents'] }); onDeleted(); },
  });

  const chartData = (history ?? []).map((pt) => ({
    hour: new Date(pt.hour).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
    invocations: pt.invocations,
    successRate: pt.invocations > 0 ? Math.round((pt.successes / pt.invocations) * 100) : 0,
    avgLatency: pt.avg_duration_ms,
    avgConfidence: Math.round((pt.avg_confidence ?? 0) * 100),
  }));

  return (
    <div className="space-y-4">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <h1 className="text-xl font-semibold text-gray-100">{agent.name}</h1>
          <StatusBadge status={agent.active ? 'active' : 'disabled'} />
          <span className={`rounded px-1.5 py-0.5 text-[10px] font-medium ${agent.source === 'system' ? 'bg-blue-900/30 text-blue-400 border border-blue-700/50' : 'bg-emerald-900/30 text-emerald-400 border border-emerald-700/50'}`}>
            {agent.source}
          </span>
        </div>
        <div className="flex gap-2">
          <button onClick={() => setVariantView({ mode: 'clone-agent' })} className="rounded-md border border-brand-500/50 px-3 py-1.5 text-sm font-medium text-brand-300 hover:bg-brand-600/20">Clone as Variant</button>
          <button onClick={onEdit} className="rounded-md bg-brand-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-brand-700">Edit</button>
          {agent.source === 'user' && (
            <button onClick={() => deleteMut.mutate()} className="rounded-md border border-red-700/50 px-3 py-1.5 text-sm text-red-400 hover:bg-red-900/20">Delete</button>
          )}
        </div>
      </div>

      {/* Config */}
      <Card>
        <dl className="grid grid-cols-2 gap-x-8 gap-y-2 text-sm sm:grid-cols-4">
          <div><dt className="text-gray-500">Model</dt><dd className="font-mono text-gray-200">{agent.model_provider}/{agent.model_name}</dd></div>
          <div><dt className="text-gray-500">Prompt Version</dt><dd className="text-gray-200">{agent.prompt_version || '—'}</dd></div>
          <div><dt className="text-gray-500">Schema Version</dt><dd className="text-gray-200">{agent.schema_version}</dd></div>
          <div><dt className="text-gray-500">Temperature</dt><dd className="text-gray-200">{agent.temperature}</dd></div>
          <div><dt className="text-gray-500">Max Tokens</dt><dd className="text-gray-200">{agent.max_tokens.toLocaleString()}</dd></div>
          <div><dt className="text-gray-500">Timeout</dt><dd className="text-gray-200">{agent.timeout_seconds}s</dd></div>
          <div><dt className="text-gray-500">Max Retries</dt><dd className="text-gray-200">{agent.max_retries}</dd></div>
          <div><dt className="text-gray-500">Updated</dt><dd className="text-gray-300">{new Date(agent.updated_at).toLocaleString()}</dd></div>
        </dl>
      </Card>

      {agent.purpose && (
        <Card>
          <h2 className="mb-2 text-sm font-medium text-gray-400">Purpose</h2>
          <p className="text-sm text-gray-300">{agent.purpose}</p>
        </Card>
      )}

      <Card>
        <h2 className="mb-2 text-sm font-medium text-gray-400">System Prompt</h2>
        <pre className="whitespace-pre-wrap rounded-md bg-surface-950 p-3 text-xs text-gray-300 max-h-40 overflow-y-auto">{agent.system_prompt || '(none)'}</pre>
      </Card>

      {/* Performance Metrics */}
      {perf && (
        <Card>
          <h2 className="mb-3 text-sm font-medium text-gray-400">Performance (24h)</h2>
          <div className="grid grid-cols-2 gap-3 sm:grid-cols-5">
            <MetricCard label="Invocations" value={String(perf.total_invocations ?? 0)} />
            <MetricCard label="Success Rate" value={perf.success_rate != null ? `${(perf.success_rate * 100).toFixed(1)}%` : '—'} color={perf.success_rate != null && perf.success_rate >= 0.95 ? 'text-green-400' : 'text-yellow-400'} />
            <MetricCard label="Avg Latency" value={perf.avg_duration_ms != null ? `${Math.round(perf.avg_duration_ms)}ms` : '—'} />
            <MetricCard label="P95 Latency" value={perf.p95_duration_ms != null ? `${Math.round(perf.p95_duration_ms)}ms` : '—'} />
            <MetricCard label="Avg Confidence" value={perf.avg_confidence != null ? `${(perf.avg_confidence * 100).toFixed(0)}%` : '—'} />
          </div>
          <div className="mt-2 flex gap-4 text-xs text-gray-500">
            <span>Retries avg: {perf.avg_retries?.toFixed(1) ?? '—'}</span>
            <span>Input tokens: {perf.total_input_tokens?.toLocaleString() ?? '—'}</span>
            <span>Output tokens: {perf.total_output_tokens?.toLocaleString() ?? '—'}</span>
          </div>
        </Card>
      )}

      {/* Performance Chart */}
      {chartData.length > 1 && (
        <Card>
          <h2 className="mb-3 text-sm font-medium text-gray-400">Performance Over Time</h2>
          <ResponsiveContainer width="100%" height={200}>
            <LineChart data={chartData}>
              <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
              <XAxis dataKey="hour" tick={{ fill: '#6b7280', fontSize: 10 }} />
              <YAxis yAxisId="left" tick={{ fill: '#6b7280', fontSize: 10 }} />
              <YAxis yAxisId="right" orientation="right" tick={{ fill: '#6b7280', fontSize: 10 }} />
              <Tooltip contentStyle={{ backgroundColor: '#1e293b', border: '1px solid #334155', borderRadius: 8 }} />
              <Line yAxisId="left" type="monotone" dataKey="invocations" name="Invocations" stroke="#3b82f6" strokeWidth={2} dot={false} />
              <Line yAxisId="right" type="monotone" dataKey="successRate" name="Success %" stroke="#10b981" strokeWidth={2} dot={false} />
              <Line yAxisId="right" type="monotone" dataKey="avgConfidence" name="Confidence %" stroke="#f59e0b" strokeWidth={1.5} dot={false} />
            </LineChart>
          </ResponsiveContainer>
        </Card>
      )}

      {/* Variant Section */}
      {variantView.mode === 'clone-agent' && (
        <VariantCloneForm
          agentId={agent.id}
          source={{
            model_provider: agent.model_provider,
            model_name: agent.model_name,
            system_prompt: agent.system_prompt,
            user_prompt_template: agent.user_prompt_template,
            prompt_version: agent.prompt_version,
            temperature: agent.temperature,
            max_tokens: agent.max_tokens,
            context_window: 0,
            input_token_limit: 0,
            token_budget: 0,
            timeout_seconds: agent.timeout_seconds,
            max_retries: agent.max_retries,
          }}
          sourceType="agent"
          onDone={() => setVariantView({ mode: 'list' })}
        />
      )}
      {variantView.mode === 'clone-variant' && (
        <VariantCloneForm
          agentId={agent.id}
          source={variantView.source}
          sourceType="variant"
          sourceVariantId={variantView.source.id}
          onDone={() => setVariantView({ mode: 'list' })}
        />
      )}
      {variantView.mode === 'edit-variant' && (
        <VariantEditForm
          agentId={agent.id}
          variant={variantView.variant}
          onDone={() => setVariantView({ mode: 'list' })}
        />
      )}
      {variantView.mode === 'delete-confirm' && (
        <DeleteVariantDialog
          agentId={agent.id}
          variant={variantView.variant}
          onDone={() => setVariantView({ mode: 'list' })}
        />
      )}

      <VariantList
        agentId={agent.id}
        variants={variants ?? []}
        selectedIds={selectedVariantIds}
        onToggleSelect={toggleVariantSelection}
        onClone={(v) => setVariantView({ mode: 'clone-variant', source: v })}
        onEdit={(v) => setVariantView({ mode: 'edit-variant', variant: v })}
        onDelete={(v) => setVariantView({ mode: 'delete-confirm', variant: v })}
      />

      {selectedVariantIds.size >= 2 && (
        <VariantCompare
          agentId={agent.id}
          variants={(variants ?? []).filter((v) => selectedVariantIds.has(v.id))}
        />
      )}
    </div>
  );
}

// ---------------------------------------------------------------------------
// Variant List
// ---------------------------------------------------------------------------

function VariantList({ agentId, variants, selectedIds, onToggleSelect, onClone, onEdit, onDelete }: {
  agentId: string;
  variants: AgentVariant[];
  selectedIds: Set<string>;
  onToggleSelect: (id: string) => void;
  onClone: (v: AgentVariant) => void;
  onEdit: (v: AgentVariant) => void;
  onDelete: (v: AgentVariant) => void;
}) {
  return (
    <Card>
      <h2 className="mb-3 text-sm font-medium text-gray-400">Variants ({variants.length})</h2>
      {variants.length === 0 ? (
        <p className="text-xs text-gray-500">No variants yet. Clone this agent to create one.</p>
      ) : (
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="border-b border-surface-700 text-left text-xs text-gray-500">
                <th className="pb-2 pr-2 w-8">
                  <span className="sr-only">Select</span>
                </th>
                <th className="pb-2 pr-4">Name</th>
                <th className="pb-2 pr-4">Model</th>
                <th className="pb-2 pr-4">Status</th>
                <th className="pb-2 pr-4">Created</th>
                <th className="pb-2 text-right">Actions</th>
              </tr>
            </thead>
            <tbody>
              {variants.map((v) => (
                <VariantRow
                  key={v.id}
                  agentId={agentId}
                  variant={v}
                  selected={selectedIds.has(v.id)}
                  onToggleSelect={onToggleSelect}
                  onClone={onClone}
                  onEdit={onEdit}
                  onDelete={onDelete}
                />
              ))}
            </tbody>
          </table>
          {selectedIds.size > 0 && selectedIds.size < 2 && (
            <p className="mt-2 text-[10px] text-gray-500">Select at least 2 variants to compare.</p>
          )}
        </div>
      )}
    </Card>
  );
}

function VariantRow({ agentId, variant, selected, onToggleSelect, onClone, onEdit, onDelete }: {
  agentId: string;
  variant: AgentVariant;
  selected: boolean;
  onToggleSelect: (id: string) => void;
  onClone: (v: AgentVariant) => void;
  onEdit: (v: AgentVariant) => void;
  onDelete: (v: AgentVariant) => void;
}) {
  const activateMut = useActivateVariant(agentId, variant.id);

  return (
    <tr className={`border-b border-surface-800 ${variant.is_active ? 'bg-green-900/10' : ''}`}>
      <td className="py-2 pr-2">
        <input
          type="checkbox"
          checked={selected}
          onChange={() => onToggleSelect(variant.id)}
          className="rounded border-surface-600 bg-surface-950 text-brand-500 focus:ring-brand-500 focus:ring-offset-0 h-3.5 w-3.5"
        />
      </td>
      <td className="py-2 pr-4">
        <span className="font-medium text-gray-200">{variant.variant_name}</span>
        {variant.description && <p className="text-[10px] text-gray-500 truncate max-w-[200px]">{variant.description}</p>}
      </td>
      <td className="py-2 pr-4 font-mono text-xs text-gray-400">{variant.model_name}</td>
      <td className="py-2 pr-4">
        {variant.is_active ? <StatusBadge status="active" /> : <span className="text-xs text-gray-600">inactive</span>}
      </td>
      <td className="py-2 pr-4 text-xs text-gray-500">{new Date(variant.created_at).toLocaleDateString()}</td>
      <td className="py-2 text-right">
        <div className="flex justify-end gap-1">
          <button onClick={() => onEdit(variant)} className="rounded px-2 py-0.5 text-[10px] text-gray-400 hover:bg-surface-800 hover:text-gray-200">Edit</button>
          <button onClick={() => onClone(variant)} className="rounded px-2 py-0.5 text-[10px] text-gray-400 hover:bg-surface-800 hover:text-gray-200">Clone</button>
          <button onClick={() => onDelete(variant)} className="rounded px-2 py-0.5 text-[10px] text-red-400 hover:bg-red-900/20">Delete</button>
          <button
            onClick={() => activateMut.mutate()}
            disabled={variant.is_active || activateMut.isPending}
            className="rounded px-2 py-0.5 text-[10px] font-medium text-brand-400 hover:bg-brand-600/20 disabled:opacity-30 disabled:cursor-not-allowed"
          >
            {activateMut.isPending ? '…' : 'Activate'}
          </button>
        </div>
      </td>
    </tr>
  );
}

// ---------------------------------------------------------------------------
// Variant Comparison View
// ---------------------------------------------------------------------------

const COMPARE_COLORS = ['#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#ec4899', '#06b6d4', '#84cc16'];

function VariantCompareColumn({ agentId, variant, color }: {
  agentId: string;
  variant: AgentVariant;
  color: string;
}) {
  const { data: perf } = useVariantPerformance(agentId, variant.id);
  const activateMut = useActivateVariant(agentId, variant.id);

  return (
    <td className="px-3 py-2 text-center text-sm">
      <div className="mb-2">
        <span className="font-medium text-gray-200">{variant.variant_name}</span>
        <span className="ml-2 text-[10px] font-mono text-gray-500">{variant.model_name}</span>
        {variant.is_active && <StatusBadge status="active" />}
      </div>
      <div className="space-y-1.5 text-xs">
        <div>
          <span className="text-gray-500">Success Rate</span>
          <div className={`font-bold ${perf?.success_rate != null && perf.success_rate >= 0.95 ? 'text-green-400' : 'text-yellow-400'}`}>
            {perf?.success_rate != null ? `${(perf.success_rate * 100).toFixed(1)}%` : '—'}
          </div>
        </div>
        <div>
          <span className="text-gray-500">Avg Latency</span>
          <div className="text-gray-200">{perf?.avg_duration_ms != null ? `${Math.round(perf.avg_duration_ms)}ms` : '—'}</div>
        </div>
        <div>
          <span className="text-gray-500">P95 Latency</span>
          <div className="text-gray-200">{perf?.p95_duration_ms != null ? `${Math.round(perf.p95_duration_ms)}ms` : '—'}</div>
        </div>
        <div>
          <span className="text-gray-500">Avg Confidence</span>
          <div className="text-gray-200">{perf?.avg_confidence != null ? `${(perf.avg_confidence * 100).toFixed(0)}%` : '—'}</div>
        </div>
        <div>
          <span className="text-gray-500">Total Tokens</span>
          <div className="text-gray-200">
            {perf?.total_input_tokens != null || perf?.total_output_tokens != null
              ? ((perf.total_input_tokens ?? 0) + (perf.total_output_tokens ?? 0)).toLocaleString()
              : '—'}
          </div>
        </div>
      </div>
      {!variant.is_active && (
        <button
          onClick={() => activateMut.mutate()}
          disabled={activateMut.isPending}
          className="mt-3 rounded-md px-3 py-1 text-[10px] font-medium text-white hover:opacity-90 disabled:opacity-30"
          style={{ backgroundColor: color }}
        >
          {activateMut.isPending ? 'Activating…' : 'Activate'}
        </button>
      )}
    </td>
  );
}

function VariantCompareChart({ agentId, variants }: { agentId: string; variants: AgentVariant[] }) {
  // Fetch history for each selected variant
  const historyQueries = variants.map((v) =>
    // eslint-disable-next-line react-hooks/rules-of-hooks
    useVariantPerfHistory(agentId, v.id)
  );

  // Merge all history data into a unified time-series keyed by hour
  const hourMap = new Map<string, Record<string, number | string>>();

  variants.forEach((v, idx) => {
    const history = historyQueries[idx].data ?? [];
    for (const pt of history) {
      const hourKey = new Date(pt.hour).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
      if (!hourMap.has(hourKey)) {
        hourMap.set(hourKey, { hour: hourKey });
      }
      const entry = hourMap.get(hourKey)!;
      entry[`sr_${v.id}`] = pt.invocations > 0 ? Math.round((pt.successes / pt.invocations) * 100) : 0;
      entry[`lat_${v.id}`] = Math.round(pt.avg_duration_ms);
    }
  });

  const chartData = Array.from(hourMap.values());

  if (chartData.length < 2) return null;

  return (
    <div className="mt-4">
      <h3 className="mb-2 text-xs font-medium text-gray-500">Success Rate Over Time</h3>
      <ResponsiveContainer width="100%" height={200}>
        <LineChart data={chartData}>
          <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
          <XAxis dataKey="hour" tick={{ fill: '#6b7280', fontSize: 10 }} />
          <YAxis tick={{ fill: '#6b7280', fontSize: 10 }} />
          <Tooltip contentStyle={{ backgroundColor: '#1e293b', border: '1px solid #334155', borderRadius: 8 }} />
          <Legend />
          {variants.map((v, idx) => (
            <Line
              key={v.id}
              type="monotone"
              dataKey={`sr_${v.id}`}
              name={v.variant_name}
              stroke={COMPARE_COLORS[idx % COMPARE_COLORS.length]}
              strokeWidth={2}
              dot={false}
            />
          ))}
        </LineChart>
      </ResponsiveContainer>
    </div>
  );
}

function VariantCompare({ agentId, variants }: { agentId: string; variants: AgentVariant[] }) {
  return (
    <Card>
      <h2 className="mb-3 text-sm font-medium text-gray-400">Variant Comparison ({variants.length} selected)</h2>
      <div className="overflow-x-auto">
        <table className="w-full text-sm">
          <thead>
            <tr className="border-b border-surface-700">
              <th className="pb-2 pr-4 text-left text-xs text-gray-500">Metric</th>
              {variants.map((v, idx) => (
                <th key={v.id} className="pb-2 px-3 text-center text-xs" style={{ color: COMPARE_COLORS[idx % COMPARE_COLORS.length] }}>
                  {v.variant_name}
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            <tr>
              <td className="py-1 pr-4 text-xs text-gray-500">Metrics</td>
              {variants.map((v, idx) => (
                <VariantCompareColumn
                  key={v.id}
                  agentId={agentId}
                  variant={v}
                  color={COMPARE_COLORS[idx % COMPARE_COLORS.length]}
                />
              ))}
            </tr>
          </tbody>
        </table>
      </div>
      <VariantCompareChart agentId={agentId} variants={variants} />
    </Card>
  );
}

// ---------------------------------------------------------------------------
// Variant Clone Form
// ---------------------------------------------------------------------------

interface VariantConfigSource {
  model_provider: string;
  model_name: string;
  system_prompt: string;
  user_prompt_template: string;
  prompt_version: string;
  temperature: number;
  max_tokens: number;
  context_window: number;
  input_token_limit: number;
  token_budget: number;
  timeout_seconds: number;
  max_retries: number;
}

function VariantCloneForm({ agentId, source, sourceType, sourceVariantId, onDone }: {
  agentId: string;
  source: VariantConfigSource;
  sourceType: 'agent' | 'variant';
  sourceVariantId?: string;
  onDone: () => void;
}) {
  const [form, setForm] = useState({
    variant_name: '',
    description: '',
    model_provider: source.model_provider,
    model_name: source.model_name,
    system_prompt: source.system_prompt,
    user_prompt_template: source.user_prompt_template,
    prompt_version: source.prompt_version,
    temperature: source.temperature,
    max_tokens: source.max_tokens,
    context_window: source.context_window,
    input_token_limit: source.input_token_limit,
    token_budget: source.token_budget,
    timeout_seconds: source.timeout_seconds,
    max_retries: source.max_retries,
  });

  const cloneAgentMut = useCloneAgentAsVariant(agentId);
  const qc = useQueryClient();

  // For cloning from a variant, we use a direct mutation since the hook needs variantId
  const cloneVariantMut = useMutation({
    mutationFn: (body: Record<string, unknown>) => apiPost<AgentVariant>('query', `/api/agents/${agentId}/variants/${sourceVariantId}/clone`, body),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['agent-variants'] }); },
  });

  const mutation = sourceType === 'agent' ? cloneAgentMut : cloneVariantMut;

  function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    mutation.mutate(form, { onSuccess: () => onDone() });
  }

  return (
    <Card>
      <h2 className="mb-4 text-sm font-medium text-gray-400">
        Clone {sourceType === 'agent' ? 'Agent' : 'Variant'} as New Variant
      </h2>
      <form onSubmit={handleSubmit} className="space-y-3">
        <div className="grid grid-cols-2 gap-3">
          <FormRow label="Variant Name">
            <input value={form.variant_name} onChange={(e) => setForm({ ...form, variant_name: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" required />
          </FormRow>
          <FormRow label="Description">
            <input value={form.description} onChange={(e) => setForm({ ...form, description: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
        </div>
        <div className="grid grid-cols-2 gap-3">
          <FormRow label="Provider">
            <input value={form.model_provider} onChange={(e) => setForm({ ...form, model_provider: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Model">
            <input value={form.model_name} onChange={(e) => setForm({ ...form, model_name: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" required />
          </FormRow>
        </div>
        <FormRow label="System Prompt">
          <textarea value={form.system_prompt} onChange={(e) => setForm({ ...form, system_prompt: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none h-24 font-mono text-xs" />
        </FormRow>
        <FormRow label="User Prompt Template">
          <textarea value={form.user_prompt_template} onChange={(e) => setForm({ ...form, user_prompt_template: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none h-20 font-mono text-xs" />
        </FormRow>
        <div className="grid grid-cols-4 gap-3">
          <FormRow label="Temperature">
            <input type="number" step="0.1" min="0" max="2" value={form.temperature} onChange={(e) => setForm({ ...form, temperature: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Max Tokens">
            <input type="number" value={form.max_tokens} onChange={(e) => setForm({ ...form, max_tokens: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Timeout (s)">
            <input type="number" value={form.timeout_seconds} onChange={(e) => setForm({ ...form, timeout_seconds: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Max Retries">
            <input type="number" value={form.max_retries} onChange={(e) => setForm({ ...form, max_retries: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
        </div>
        <div className="grid grid-cols-3 gap-3">
          <FormRow label="Context Window (0 = default)">
            <input type="number" min="0" value={form.context_window} onChange={(e) => setForm({ ...form, context_window: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Input Token Limit (0 = unlimited)">
            <input type="number" min="0" value={form.input_token_limit} onChange={(e) => setForm({ ...form, input_token_limit: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Token Budget/hr (0 = unlimited)">
            <input type="number" min="0" value={form.token_budget} onChange={(e) => setForm({ ...form, token_budget: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
        </div>
        <FormRow label="Prompt Version">
          <input value={form.prompt_version} onChange={(e) => setForm({ ...form, prompt_version: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
        </FormRow>
        <div className="flex gap-2 pt-2">
          <button type="submit" disabled={mutation.isPending} className="rounded-md bg-brand-600 px-4 py-1.5 text-sm font-medium text-white hover:bg-brand-700 disabled:opacity-50">
            {mutation.isPending ? 'Cloning…' : 'Clone'}
          </button>
          <button type="button" onClick={onDone} className="rounded-md border border-surface-700 px-4 py-1.5 text-sm text-gray-400 hover:bg-surface-800">Cancel</button>
        </div>
        {mutation.isError && <p className="text-xs text-red-400">Failed to clone: {(mutation.error as ApiError)?.status === 409 ? 'Slug already exists' : 'Unknown error'}</p>}
      </form>
    </Card>
  );
}

// ---------------------------------------------------------------------------
// Variant Edit Form
// ---------------------------------------------------------------------------

function VariantEditForm({ agentId, variant, onDone }: {
  agentId: string;
  variant: AgentVariant;
  onDone: () => void;
}) {
  const [form, setForm] = useState({
    variant_name: variant.variant_name,
    description: variant.description,
    model_provider: variant.model_provider,
    model_name: variant.model_name,
    system_prompt: variant.system_prompt,
    user_prompt_template: variant.user_prompt_template,
    prompt_version: variant.prompt_version,
    temperature: variant.temperature,
    max_tokens: variant.max_tokens,
    context_window: variant.context_window,
    input_token_limit: variant.input_token_limit,
    token_budget: variant.token_budget,
    timeout_seconds: variant.timeout_seconds,
    max_retries: variant.max_retries,
  });

  const mutation = useUpdateVariant(agentId, variant.id);

  function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    mutation.mutate(form, { onSuccess: () => onDone() });
  }

  return (
    <Card>
      <h2 className="mb-4 text-sm font-medium text-gray-400">Edit Variant: {variant.variant_name}</h2>
      <form onSubmit={handleSubmit} className="space-y-3">
        <div className="grid grid-cols-2 gap-3">
          <FormRow label="Variant Name">
            <input value={form.variant_name} onChange={(e) => setForm({ ...form, variant_name: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" required />
          </FormRow>
          <FormRow label="Description">
            <input value={form.description} onChange={(e) => setForm({ ...form, description: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
        </div>
        <div className="grid grid-cols-2 gap-3">
          <FormRow label="Provider">
            <input value={form.model_provider} onChange={(e) => setForm({ ...form, model_provider: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Model">
            <input value={form.model_name} onChange={(e) => setForm({ ...form, model_name: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" required />
          </FormRow>
        </div>
        <FormRow label="System Prompt">
          <textarea value={form.system_prompt} onChange={(e) => setForm({ ...form, system_prompt: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none h-24 font-mono text-xs" />
        </FormRow>
        <FormRow label="User Prompt Template">
          <textarea value={form.user_prompt_template} onChange={(e) => setForm({ ...form, user_prompt_template: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none h-20 font-mono text-xs" />
        </FormRow>
        <div className="grid grid-cols-4 gap-3">
          <FormRow label="Temperature">
            <input type="number" step="0.1" min="0" max="2" value={form.temperature} onChange={(e) => setForm({ ...form, temperature: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Max Tokens">
            <input type="number" value={form.max_tokens} onChange={(e) => setForm({ ...form, max_tokens: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Timeout (s)">
            <input type="number" value={form.timeout_seconds} onChange={(e) => setForm({ ...form, timeout_seconds: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Max Retries">
            <input type="number" value={form.max_retries} onChange={(e) => setForm({ ...form, max_retries: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
        </div>
        <div className="grid grid-cols-3 gap-3">
          <FormRow label="Context Window (0 = default)">
            <input type="number" min="0" value={form.context_window} onChange={(e) => setForm({ ...form, context_window: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Input Token Limit (0 = unlimited)">
            <input type="number" min="0" value={form.input_token_limit} onChange={(e) => setForm({ ...form, input_token_limit: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Token Budget/hr (0 = unlimited)">
            <input type="number" min="0" value={form.token_budget} onChange={(e) => setForm({ ...form, token_budget: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
        </div>
        <FormRow label="Prompt Version">
          <input value={form.prompt_version} onChange={(e) => setForm({ ...form, prompt_version: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
        </FormRow>
        <div className="flex gap-2 pt-2">
          <button type="submit" disabled={mutation.isPending} className="rounded-md bg-brand-600 px-4 py-1.5 text-sm font-medium text-white hover:bg-brand-700 disabled:opacity-50">
            {mutation.isPending ? 'Saving…' : 'Save'}
          </button>
          <button type="button" onClick={onDone} className="rounded-md border border-surface-700 px-4 py-1.5 text-sm text-gray-400 hover:bg-surface-800">Cancel</button>
        </div>
        {mutation.isError && <p className="text-xs text-red-400">Failed to save variant</p>}
      </form>
    </Card>
  );
}

// ---------------------------------------------------------------------------
// Delete Variant Dialog
// ---------------------------------------------------------------------------

function DeleteVariantDialog({ agentId, variant, onDone }: {
  agentId: string;
  variant: AgentVariant;
  onDone: () => void;
}) {
  const mutation = useDeleteVariant(agentId, variant.id);
  const [error, setError] = useState<string | null>(null);

  function handleDelete() {
    setError(null);
    mutation.mutate(undefined, {
      onSuccess: () => onDone(),
      onError: (err) => {
        if (err instanceof ApiError && err.status === 400) {
          setError('Cannot delete the active variant. Deactivate it first or activate a different variant.');
        } else {
          setError('Failed to delete variant.');
        }
      },
    });
  }

  return (
    <Card>
      <h2 className="mb-3 text-sm font-medium text-red-400">Delete Variant</h2>
      <p className="text-sm text-gray-300 mb-1">
        Are you sure you want to delete <span className="font-medium text-gray-100">{variant.variant_name}</span>?
      </p>
      <p className="text-xs text-gray-500 mb-4">This action cannot be undone. Associated performance log entries will be unlinked.</p>
      {error && <p className="text-xs text-red-400 mb-3">{error}</p>}
      <div className="flex gap-2">
        <button onClick={handleDelete} disabled={mutation.isPending} className="rounded-md bg-red-600 px-4 py-1.5 text-sm font-medium text-white hover:bg-red-700 disabled:opacity-50">
          {mutation.isPending ? 'Deleting…' : 'Delete'}
        </button>
        <button onClick={onDone} className="rounded-md border border-surface-700 px-4 py-1.5 text-sm text-gray-400 hover:bg-surface-800">Cancel</button>
      </div>
    </Card>
  );
}

// ---------------------------------------------------------------------------
// Edit Form
// ---------------------------------------------------------------------------

function EditAgentForm({ agent, onSaved, onCancel }: { agent: Agent; onSaved: () => void; onCancel: () => void }) {
  const [form, setForm] = useState({
    name: agent.name,
    purpose: agent.purpose,
    model_provider: agent.model_provider,
    model_name: agent.model_name,
    system_prompt: agent.system_prompt,
    user_prompt_template: agent.user_prompt_template,
    prompt_version: agent.prompt_version,
    schema_version: agent.schema_version,
    temperature: agent.temperature,
    max_tokens: agent.max_tokens,
    timeout_seconds: agent.timeout_seconds,
    max_retries: agent.max_retries,
    active: agent.active,
  });

  const mutation = useMutation({
    mutationFn: (body: Record<string, unknown>) => apiPut<Agent>('query', `/api/agents/${agent.id}`, body),
    onSuccess: onSaved,
  });

  function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    mutation.mutate(form);
  }

  return (
    <Card>
      <h2 className="mb-4 text-sm font-medium text-gray-400">Edit Agent: {agent.name}</h2>
      <form onSubmit={handleSubmit} className="space-y-3">
        <FormRow label="Name">
          <input value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
        </FormRow>
        <FormRow label="Purpose">
          <textarea value={form.purpose} onChange={(e) => setForm({ ...form, purpose: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none h-16" />
        </FormRow>
        <div className="grid grid-cols-2 gap-3">
          <FormRow label="Provider">
            <input value={form.model_provider} onChange={(e) => setForm({ ...form, model_provider: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Model">
            <input value={form.model_name} onChange={(e) => setForm({ ...form, model_name: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
        </div>
        <FormRow label="System Prompt">
          <textarea value={form.system_prompt} onChange={(e) => setForm({ ...form, system_prompt: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none h-32 font-mono text-xs" />
        </FormRow>
        <FormRow label="User Prompt Template">
          <textarea value={form.user_prompt_template} onChange={(e) => setForm({ ...form, user_prompt_template: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none h-24 font-mono text-xs" />
        </FormRow>
        <div className="grid grid-cols-4 gap-3">
          <FormRow label="Temperature">
            <input type="number" step="0.1" min="0" max="2" value={form.temperature} onChange={(e) => setForm({ ...form, temperature: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Max Tokens">
            <input type="number" value={form.max_tokens} onChange={(e) => setForm({ ...form, max_tokens: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Timeout (s)">
            <input type="number" value={form.timeout_seconds} onChange={(e) => setForm({ ...form, timeout_seconds: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Max Retries">
            <input type="number" value={form.max_retries} onChange={(e) => setForm({ ...form, max_retries: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
        </div>
        <div className="flex items-center gap-2">
          <label className="flex items-center gap-2 text-sm text-gray-300">
            <input type="checkbox" checked={form.active} onChange={(e) => setForm({ ...form, active: e.target.checked })} />
            Active
          </label>
        </div>
        <div className="flex gap-2 pt-2">
          <button type="submit" disabled={mutation.isPending} className="rounded-md bg-brand-600 px-4 py-1.5 text-sm font-medium text-white hover:bg-brand-700 disabled:opacity-50">
            {mutation.isPending ? 'Saving…' : 'Save'}
          </button>
          <button type="button" onClick={onCancel} className="rounded-md border border-surface-700 px-4 py-1.5 text-sm text-gray-400 hover:bg-surface-800">Cancel</button>
        </div>
        {mutation.isError && <p className="text-xs text-red-400">Failed to save</p>}
      </form>
    </Card>
  );
}

// ---------------------------------------------------------------------------
// Create Form
// ---------------------------------------------------------------------------

function CreateAgentForm({ onCreated, onCancel }: { onCreated: (id: string) => void; onCancel: () => void }) {
  const [form, setForm] = useState({
    name: '',
    slug: '',
    purpose: '',
    model_provider: 'ollama',
    model_name: 'llama3.1:8b',
    system_prompt: '',
    user_prompt_template: '',
    temperature: 0,
    max_tokens: 32768,
    timeout_seconds: 120,
    max_retries: 2,
  });

  const mutation = useMutation({
    mutationFn: (body: Record<string, unknown>) => apiPost<{ id: string }>('query', '/api/agents', body),
    onSuccess: (data) => onCreated(data.id),
  });

  // Auto-generate slug from name
  function handleNameChange(name: string) {
    const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
    setForm({ ...form, name, slug });
  }

  function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    mutation.mutate(form);
  }

  return (
    <Card>
      <h2 className="mb-4 text-sm font-medium text-gray-400">Create New Agent</h2>
      <form onSubmit={handleSubmit} className="space-y-3">
        <div className="grid grid-cols-2 gap-3">
          <FormRow label="Name">
            <input value={form.name} onChange={(e) => handleNameChange(e.target.value)} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" required />
          </FormRow>
          <FormRow label="Slug">
            <input value={form.slug} onChange={(e) => setForm({ ...form, slug: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none font-mono" required />
          </FormRow>
        </div>
        <FormRow label="Purpose">
          <textarea value={form.purpose} onChange={(e) => setForm({ ...form, purpose: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none h-16" />
        </FormRow>
        <div className="grid grid-cols-2 gap-3">
          <FormRow label="Provider">
            <input value={form.model_provider} onChange={(e) => setForm({ ...form, model_provider: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Model">
            <input value={form.model_name} onChange={(e) => setForm({ ...form, model_name: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
        </div>
        <FormRow label="System Prompt">
          <textarea value={form.system_prompt} onChange={(e) => setForm({ ...form, system_prompt: e.target.value })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none h-32 font-mono text-xs" />
        </FormRow>
        <div className="grid grid-cols-4 gap-3">
          <FormRow label="Temperature">
            <input type="number" step="0.1" min="0" max="2" value={form.temperature} onChange={(e) => setForm({ ...form, temperature: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Max Tokens">
            <input type="number" value={form.max_tokens} onChange={(e) => setForm({ ...form, max_tokens: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Timeout (s)">
            <input type="number" value={form.timeout_seconds} onChange={(e) => setForm({ ...form, timeout_seconds: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
          <FormRow label="Max Retries">
            <input type="number" value={form.max_retries} onChange={(e) => setForm({ ...form, max_retries: Number(e.target.value) })} className="w-full rounded-md border border-surface-700 bg-surface-950 px-2 py-1.5 text-sm text-gray-200 focus:border-brand-500 focus:outline-none" />
          </FormRow>
        </div>
        <div className="flex gap-2 pt-2">
          <button type="submit" disabled={mutation.isPending} className="rounded-md bg-brand-600 px-4 py-1.5 text-sm font-medium text-white hover:bg-brand-700 disabled:opacity-50">
            {mutation.isPending ? 'Creating…' : 'Create'}
          </button>
          <button type="button" onClick={onCancel} className="rounded-md border border-surface-700 px-4 py-1.5 text-sm text-gray-400 hover:bg-surface-800">Cancel</button>
        </div>
        {mutation.isError && <p className="text-xs text-red-400">Failed to create agent</p>}
      </form>
    </Card>
  );
}

// ---------------------------------------------------------------------------
// Shared Components
// ---------------------------------------------------------------------------

function FormRow({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <div>
      <label className="mb-1 block text-xs text-gray-500">{label}</label>
      {children}
    </div>
  );
}

function MetricCard({ label, value, color = 'text-gray-100' }: { label: string; value: string; color?: string }) {
  return (
    <div className="text-center">
      <div className={`text-lg font-bold ${color}`}>{value}</div>
      <div className="text-xs text-gray-500">{label}</div>
    </div>
  );
}
