import { Suspense, lazy, type ComponentType } from 'react';
import { LoadingSpinner } from './loading-spinner';

// Composant de fallback pour les erreurs de chargement
function ErrorFallback({ pageName }: { pageName: string }) {
  return (
    <div className="container mx-auto px-4 py-8">
      <div className="max-w-2xl mx-auto">
        <h1 className="text-2xl font-bold mb-4">{pageName}</h1>
        <div className="bg-yellow-50 border border-yellow-200 text-yellow-700 px-4 py-3 rounded">
          <p>Failed to load {pageName}. Please refresh the page.</p>
        </div>
      </div>
    </div>
  );
}

interface LazyComponentProps {
  fallback?: React.ReactNode;
}

export function createLazyComponent<T extends ComponentType<any>>(
  importFunc: () => Promise<{ default: T }>,
  fallback?: React.ReactNode,
) {
  const LazyComponent = lazy(importFunc);

  return function WrappedLazyComponent(
    props: React.ComponentProps<T> & LazyComponentProps,
  ) {
    // Extraire fallback des props pour ne pas le passer au composant lazy
    const { fallback: _fallback, ...componentProps } = props;
    return (
      <Suspense fallback={fallback || <LoadingSpinner />}>
        {/* @ts-expect-error - LazyComponent props are compatible but TypeScript can't infer it */}
        <LazyComponent {...componentProps} />
      </Suspense>
    );
  };
}

// Composants lazy communs
export const LazyDashboard = createLazyComponent(() =>
  import('@/pages/DashboardPage').then((m) => ({ default: m.DashboardPage })),
);
export const LazyChat = createLazyComponent(() =>
  import('@/features/chat/pages/ChatPage').then((m) => ({
    default: m.ChatPage,
  })),
);
export const LazyLibrary = createLazyComponent(
  () =>
    import('@/features/library/pages/LibraryPage')
      .then((m) => ({ default: m.default }))
      .catch((err) => {
        console.error('Failed to load LibraryPage:', err);
        return { default: () => <ErrorFallback pageName="Library" /> };
      }) as Promise<{ default: ComponentType<any> }>,
);
export const LazyProfile = createLazyComponent(() =>
  import('@/pages/ProfilePage')
    .then((m) => ({ default: m.ProfilePage }))
    .catch((err) => {
      console.error('Failed to load ProfilePage:', err);
      return { default: () => <ErrorFallback pageName="Profile" /> };
    }) as Promise<{ default: ComponentType<any> }>,
);
export const LazySettings = createLazyComponent(() =>
  import('@/features/settings/pages/SettingsPage')
    .then((m) => ({
      default: m.SettingsPage,
    }))
    .catch((err) => {
      console.error('Failed to load SettingsPage:', err);
      return { default: () => <ErrorFallback pageName="Settings" /> };
    }) as Promise<{ default: ComponentType<any> }>,
);
export const LazyLogin = createLazyComponent(() =>
  import('@/pages/LoginPage').then((m) => ({ default: m.LoginPage })),
);
export const LazyRegister = createLazyComponent(() =>
  import('@/pages/RegisterPage').then((m) => ({ default: m.RegisterPage })),
);
export const LazyForgotPassword = createLazyComponent(
  () => import('@/features/auth/pages/ForgotPasswordPage'),
);
export const LazyVerifyEmail = createLazyComponent(
  () => import('@/features/auth/pages/VerifyEmailPage'),
);
export const LazyResetPassword = createLazyComponent(
  () => import('@/features/auth/pages/ResetPasswordPage'),
);
export const LazySessions = createLazyComponent(
  () => import('@/features/auth/pages/SessionsPage'),
);
export const LazyNotFound = createLazyComponent(
  () => import('@/features/error/pages/NotFoundPage'),
);
export const LazyServerError = createLazyComponent(
  () => import('@/features/error/pages/ServerErrorPage'),
);
export const LazyUserProfile = createLazyComponent(() =>
  import('@/features/profile/pages/UserProfilePage').then((m) => ({
    default: m.UserProfilePage,
  })),
);
export const LazyRoles = createLazyComponent(() =>
  import('@/features/roles/pages/RolesPage').then((m) => ({
    default: m.RolesPage,
  })),
);
export const LazyTrackDetail = createLazyComponent(() =>
  import('@/features/tracks/pages/TrackDetailPage').then((m) => ({
    default: m.TrackDetailPage,
  })),
);
export const LazyPlaylistRoutes = createLazyComponent(() =>
  import('@/features/playlists/routes').then((m) => ({
    default: m.PlaylistRoutes,
  })),
);
export const LazyMarketplace = createLazyComponent(() =>
  import('@/pages/marketplace/MarketplaceHome').then((m) => ({
    default: m.MarketplaceHome,
  })),
);
