import { type ReactNode } from 'react';
import { motion } from 'framer-motion';
import {
  FileSearch,
  Inbox,
  AlertCircle,
  Search,
  Plus,
  type LucideIcon
} from 'lucide-react';
import { Button } from '@components/atoms/Button';
import { cn } from '@utils/cn';

export type EmptyStateVariant = 'default' | 'search' | 'error' | 'no-data' | 'custom';

export interface EmptyStateAction {
  label: string;
  onClick: () => void;
  variant?: 'primary' | 'secondary' | 'outline';
  icon?: ReactNode;
}

export interface EmptyStateProps {
  variant?: EmptyStateVariant;
  icon?: ReactNode;
  title: string;
  description?: string;
  primaryAction?: EmptyStateAction;
  secondaryAction?: EmptyStateAction;
  className?: string;
  compact?: boolean;
  animated?: boolean;
}

const variantIcons: Record<Exclude<EmptyStateVariant, 'custom'>, LucideIcon> = {
  default: Inbox,
  search: Search,
  error: AlertCircle,
  'no-data': FileSearch,
};

const variantColors: Record<Exclude<EmptyStateVariant, 'custom'>, string> = {
  default: 'text-gray-400',
  search: 'text-primary-400',
  error: 'text-danger-400',
  'no-data': 'text-gray-400',
};

export function EmptyState({
  variant = 'default',
  icon,
  title,
  description,
  primaryAction,
  secondaryAction,
  className,
  compact = false,
  animated = true,
}: EmptyStateProps) {
  const IconComponent = variant !== 'custom' ? variantIcons[variant] : null;
  const iconColor = variant !== 'custom' ? variantColors[variant] : 'text-gray-400';

  const content = (
    <div
      className={cn(
        'flex flex-col items-center justify-center text-center',
        compact ? 'py-8 px-4' : 'py-16 px-8',
        className
      )}
    >
      {/* Icon */}
      <div
        className={cn(
          'flex items-center justify-center rounded-full bg-gray-100',
          compact ? 'h-12 w-12 mb-3' : 'h-16 w-16 mb-4'
        )}
      >
        {icon || (IconComponent && (
          <IconComponent className={cn(compact ? 'h-6 w-6' : 'h-8 w-8', iconColor)} />
        ))}
      </div>

      {/* Title */}
      <h3
        className={cn(
          'font-semibold text-gray-900',
          compact ? 'text-base mb-1' : 'text-lg mb-2'
        )}
      >
        {title}
      </h3>

      {/* Description */}
      {description && (
        <p
          className={cn(
            'text-gray-500 max-w-sm',
            compact ? 'text-sm mb-4' : 'text-base mb-6'
          )}
        >
          {description}
        </p>
      )}

      {/* Actions */}
      {(primaryAction || secondaryAction) && (
        <div className={cn('flex items-center gap-3', compact ? 'mt-2' : 'mt-4')}>
          {primaryAction && (
            <Button
              variant={primaryAction.variant || 'primary'}
              size={compact ? 'sm' : 'md'}
              onClick={primaryAction.onClick}
            >
              {primaryAction.icon}
              {primaryAction.label}
            </Button>
          )}
          {secondaryAction && (
            <Button
              variant={secondaryAction.variant || 'outline'}
              size={compact ? 'sm' : 'md'}
              onClick={secondaryAction.onClick}
            >
              {secondaryAction.icon}
              {secondaryAction.label}
            </Button>
          )}
        </div>
      )}
    </div>
  );

  if (animated) {
    return (
      <motion.div
        initial={{ opacity: 0, y: 10 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.3 }}
      >
        {content}
      </motion.div>
    );
  }

  return content;
}

// Preset Empty States for common scenarios

export interface NoResultsEmptyStateProps {
  searchTerm?: string;
  onClearSearch?: () => void;
  className?: string;
}

export function NoResultsEmptyState({
  searchTerm,
  onClearSearch,
  className,
}: NoResultsEmptyStateProps) {
  return (
    <EmptyState
      variant="search"
      title="No se encontraron resultados"
      description={
        searchTerm
          ? `No hay resultados para "${searchTerm}". Intenta con otros términos de búsqueda.`
          : 'No se encontraron elementos que coincidan con tu búsqueda.'
      }
      primaryAction={
        onClearSearch
          ? {
              label: 'Limpiar búsqueda',
              onClick: onClearSearch,
              variant: 'outline',
            }
          : undefined
      }
      className={className}
    />
  );
}

export interface NoDataEmptyStateProps {
  entityName: string;
  onCreateNew?: () => void;
  className?: string;
}

export function NoDataEmptyState({
  entityName,
  onCreateNew,
  className,
}: NoDataEmptyStateProps) {
  return (
    <EmptyState
      variant="no-data"
      title={`No hay ${entityName}`}
      description={`Aún no se han creado ${entityName}. Comienza agregando el primero.`}
      primaryAction={
        onCreateNew
          ? {
              label: `Crear ${entityName.slice(0, -1)}`,
              onClick: onCreateNew,
              icon: <Plus className="h-4 w-4 mr-1" />,
            }
          : undefined
      }
      className={className}
    />
  );
}

export interface ErrorEmptyStateProps {
  title?: string;
  description?: string;
  onRetry?: () => void;
  className?: string;
}

export function ErrorEmptyState({
  title = 'Ocurrió un error',
  description = 'No pudimos cargar la información. Por favor intenta de nuevo.',
  onRetry,
  className,
}: ErrorEmptyStateProps) {
  return (
    <EmptyState
      variant="error"
      title={title}
      description={description}
      primaryAction={
        onRetry
          ? {
              label: 'Reintentar',
              onClick: onRetry,
              variant: 'primary',
            }
          : undefined
      }
      className={className}
    />
  );
}

export interface ComingSoonEmptyStateProps {
  featureName: string;
  description?: string;
  className?: string;
}

export function ComingSoonEmptyState({
  featureName,
  description,
  className,
}: ComingSoonEmptyStateProps) {
  return (
    <EmptyState
      variant="default"
      title={`${featureName} próximamente`}
      description={description || 'Esta funcionalidad estará disponible en una próxima actualización.'}
      className={className}
    />
  );
}
