/**
 * ConnectionStatus Component
 *
 * Displays the current SSE connection state with visual indicators
 * and reconnection controls.
 */

'use client';

import { RefreshCw, Wifi, WifiOff, Loader2, AlertCircle } from 'lucide-react';
import { cn } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import type { ConnectionState, SSEError } from '@/lib/types/events';

// ============================================================================
// Types
// ============================================================================

interface ConnectionStatusProps {
  /** Current connection state */
  state: ConnectionState;
  /** Current error, if any */
  error?: SSEError | null;
  /** Current retry attempt count */
  retryCount?: number;
  /** Callback to trigger reconnection */
  onReconnect?: () => void;
  /** Whether to show the reconnect button (default: true) */
  showReconnectButton?: boolean;
  /** Whether to show error details (default: true) */
  showErrorDetails?: boolean;
  /** Additional CSS classes */
  className?: string;
  /** Compact mode - smaller display */
  compact?: boolean;
}

// ============================================================================
// Helper Functions
// ============================================================================

function getStatusConfig(state: ConnectionState) {
  switch (state) {
    case 'connected':
      return {
        icon: Wifi,
        label: 'Connected',
        variant: 'default' as const,
        iconClassName: 'text-green-500',
        description: 'Receiving real-time updates',
      };
    case 'connecting':
      return {
        icon: Loader2,
        label: 'Connecting',
        variant: 'secondary' as const,
        iconClassName: 'animate-spin text-muted-foreground',
        description: 'Establishing connection...',
      };
    case 'disconnected':
      return {
        icon: WifiOff,
        label: 'Disconnected',
        variant: 'outline' as const,
        iconClassName: 'text-muted-foreground',
        description: 'Not connected to server',
      };
    case 'error':
      return {
        icon: AlertCircle,
        label: 'Connection Error',
        variant: 'destructive' as const,
        iconClassName: 'text-destructive',
        description: 'Failed to connect',
      };
    default:
      return {
        icon: WifiOff,
        label: 'Unknown',
        variant: 'outline' as const,
        iconClassName: 'text-muted-foreground',
        description: 'Unknown state',
      };
  }
}

// ============================================================================
// Component
// ============================================================================

/**
 * ConnectionStatus - Display SSE connection state
 *
 * Features:
 * - Visual state indicator with icon
 * - Connection state badge
 * - Error message display
 * - Retry count display
 * - Reconnect button
 * - Compact mode for inline use
 *
 * @example
 * ```tsx
 * <ConnectionStatus
 *   state={connectionState}
 *   error={error}
 *   retryCount={retryCount}
 *   onReconnect={reconnect}
 * />
 * ```
 */
export function ConnectionStatus({
  state,
  error,
  retryCount = 0,
  onReconnect,
  showReconnectButton = true,
  showErrorDetails = true,
  className,
  compact = false,
}: ConnectionStatusProps) {
  const { icon: Icon, label, variant, iconClassName, description } = getStatusConfig(state);

  const canReconnect = state === 'disconnected' || state === 'error';
  const isRetrying = state === 'connecting' && retryCount > 0;

  if (compact) {
    return (
      <div className={cn('flex items-center gap-2', className)}>
        <Icon className={cn('h-4 w-4', iconClassName)} aria-hidden="true" />
        <Badge variant={variant} className="text-xs">
          {label}
          {isRetrying && ` (retry ${retryCount})`}
        </Badge>
        {showReconnectButton && canReconnect && onReconnect && (
          <Button
            variant="ghost"
            size="sm"
            onClick={onReconnect}
            className="h-6 w-6 p-0"
            aria-label="Reconnect"
          >
            <RefreshCw className="h-3 w-3" />
          </Button>
        )}
      </div>
    );
  }

  return (
    <div
      className={cn(
        'flex flex-col gap-3 rounded-lg border p-4',
        state === 'error' && 'border-destructive bg-destructive/5',
        state === 'connected' && 'border-green-200 bg-green-50 dark:border-green-900 dark:bg-green-950',
        className
      )}
      role="status"
      aria-live="polite"
    >
      {/* Header with icon and status */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <div
            className={cn(
              'flex h-10 w-10 items-center justify-center rounded-full',
              state === 'connected' && 'bg-green-100 dark:bg-green-900',
              state === 'connecting' && 'bg-muted',
              state === 'disconnected' && 'bg-muted',
              state === 'error' && 'bg-destructive/10'
            )}
          >
            <Icon className={cn('h-5 w-5', iconClassName)} aria-hidden="true" />
          </div>
          <div>
            <div className="flex items-center gap-2">
              <span className="font-medium">{label}</span>
              {isRetrying && (
                <Badge variant="secondary" className="text-xs">
                  Retry {retryCount}
                </Badge>
              )}
            </div>
            <p className="text-sm text-muted-foreground">{description}</p>
          </div>
        </div>

        {/* Reconnect button */}
        {showReconnectButton && canReconnect && onReconnect && (
          <Button variant="outline" size="sm" onClick={onReconnect} className="gap-2">
            <RefreshCw className="h-4 w-4" />
            Reconnect
          </Button>
        )}
      </div>

      {/* Error details */}
      {showErrorDetails && error && (
        <div className="rounded-md bg-destructive/10 p-3 text-sm">
          <p className="font-medium text-destructive">Error: {error.message}</p>
          {error.code && (
            <p className="mt-1 text-muted-foreground">
              Code: {error.code}
            </p>
          )}
          <p className="mt-1 text-xs text-muted-foreground">
            {new Date(error.timestamp).toLocaleTimeString()}
          </p>
        </div>
      )}
    </div>
  );
}
