/**
 * ErrorMessage - Error display components for web
 *
 * Components:
 * - ErrorMessage: Inline error with optional retry
 * - FullScreenError: Full page error state
 * - ErrorToast: Dismissible error notification
 * - FieldError: Form field validation error
 *
 * Features:
 * - Multiple severity levels
 * - Retry and dismiss actions
 * - Accessible ARIA labels
 * - Tailwind CSS styling
 */

import { cn } from '@/lib/utils';

// Error severity types
export type ErrorSeverity = 'error' | 'warning' | 'info';

/**
 * ErrorMessage - Inline error message with icon and optional actions
 *
 * @example
 * ```tsx
 * <ErrorMessage
 *   message="Failed to load data"
 *   onRetry={() => refetch()}
 * />
 * ```
 */
interface ErrorMessageProps {
  message: string;
  severity?: ErrorSeverity;
  onRetry?: () => void;
  onDismiss?: () => void;
  className?: string;
}

const severityStyles = {
  error: {
    container: 'bg-red-50 border-red-200 text-red-800',
    icon: 'text-red-500',
    button: 'text-red-600 hover:text-red-700 hover:bg-red-100',
  },
  warning: {
    container: 'bg-yellow-50 border-yellow-200 text-yellow-800',
    icon: 'text-yellow-500',
    button: 'text-yellow-600 hover:text-yellow-700 hover:bg-yellow-100',
  },
  info: {
    container: 'bg-blue-50 border-blue-200 text-blue-800',
    icon: 'text-blue-500',
    button: 'text-blue-600 hover:text-blue-700 hover:bg-blue-100',
  },
};

export function ErrorMessage({
  message,
  severity = 'error',
  onRetry,
  onDismiss,
  className,
}: ErrorMessageProps) {
  const styles = severityStyles[severity];

  return (
    <div
      className={cn(
        'flex items-start gap-3 rounded-lg border p-4',
        styles.container,
        className
      )}
      role="alert"
      aria-live="polite"
    >
      {/* Icon */}
      <svg
        className={cn('h-5 w-5 flex-shrink-0', styles.icon)}
        fill="none"
        stroke="currentColor"
        viewBox="0 0 24 24"
        aria-hidden="true"
      >
        <path
          strokeLinecap="round"
          strokeLinejoin="round"
          strokeWidth={2}
          d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
        />
      </svg>

      {/* Message */}
      <div className="flex-1 text-sm">
        <p>{message}</p>
      </div>

      {/* Actions */}
      <div className="flex items-center gap-2">
        {onRetry && (
          <button
            onClick={onRetry}
            className={cn(
              'flex items-center gap-1 rounded px-2 py-1 text-xs font-medium transition-colors',
              styles.button
            )}
          >
            <svg
              className="h-4 w-4"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
              />
            </svg>
            Retry
          </button>
        )}
        {onDismiss && (
          <button
            onClick={onDismiss}
            className={cn(
              'rounded p-1 transition-colors',
              styles.button
            )}
            aria-label="Dismiss"
          >
            <svg
              className="h-4 w-4"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M6 18L18 6M6 6l12 12"
              />
            </svg>
          </button>
        )}
      </div>
    </div>
  );
}

/**
 * FullScreenError - Full page error state with icon and actions
 *
 * @example
 * ```tsx
 * if (error) {
 *   return (
 *     <FullScreenError
 *       title="Failed to Load"
 *       message={error.message}
 *       onRetry={() => refetch()}
 *     />
 *   );
 * }
 * ```
 */
interface FullScreenErrorProps {
  title?: string;
  message: string;
  icon?: 'error' | 'offline' | 'notFound';
  onRetry?: () => void;
  onBack?: () => void;
  retryLabel?: string;
  backLabel?: string;
}

const iconPaths = {
  error: 'M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z',
  offline: 'M3 15a4 4 0 004 4h9a5 5 0 10-.1-9.999 5.002 5.002 0 10-9.78 2.096A4.001 4.001 0 003 15z',
  notFound: 'M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M12 12h.01M12 12h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z',
};

export function FullScreenError({
  title = 'Something went wrong',
  message,
  icon = 'error',
  onRetry,
  onBack,
  retryLabel = 'Try Again',
  backLabel = 'Go Back',
}: FullScreenErrorProps) {
  return (
    <div className="flex min-h-[400px] flex-col items-center justify-center p-8 text-center">
      {/* Icon */}
      <div className="mb-6 flex h-20 w-20 items-center justify-center rounded-full bg-red-100">
        <svg
          className="h-10 w-10 text-red-600"
          fill="none"
          stroke="currentColor"
          viewBox="0 0 24 24"
        >
          <path
            strokeLinecap="round"
            strokeLinejoin="round"
            strokeWidth={2}
            d={iconPaths[icon]}
          />
        </svg>
      </div>

      {/* Title */}
      <h2 className="mb-2 text-2xl font-semibold text-slate-900">
        {title}
      </h2>

      {/* Message */}
      <p className="mb-8 max-w-md text-slate-600">
        {message}
      </p>

      {/* Actions */}
      <div className="flex gap-3">
        {onRetry && (
          <button
            onClick={onRetry}
            className="flex items-center gap-2 rounded-lg bg-blue-600 px-6 py-3 text-sm font-medium text-white shadow-sm transition-colors hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
          >
            <svg
              className="h-4 w-4"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
              />
            </svg>
            {retryLabel}
          </button>
        )}
        {onBack && (
          <button
            onClick={onBack}
            className="rounded-lg border border-slate-300 bg-white px-6 py-3 text-sm font-medium text-slate-700 shadow-sm transition-colors hover:bg-slate-50 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
          >
            {backLabel}
          </button>
        )}
      </div>
    </div>
  );
}

/**
 * FieldError - Inline form field validation error
 *
 * @example
 * ```tsx
 * <input type="email" aria-invalid={!!error} />
 * {error && <FieldError message={error} />}
 * ```
 */
interface FieldErrorProps {
  message: string;
  className?: string;
}

export function FieldError({ message, className }: FieldErrorProps) {
  return (
    <p
      className={cn('mt-1 flex items-center gap-1 text-sm text-red-600', className)}
      role="alert"
    >
      <svg
        className="h-4 w-4 flex-shrink-0"
        fill="none"
        stroke="currentColor"
        viewBox="0 0 24 24"
      >
        <path
          strokeLinecap="round"
          strokeLinejoin="round"
          strokeWidth={2}
          d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
        />
      </svg>
      <span>{message}</span>
    </p>
  );
}

/**
 * ErrorBoundary fallback component
 *
 * @example
 * ```tsx
 * <ErrorBoundary fallback={<ErrorBoundaryFallback />}>
 *   <App />
 * </ErrorBoundary>
 * ```
 */
interface ErrorBoundaryFallbackProps {
  error?: Error;
  resetError?: () => void;
}

export function ErrorBoundaryFallback({
  error,
  resetError,
}: ErrorBoundaryFallbackProps) {
  return (
    <FullScreenError
      title="Application Error"
      message={
        error?.message ||
        'An unexpected error occurred. Please refresh the page.'
      }
      onRetry={resetError}
      retryLabel="Reload Page"
    />
  );
}

/**
 * EmptyState - Component for empty data states (not strictly an error)
 *
 * @example
 * ```tsx
 * {items.length === 0 && (
 *   <EmptyState
 *     title="No items found"
 *     message="Get started by adding your first item"
 *     actionLabel="Add Item"
 *     onAction={() => setShowModal(true)}
 *   />
 * )}
 * ```
 */
interface EmptyStateProps {
  title: string;
  message?: string;
  icon?: React.ReactNode;
  actionLabel?: string;
  onAction?: () => void;
  className?: string;
}

export function EmptyState({
  title,
  message,
  icon,
  actionLabel,
  onAction,
  className,
}: EmptyStateProps) {
  return (
    <div
      className={cn(
        'flex flex-col items-center justify-center p-8 text-center',
        className
      )}
    >
      {/* Icon */}
      {icon && (
        <div className="mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-slate-100">
          {icon}
        </div>
      )}

      {/* Title */}
      <h3 className="mb-2 text-lg font-semibold text-slate-900">
        {title}
      </h3>

      {/* Message */}
      {message && (
        <p className="mb-6 max-w-sm text-sm text-slate-600">
          {message}
        </p>
      )}

      {/* Action */}
      {actionLabel && onAction && (
        <button
          onClick={onAction}
          className="rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
        >
          {actionLabel}
        </button>
      )}
    </div>
  );
}
