import type {
  Slide,
  SlideComponentModule,
  SlideRegistry
} from "../types/lecture";

const slideModuleCache = new Map<string, Promise<SlideComponentModule>>();

export const defaultSlideRegistry: SlideRegistry = {
  ChartSingle: () => import("../slides/ChartSingle"),
  DefinitionCard: () => import("../slides/DefinitionCard"),
  EquationFocus: () => import("../slides/EquationFocus"),
  FullscreenSplit: () => import("../slides/FullscreenSplit"),
  FullscreenVideo: () => import("../slides/FullscreenVideo"),
  FullscreenVideoCenterCaption: () =>
    import("../slides/FullscreenVideoCenterCaption"),
  FullscreenVideoTitle: () => import("../slides/FullscreenVideoTitle"),
  GlitchComponentFrame: () => import("../slides/GlitchComponentFrame"),
  ProcessFlow: () => import("../slides/ProcessFlow"),
  QuoteImage: () => import("../slides/QuoteImage"),
  SquareVideo: () => import("../slides/SquareVideo"),
  SquareYellow: () => import("../slides/SquareYellow")
};

export function loadSlideModule(
  slideRegistry: SlideRegistry,
  componentKey: string
): Promise<SlideComponentModule> {
  const existingPromise = slideModuleCache.get(componentKey);
  if (existingPromise) {
    return existingPromise;
  }

  const loader = slideRegistry[componentKey];
  if (!loader) {
    return Promise.reject(new Error(`Unknown slide component: ${componentKey}`));
  }

  const nextPromise = loader();
  slideModuleCache.set(componentKey, nextPromise);
  return nextPromise;
}

export async function preloadSlideModules(
  slideRegistry: SlideRegistry,
  slides: Slide[]
) {
  const componentKeys = new Set<string>();

  slides.forEach((slide) => {
    slide.glitchSlides.forEach((glitchSlide) => {
      componentKeys.add(glitchSlide.componentKey);
    });
  });

  await Promise.allSettled(
    [...componentKeys].map((componentKey) =>
      loadSlideModule(slideRegistry, componentKey)
    )
  );
}
