import { useEffect, useState, useCallback } from 'react';
import { cn } from '@/lib/utils';
import { X, Copy } from 'lucide-react';
import { codeToHtml } from 'shiki';

interface CaptureDrawerProps {
  requestId: number;
  providerId: string;
  onClose: () => void;
}

interface CaptureData {
  id: number;
  providerId: string;
  timestamp: string;
  model: string;
  requestHeaders: Record<string, string>;
  requestBody: string;
  responseHeaders: Record<string, string>;
  responseBody: string;
  durationMs: number;
  sizeBytes: number;
}

export function CaptureDrawer({ requestId, providerId, onClose }: CaptureDrawerProps) {
  const [capture, setCapture] = useState<CaptureData | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [activePanel, setActivePanel] = useState<'req' | 'resp'>('req');
  const [highlightedReq, setHighlightedReq] = useState('');
  const [highlightedResp, setHighlightedResp] = useState('');

  useEffect(() => {
    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === 'Escape') onClose();
    };
    document.addEventListener('keydown', handleKeyDown);
    return () => document.removeEventListener('keydown', handleKeyDown);
  }, [onClose]);

  useEffect(() => {
    let cancelled = false;
    async function fetchCapture() {
      try {
        const res = await fetch(`/api/control/capture/${providerId}/${requestId}`);
        if (!res.ok) {
          if (!cancelled) {
            setError(res.status === 404 ? 'Capture not found' : `Fetch failed: ${res.status}`);
            setLoading(false);
          }
          return;
        }
        const data = await res.json();
        if (!cancelled) {
          setCapture(data);
          setLoading(false);
        }
      } catch (err) {
        if (!cancelled) {
          setError((err as Error).message);
          setLoading(false);
        }
      }
    }
    fetchCapture();
    return () => { cancelled = true; };
  }, [requestId, providerId]);

  useEffect(() => {
    if (!capture) return;
    const reqBody = capture.requestBody || '{}';
    const respBody = capture.responseBody || '{}';
    let cancelled = false;
    async function highlight() {
      try {
        const reqHtml = await codeToHtml(reqBody, {
          lang: 'json',
          theme: 'github-dark',
        });
        const respHtml = await codeToHtml(respBody, {
          lang: 'json',
          theme: 'github-dark',
        });
        if (!cancelled) {
          setHighlightedReq(reqHtml);
          setHighlightedResp(respHtml);
        }
      } catch {
        // Fallback to plain text
      }
    }
    highlight();
    return () => { cancelled = true; };
  }, [capture]);

  const copyToClipboard = useCallback((text: string) => {
    navigator.clipboard.writeText(text).catch(() => {});
  }, []);

  if (loading) {
    return (
      <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50" onClick={onClose}>
        <div
          className="bg-background border border-border rounded-lg p-6 w-[80vw] max-w-4xl max-h-[80vh]"
          role="dialog"
          aria-modal="true"
          onClick={(event) => event.stopPropagation()}
        >
          <div className="flex items-center justify-between mb-4">
            <h2 className="text-lg font-semibold">Loading capture...</h2>
            <button type="button" onClick={onClose} className="text-muted-foreground hover:text-foreground" aria-label="Close capture">
              <X className="size-4" />
            </button>
          </div>
          <div className="flex items-center justify-center py-8">
            <div className="animate-spin size-5 border-2 border-foreground/30 border-t-foreground rounded-full" />
          </div>
        </div>
      </div>
    );
  }

  if (error) {
    return (
      <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50" onClick={onClose}>
        <div
          className="bg-background border border-border rounded-lg p-6 w-[80vw] max-w-4xl max-h-[80vh]"
          role="dialog"
          aria-modal="true"
          onClick={(event) => event.stopPropagation()}
        >
          <div className="flex items-center justify-between mb-4">
            <h2 className="text-lg font-semibold text-red-400">Capture Error</h2>
            <button type="button" onClick={onClose} className="text-muted-foreground hover:text-foreground" aria-label="Close capture">
              <X className="size-4" />
            </button>
          </div>
          <p className="text-sm text-muted-foreground">{error}</p>
        </div>
      </div>
    );
  }

  if (!capture) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50" onClick={onClose}>
      <div
        className="bg-background border border-border rounded-lg w-[80vw] max-w-4xl max-h-[80vh] flex flex-col"
        role="dialog"
        aria-modal="true"
        onClick={(event) => event.stopPropagation()}
      >
        {/* Header */}
        <div className="flex items-center justify-between px-4 py-3 border-b border-border shrink-0">
          <div>
            <h2 className="text-lg font-semibold">Request Capture</h2>
            <p className="text-xs text-muted-foreground">
              {capture.model} &middot; {capture.durationMs}ms &middot; {(capture.sizeBytes / 1024).toFixed(1)}KB
            </p>
          </div>
          <div className="flex items-center gap-2">
            {/* C3: "Open in Playground" was a dead button (no handler); hidden until wired. */}
            <button type="button" onClick={onClose} className="text-muted-foreground hover:text-foreground" aria-label="Close capture">
              <X className="size-4" />
            </button>
          </div>
        </div>

        {/* Headers table */}
        <div className="px-4 py-2 border-b border-border shrink-0">
          <div className="grid grid-cols-2 gap-4">
            <div>
              <h3 className="text-xs font-medium text-muted-foreground mb-1">Request Headers</h3>
              <HeadersTable headers={capture.requestHeaders} />
            </div>
            <div>
              <h3 className="text-xs font-medium text-muted-foreground mb-1">Response Headers</h3>
              <HeadersTable headers={capture.responseHeaders} />
            </div>
          </div>
        </div>

        {/* Body panels */}
        <div className="flex-1 min-h-0 flex flex-col">
          <div className="flex gap-1 px-4 pt-2 shrink-0">
            <button
              type="button"
              onClick={() => setActivePanel('req')}
              className={cn(
                'px-3 py-1 text-xs rounded-t transition-colors',
                activePanel === 'req'
                  ? 'bg-muted/50 text-foreground font-medium'
                  : 'text-muted-foreground hover:text-foreground',
              )}
            >
              Request Body
            </button>
            <button
              type="button"
              onClick={() => setActivePanel('resp')}
              className={cn(
                'px-3 py-1 text-xs rounded-t transition-colors',
                activePanel === 'resp'
                  ? 'bg-muted/50 text-foreground font-medium'
                  : 'text-muted-foreground hover:text-foreground',
              )}
            >
              Response Body
            </button>
            <div className="flex-1" />
            <button
              type="button"
              onClick={() => copyToClipboard(activePanel === 'req' ? capture.requestBody : capture.responseBody)}
              className="px-2 py-1 text-xs text-muted-foreground hover:text-foreground transition-colors"
            >
              <Copy className="size-3" />
            </button>
          </div>
          <div className="flex-1 min-h-0 overflow-auto p-4">
            <div
              className="text-[11px] font-mono"
              dangerouslySetInnerHTML={{
                __html: activePanel === 'req' ? highlightedReq : highlightedResp,
              }}
            />
          </div>
        </div>
      </div>
    </div>
  );
}

function HeadersTable({ headers }: { headers: Record<string, string> }) {
  const entries = Object.entries(headers);
  if (entries.length === 0) {
    return <p className="text-[11px] text-muted-foreground">No headers</p>;
  }
  return (
    <div className="space-y-0.5">
      {entries.slice(0, 8).map(([key, value]) => (
        <div key={key} className="flex gap-2 text-[10px] font-mono">
          <span className="text-muted-foreground shrink-0 truncate max-w-[120px]">{key}</span>
          <span className="text-foreground/70 truncate">{value}</span>
        </div>
      ))}
      {entries.length > 8 && (
        <p className="text-[10px] text-muted-foreground">+{entries.length - 8} more</p>
      )}
    </div>
  );
}
