import { Code, List } from 'lucide-react';

import { useState } from 'react';

import { Badge } from '@/Components/ui/badge';
import { Button } from '@/Components/ui/button';
import { cn } from '@/lib/utils';

interface MetadataViewerProps {
  metadata: Record<string, unknown>;
}

function formatValue(value: unknown): React.ReactNode {
  if (value === null) {
    return <span className="text-muted-foreground italic">null</span>;
  }
  if (value === undefined) {
    return <span className="text-muted-foreground italic">undefined</span>;
  }
  if (typeof value === 'boolean') {
    return (
      <Badge variant={value ? 'default' : 'secondary'} className="text-xs">
        {value ? 'true' : 'false'}
      </Badge>
    );
  }
  if (typeof value === 'number') {
    return <span className="font-mono text-sm">{value}</span>;
  }
  if (typeof value === 'string') {
    if (value.length === 0) {
      return <span className="text-muted-foreground italic">empty string</span>;
    }
    return <span className="text-sm break-all">{value}</span>;
  }
  if (Array.isArray(value)) {
    if (value.length === 0) {
      return <span className="text-muted-foreground italic">[]</span>;
    }
    return (
      <div className="space-y-1">
        {value.map((item, i) => (
          <div key={i} className="text-sm">
            {typeof item === 'object' && item !== null ? (
              <pre className="bg-muted/50 rounded p-2 text-xs overflow-auto">
                {JSON.stringify(item, null, 2)}
              </pre>
            ) : (
              formatValue(item)
            )}
          </div>
        ))}
      </div>
    );
  }
  if (typeof value === 'object') {
    return (
      <pre className="bg-muted/50 rounded p-2 text-xs overflow-auto">
        {JSON.stringify(value, null, 2)}
      </pre>
    );
  }
  return <span className="text-sm">{String(value)}</span>;
}

export function MetadataViewer({ metadata }: MetadataViewerProps) {
  const [showRaw, setShowRaw] = useState(false);
  const entries = Object.entries(metadata);

  if (entries.length === 0) {
    return null;
  }

  return (
    <div>
      <div className="flex items-center justify-between mb-2">
        <p className="text-sm text-muted-foreground">Metadata</p>
        <Button
          variant="ghost"
          size="sm"
          className="h-7 gap-1.5 text-xs"
          onClick={() => setShowRaw(!showRaw)}
          aria-label={showRaw ? 'Show formatted metadata' : 'Show raw JSON'}
        >
          {showRaw ? (
            <>
              <List className="h-3.5 w-3.5" />
              Formatted
            </>
          ) : (
            <>
              <Code className="h-3.5 w-3.5" />
              Raw JSON
            </>
          )}
        </Button>
      </div>

      {showRaw ? (
        <pre className="bg-muted p-4 rounded-lg overflow-auto text-sm max-h-96">
          {JSON.stringify(metadata, null, 2)}
        </pre>
      ) : (
        <dl
          className={cn(
            'grid gap-x-4 gap-y-3 rounded-lg border p-4',
            entries.length > 4 ? 'md:grid-cols-[auto_1fr_auto_1fr]' : 'grid-cols-[auto_1fr]',
          )}
        >
          {entries.map(([key, value]) => (
            <div key={key} className="contents">
              <dt className="text-sm font-medium text-muted-foreground whitespace-nowrap">
                {key.replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase())}
              </dt>
              <dd className="text-sm min-w-0">{formatValue(value)}</dd>
            </div>
          ))}
        </dl>
      )}
    </div>
  );
}
