import { EmptyState } from '@/components/shared/state/EmptyState';
import { ErrorDisplay } from '@/components/shared/state/ErrorDisplay';
import { LoadingWrapper } from '@/components/shared/state/LoadingWrapper';
import { ApiError } from '@/lib/api/base/ApiError';
import { Box } from '@/ui/primitives/Box';
import { Inbox, List, LucideIcon } from 'lucide-react';
import React, { ReactNode } from 'react';

// ==================== PAGEWRAPPER TYPES ====================

export interface PageWrapperLoadingConfig {
  variant?: 'skeleton' | 'full-screen';
  message?: string;
}

export interface PageWrapperErrorConfig {
  variant?: 'full-screen' | 'card';
  card?: {
    title?: string;
    description?: string;
  };
}

export interface PageWrapperEmptyConfig {
  icon?: LucideIcon;
  title?: string;
  description?: string;
  action?: {
    label: string;
    onClick: () => void;
  };
}

export interface PageWrapperProps<TData> {
  /** Data to be rendered */
  data: TData | undefined;
  /** Loading state (default: false) */
  isLoading?: boolean;
  /** Error state (default: null) */
  error?: Error | null;
  /** Retry function for errors */
  retry?: () => void;
  /** Template component that receives the data */
  Template: React.ComponentType<{ data: TData }>;
  /** Loading configuration */
  loading?: PageWrapperLoadingConfig;
  /** Error configuration */
  errorConfig?: PageWrapperErrorConfig;
  /** Empty configuration */
  empty?: PageWrapperEmptyConfig;
  /** Children for flexible content rendering */
  children?: ReactNode;
}

/**
 * PageWrapper Component
 * 
 * A comprehensive wrapper component that handles all page states:
 * - Loading states (skeleton or full-screen)
 * - Error states (full-screen or card)
 * - Empty states (with icon, title, description, and action)
 * - Success state (renders Template component with data)
 * - Flexible children support for custom content
 * 
 * Usage Example:
 * ```typescript
 * <PageWrapper
 *   data={data}
 *   isLoading={isLoading}
 *   error={error}
 *   retry={retry}
 *   Template={MyTemplateComponent}
 *   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 }
 *   }}
 * >
 *   <AdditionalContent />
 * </PageWrapper>
 * ```
 */
export function PageWrapper<TData>({
  data,
  isLoading = false,
  error = null,
  retry,
  Template,
  loading,
  errorConfig,
  empty,
  children,
}: PageWrapperProps<TData>) {
  // Priority order: Loading > Error > Empty > Success

  // 1. Loading State
  if (isLoading) {
    const loadingVariant = loading?.variant || 'skeleton';
    const loadingMessage = loading?.message || 'Loading...';

    if (loadingVariant === 'full-screen') {
      return (
        <LoadingWrapper
          variant="full-screen"
          message={loadingMessage}
        />
      );
    }

    // Default to skeleton
    return (
      <Box>
        <LoadingWrapper
          variant="skeleton"
          message={loadingMessage}
          skeletonCount={3}
        />
        {children}
      </Box>
    );
  }

  // 2. Error State
  if (error) {
    const errorVariant = errorConfig?.variant || 'full-screen';

    if (errorVariant === 'card') {
      return (
        <Box>
          <ErrorDisplay
            error={error as ApiError}
            onRetry={retry}
            variant="card"
          />
          {children}
        </Box>
      );
    }

    // Default to full-screen
    return (
      <ErrorDisplay
        error={error as ApiError}
        onRetry={retry}
        variant="full-screen"
      />
    );
  }

  // 3. Empty State
  if (!data || (Array.isArray(data) && data.length === 0)) {
    if (empty) {
      const Icon = empty.icon;
      const hasAction = empty.action && retry;

      return (
        <Box>
          <EmptyState
            icon={Icon || Inbox}
            title={empty.title || 'No data available'}
            description={empty.description}
            action={hasAction ? {
              label: empty.action!.label,
              onClick: empty.action!.onClick,
            } : undefined}
            variant="default"
          />
          {children}
        </Box>
      );
    }

    // If no empty config provided but data is empty, show nothing
    return (
      <Box>
        {children}
      </Box>
    );
  }

  // 4. Success State - Render Template with data
  return (
    <Box>
      <Template data={data} />
      {children}
    </Box>
  );
}

/**
 * Convenience component for list data with automatic empty state handling
 */
export function ListPageWrapper<TData extends unknown[]>({
  data,
  isLoading = false,
  error = null,
  retry,
  Template,
  loading,
  errorConfig,
  empty,
  children,
}: PageWrapperProps<TData>) {
  const listEmpty = empty || {
    icon: List,
    title: 'No items found',
    description: 'This list is currently empty',
  };

  return (
    <PageWrapper
      data={data}
      isLoading={isLoading}
      error={error}
      retry={retry}
      Template={Template}
      loading={loading}
      errorConfig={errorConfig}
      empty={listEmpty}
    >
      {children}
    </PageWrapper>
  );
}

/**
 * Convenience component for detail pages with enhanced error handling
 */
export function DetailPageWrapper<TData>({
  data,
  isLoading = false,
  error = null,
  retry,
  Template,
  loading,
  errorConfig,
  empty,
  children,
}: PageWrapperProps<TData> & {
  onBack?: () => void;
  onRefresh?: () => void;
}) {
  // Create enhanced error config with additional actions
  const enhancedErrorConfig: PageWrapperErrorConfig = {
    ...errorConfig,
  };

  return (
    <PageWrapper
      data={data}
      isLoading={isLoading}
      error={error}
      retry={retry}
      Template={Template}
      loading={loading}
      errorConfig={enhancedErrorConfig}
      empty={empty}
    >
      {children}
    </PageWrapper>
  );
}