'use client';

import { EmptyState } from '@/ui/EmptyState';
import { ErrorDisplay } from '@/components/shared/ErrorDisplay';
import { LoadingWrapper } from '@/ui/LoadingWrapper';
import { Box } from '@/ui/Box';
import { Heading } from '@/ui/Heading';
import { StateContainerConfig, StateContainerProps } from '@/ui/state-types';
import { Text } from '@/ui/Text';
import { AlertCircle, Grid, Inbox, List, LucideIcon } from 'lucide-react';

/**
 * StateContainer Component
 * 
 * Combined wrapper that automatically handles all states (loading, error, empty, success)
 * based on the provided data and state values.
 * 
 * Features:
 * - Automatic state detection and rendering
 * - Customizable configuration for each state
 * - Custom render functions for advanced use cases
 * - Consistent behavior across all pages
 * 
 * Usage Example:
 * ```typescript
 * <StateContainer
 *   data={data}
 *   isLoading={isLoading}
 *   error={error}
 *   retry={retry}
 *   config={{
 *     loading: { variant: 'skeleton', message: 'Loading...' },
 *     error: { variant: 'full-screen' },
 *     empty: {
 *       icon: Trophy,
 *       title: 'No data found',
 *       description: 'Try refreshing the page',
 *       action: { label: 'Refresh', onClick: retry }
 *     }
 *   }}
 * >
 *   {(content) => <MyContent data={content} />}
 * </StateContainer>
 * ```
 */
export function StateContainer<T>({
  data,
  isLoading,
  error,
  retry,
  children,
  config,
  showEmpty = true,
  isEmpty,
}: StateContainerProps<T>) {
  // Determine if data is empty
  const isDataEmpty = (data: T | null | undefined): boolean => {
    if (data === null || data === undefined) return true;
    if (isEmpty) return isEmpty(data);
    
    // Default empty checks
    if (Array.isArray(data)) return data.length === 0;
    if (typeof data === 'object' && data !== null) {
      return Object.keys(data).length === 0;
    }
    return false;
  };

  // Priority order: Loading > Error > Empty > Success
  if (isLoading) {
    const loadingConfig = config?.loading || {};
    
    // Custom render
    if (config?.customRender?.loading) {
      return <>{config.customRender.loading()}</>;
    }

    return (
      <Box>
        <LoadingWrapper
          variant={loadingConfig.variant || 'spinner'}
          message={loadingConfig.message || 'Loading...'}
          size={loadingConfig.size || 'md'}
          skeletonCount={loadingConfig.skeletonCount}
        />
      </Box>
    );
  }

  if (error) {
    const errorConfig = config?.error || {};
    
    // Custom render
    if (config?.customRender?.error) {
      return <>{config.customRender.error(error)}</>;
    }

    return (
      <Box>
        <ErrorDisplay
          error={error}
          onRetry={retry}
          variant={errorConfig.variant || 'full-screen'}
          actions={errorConfig.actions}
          showRetry={errorConfig.showRetry}
          showNavigation={errorConfig.showNavigation}
          hideTechnicalDetails={errorConfig.hideTechnicalDetails}
        />
      </Box>
    );
  }

  if (showEmpty && isDataEmpty(data)) {
    const emptyConfig = config?.empty;
    
    // Custom render
    if (config?.customRender?.empty) {
      return <>{config.customRender.empty()}</>;
    }

    // If no empty config provided, show nothing (or could show default empty state)
    if (!emptyConfig) {
      return (
        <Box>
          <EmptyState
            icon={Inbox}
            title="No data available"
            description="There is nothing to display here"
          />
        </Box>
      );
    }

    return (
      <Box>
        <EmptyState
          icon={emptyConfig.icon}
          title={emptyConfig.title || 'No data available'}
          description={emptyConfig.description}
          action={emptyConfig.action}
          variant="default"
        />
      </Box>
    );
  }

  // Success state - render children with data
  if (data === null || data === undefined) {
    // This shouldn't happen if we've handled all cases above, but as a fallback
    return (
      <Box>
        <EmptyState
          icon={AlertCircle}
          title="Unexpected state"
          description="No data available but no error or loading state"
        />
      </Box>
    );
  }

  // Custom success render
  if (config?.customRender?.success) {
    return <>{config.customRender.success(data as T)}</>;
  }

  // At this point, data is guaranteed to be non-null and non-undefined
  return <>{children(data as T)}</>;
}

/**
 * ListStateContainer - Specialized for list data
 * Automatically handles empty arrays with appropriate messaging
 */
export function ListStateContainer<T>({
  data,
  isLoading,
  error,
  retry,
  children,
  config,
  emptyConfig,
}: StateContainerProps<T[]> & {
  emptyConfig?: {
    icon: LucideIcon;
    title: string;
    description?: string;
    action?: {
      label: string;
      onClick: () => void;
    };
  };
}) {
  const listConfig: StateContainerConfig<T[]> = {
    ...config,
    empty: emptyConfig || {
      icon: List,
      title: 'No items found',
      description: 'This list is currently empty',
    },
  };

  return (
    <StateContainer
      data={data}
      isLoading={isLoading}
      error={error}
      retry={retry}
      config={listConfig}
      isEmpty={(arr) => !arr || arr.length === 0}
    >
      {children}
    </StateContainer>
  );
}

/**
 * DetailStateContainer - Specialized for detail pages
 * Includes back/refresh functionality
 */
export function DetailStateContainer<T>({
  data,
  isLoading,
  error,
  retry,
  children,
  config,
  onBack,
  onRefresh,
}: StateContainerProps<T> & {
  onBack?: () => void;
  onRefresh?: () => void;
}) {
  const detailConfig: StateContainerConfig<T> = {
    ...config,
    error: {
      ...config?.error,
      actions: [
        ...(config?.error?.actions || []),
        ...(onBack ? [{ label: 'Go Back', onClick: onBack, variant: 'secondary' as const }] : []),
        ...(onRefresh ? [{ label: 'Refresh', onClick: onRefresh, variant: 'primary' as const }] : []),
      ],
      showNavigation: config?.error?.showNavigation ?? true,
    },
  };

  return (
    <StateContainer
      data={data}
      isLoading={isLoading}
      error={error}
      retry={retry}
      config={detailConfig}
    >
      {children}
    </StateContainer>
  );
}

/**
 * PageStateContainer - Full page state management
 * Wraps content in proper page structure
 */
export function PageStateContainer<T>({
  data,
  isLoading,
  error,
  retry,
  children,
  config,
  title,
  description,
}: StateContainerProps<T> & {
  title?: string;
  description?: string;
}) {
  const pageConfig: StateContainerConfig<T> = {
    loading: {
      variant: 'full-screen',
      message: title ? `Loading ${title}...` : 'Loading...',
      ...config?.loading,
    },
    error: {
      variant: 'full-screen',
      ...config?.error,
    },
    empty: config?.empty,
  };

  if (isLoading) {
    return <StateContainer data={data} isLoading={isLoading} error={error} retry={retry} config={pageConfig}>
      {children}
    </StateContainer>;
  }

  if (error) {
    return <StateContainer data={data} isLoading={isLoading} error={error} retry={retry} config={pageConfig}>
      {children}
    </StateContainer>;
  }

  if (!data || (Array.isArray(data) && data.length === 0)) {
    if (config?.empty) {
      return (
        <Box bg="bg-deep-graphite" py={12} minHeight="100vh">
          <Box maxWidth="4xl" mx="auto" px={4}>
            {title && (
              <Box mb={8}>
                <Heading level={1}>{title}</Heading>
                {description && (
                  <Text color="text-gray-400">{description}</Text>
                )}
              </Box>
            )}
            <StateContainer data={data} isLoading={isLoading} error={error} retry={retry} config={pageConfig}>
              {children}
            </StateContainer>
          </Box>
        </Box>
      );
    }
  }

  return (
    <Box bg="bg-deep-graphite" py={8} minHeight="100vh">
      <Box maxWidth="4xl" mx="auto" px={4}>
        {title && (
          <Box mb={6}>
            <Heading level={1}>{title}</Heading>
            {description && (
              <Text color="text-gray-400">{description}</Text>
            )}
          </Box>
        )}
        <StateContainer data={data} isLoading={isLoading} error={error} retry={retry} config={pageConfig}>
          {children}
        </StateContainer>
      </Box>
    </Box>
  );
}

/**
 * GridStateContainer - Specialized for grid layouts
 * Handles card-based empty states
 */
export function GridStateContainer<T>({
  data,
  isLoading,
  error,
  retry,
  children,
  config,
  emptyConfig,
}: StateContainerProps<T[]> & {
  emptyConfig?: {
    icon: LucideIcon;
    title: string;
    description?: string;
    action?: {
      label: string;
      onClick: () => void;
    };
  };
}) {
  const gridConfig: StateContainerConfig<T[]> = {
    loading: {
      variant: 'card',
      ...config?.loading,
    },
    ...config,
    empty: emptyConfig || {
      icon: Grid,
      title: 'No items to display',
      description: 'Try adjusting your filters or search',
    },
  };

  return (
    <StateContainer
      data={data}
      isLoading={isLoading}
      error={error}
      retry={retry}
      config={gridConfig}
      isEmpty={(arr) => !arr || arr.length === 0}
    >
      {children}
    </StateContainer>
  );
}
