import React from 'react';
import { Stack, Text, Button, Center, Box } from '@mantine/core';
import {
  IconDatabase,
  IconUsers,
  IconApps,
  IconFunction,
  IconKey,
  IconSearch,
  IconFilter,
  IconPlus,
  IconRefresh,
  IconAlertCircle,
  TablerIconsProps,
} from '@tabler/icons-react';

export type EmptyStateVariant = 
  | 'no-data'
  | 'no-results' 
  | 'error'
  | 'loading-failed'
  | 'access-denied'
  | 'coming-soon';

export type EmptyStateContext =
  | 'users'
  | 'applications' 
  | 'functions'
  | 'tokens'
  | 'executions'
  | 'permissions'
  | 'audit'
  | 'generic';

export interface EmptyStateAction {
  label: string;
  onClick: () => void;
  variant?: 'filled' | 'light' | 'outline';
  color?: string;
  leftSection?: React.ReactNode;
}

export interface EmptyStateProps {
  variant?: EmptyStateVariant;
  context?: EmptyStateContext;
  title?: string;
  message?: string;
  icon?: React.ComponentType<TablerIconsProps>;
  iconSize?: number;
  iconColor?: string;
  actions?: EmptyStateAction[];
  height?: number | string;
}

// Default icons for each context
const CONTEXT_ICONS: Record<EmptyStateContext, React.ComponentType<TablerIconsProps>> = {
  users: IconUsers,
  applications: IconApps,
  functions: IconFunction,
  tokens: IconKey,
  executions: IconFunction,
  permissions: IconKey,
  audit: IconDatabase,
  generic: IconDatabase,
};

// Default messages based on variant and context
const getDefaultContent = (variant: EmptyStateVariant, context: EmptyStateContext) => {
  const contextNames: Record<EmptyStateContext, string> = {
    users: 'users',
    applications: 'applications',
    functions: 'functions',
    tokens: 'tokens',
    executions: 'executions',
    permissions: 'permissions',
    audit: 'audit events',
    generic: 'items',
  };

  const contextName = contextNames[context];
  const capitalizedContext = contextName.charAt(0).toUpperCase() + contextName.slice(1);

  switch (variant) {
    case 'no-data':
      return {
        title: `No ${contextName} found`,
        message: `You haven't created any ${contextName} yet. Get started by adding your first ${contextName.slice(0, -1)}.`,
      };
      
    case 'no-results':
      return {
        title: 'No matching results',
        message: `No ${contextName} match your current filters or search criteria. Try adjusting your search terms or clearing filters.`,
      };
      
    case 'error':
      return {
        title: 'Something went wrong',
        message: `We couldn't load your ${contextName}. Please try again or contact support if the problem persists.`,
      };
      
    case 'loading-failed':
      return {
        title: 'Failed to load data',
        message: `There was a problem loading ${contextName}. Check your connection and try again.`,
      };
      
    case 'access-denied':
      return {
        title: 'Access denied',
        message: `You don't have permission to view ${contextName}. Contact your administrator if you need access.`,
      };
      
    case 'coming-soon':
      return {
        title: 'Coming soon',
        message: `${capitalizedContext} functionality is being developed. Check back soon for updates.`,
      };
      
    default:
      return {
        title: `No ${contextName}`,
        message: `There are no ${contextName} to display.`,
      };
  }
};

// Default actions based on variant and context
const getDefaultActions = (
  variant: EmptyStateVariant,
  context: EmptyStateContext,
  onAdd?: () => void,
  onRefresh?: () => void,
  onClearFilters?: () => void
): EmptyStateAction[] => {
  const actions: EmptyStateAction[] = [];

  switch (variant) {
    case 'no-data':
      if (onAdd) {
        const contextActions: Record<EmptyStateContext, EmptyStateAction> = {
          users: {
            label: 'Add User',
            onClick: onAdd,
            variant: 'filled',
            leftSection: <IconPlus size={16} />,
          },
          applications: {
            label: 'Create Application',
            onClick: onAdd,
            variant: 'filled',
            leftSection: <IconPlus size={16} />,
          },
          functions: {
            label: 'Create Function',
            onClick: onAdd,
            variant: 'filled',
            leftSection: <IconPlus size={16} />,
          },
          tokens: {
            label: 'Generate Token',
            onClick: onAdd,
            variant: 'filled',
            leftSection: <IconPlus size={16} />,
          },
          executions: {
            label: 'Run Function',
            onClick: onAdd,
            variant: 'filled',
            leftSection: <IconFunction size={16} />,
          },
          permissions: {
            label: 'Add Permission',
            onClick: onAdd,
            variant: 'filled',
            leftSection: <IconPlus size={16} />,
          },
          audit: {
            label: 'Refresh',
            onClick: onAdd,
            variant: 'light',
            leftSection: <IconRefresh size={16} />,
          },
          generic: {
            label: 'Add New',
            onClick: onAdd,
            variant: 'filled',
            leftSection: <IconPlus size={16} />,
          },
        };
        actions.push(contextActions[context]);
      }
      break;
      
    case 'no-results':
      if (onClearFilters) {
        actions.push({
          label: 'Clear Filters',
          onClick: onClearFilters,
          variant: 'light',
          leftSection: <IconFilter size={16} />,
        });
      }
      if (onRefresh) {
        actions.push({
          label: 'Refresh',
          onClick: onRefresh,
          variant: 'outline',
          leftSection: <IconRefresh size={16} />,
        });
      }
      break;
      
    case 'error':
    case 'loading-failed':
      if (onRefresh) {
        actions.push({
          label: 'Try Again',
          onClick: onRefresh,
          variant: 'filled',
          leftSection: <IconRefresh size={16} />,
        });
      }
      break;
  }

  return actions;
};

// Default icon based on variant
const getVariantIcon = (variant: EmptyStateVariant): React.ComponentType<TablerIconsProps> => {
  switch (variant) {
    case 'no-results':
      return IconSearch;
    case 'error':
    case 'loading-failed':
    case 'access-denied':
      return IconAlertCircle;
    default:
      return IconDatabase;
  }
};

const EmptyState: React.FC<EmptyStateProps & {
  onAdd?: () => void;
  onRefresh?: () => void;
  onClearFilters?: () => void;
}> = ({
  variant = 'no-data',
  context = 'generic',
  title,
  message,
  icon,
  iconSize = 48,
  iconColor = 'dimmed',
  actions,
  height = 400,
  onAdd,
  onRefresh,
  onClearFilters,
}) => {
  const defaultContent = getDefaultContent(variant, context);
  const finalTitle = title || defaultContent.title;
  const finalMessage = message || defaultContent.message;
  
  const IconComponent = icon || CONTEXT_ICONS[context] || getVariantIcon(variant);
  
  const finalActions = actions || getDefaultActions(
    variant, 
    context, 
    onAdd, 
    onRefresh, 
    onClearFilters
  );

  return (
    <Center h={height}>
      <Stack align="center" gap="lg" maw={400} ta="center">
        <Box c={iconColor}>
          <IconComponent size={iconSize} stroke={1.5} />
        </Box>
        
        <Stack align="center" gap="xs">
          <Text size="lg" fw={600} c="dimmed">
            {finalTitle}
          </Text>
          <Text size="sm" c="dimmed" lh={1.5}>
            {finalMessage}
          </Text>
        </Stack>
        
        {finalActions.length > 0 && (
          <Stack align="center" gap="sm" w="100%">
            {finalActions.map((action, index) => (
              <Button
                key={index}
                onClick={action.onClick}
                variant={action.variant || 'filled'}
                color={action.color}
                leftSection={action.leftSection}
                size="sm"
              >
                {action.label}
              </Button>
            ))}
          </Stack>
        )}
      </Stack>
    </Center>
  );
};

export default EmptyState;

// Convenience components for common scenarios
export const NoUsersState: React.FC<Omit<EmptyStateProps, 'context' | 'variant'> & { onAddUser?: () => void }> = 
  ({ onAddUser, ...props }) => (
    <EmptyState {...props} variant="no-data" context="users" onAdd={onAddUser} />
  );

export const NoApplicationsState: React.FC<Omit<EmptyStateProps, 'context' | 'variant'> & { onCreateApp?: () => void }> = 
  ({ onCreateApp, ...props }) => (
    <EmptyState {...props} variant="no-data" context="applications" onAdd={onCreateApp} />
  );

export const NoFunctionsState: React.FC<Omit<EmptyStateProps, 'context' | 'variant'> & { onCreateFunction?: () => void }> = 
  ({ onCreateFunction, ...props }) => (
    <EmptyState {...props} variant="no-data" context="functions" onAdd={onCreateFunction} />
  );

export const NoTokensState: React.FC<Omit<EmptyStateProps, 'context' | 'variant'> & { onGenerateToken?: () => void }> = 
  ({ onGenerateToken, ...props }) => (
    <EmptyState {...props} variant="no-data" context="tokens" onAdd={onGenerateToken} />
  );

export const NoSearchResults: React.FC<Omit<EmptyStateProps, 'variant'> & { 
  onClearFilters?: () => void; 
  onRefresh?: () => void;
}> = ({ onClearFilters, onRefresh, ...props }) => (
  <EmptyState {...props} variant="no-results" onClearFilters={onClearFilters} onRefresh={onRefresh} />
);

export const ErrorState: React.FC<Omit<EmptyStateProps, 'variant'> & { onRetry?: () => void }> = 
  ({ onRetry, ...props }) => (
    <EmptyState {...props} variant="error" onRefresh={onRetry} />
  );