import { type Component, defineAsyncComponent } from "vue"
import { resolveCardPath } from "./registry"
import { __createMissingFallback } from "./useElementLoader"

const cardModules = import.meta.glob("../components/compositions/cards/**/*.vue")

const componentCache = new Map<string, Component>()

/**
 * Resolves the Vue component for a given DisplayCard `cardType`.
 * Same lazy-loading + fallback semantics as `getElementComponent`.
 */
export function getCardComponent(cardType: string): Component {
  const cached = componentCache.get(cardType)
  if (cached) {
    return cached
  }

  const path = resolveCardPath(cardType)
  if (!path) {
    const fallback = __createMissingFallback("card", cardType)
    componentCache.set(cardType, fallback)
    return fallback
  }

  const importer = cardModules[`../components/compositions/cards/${path}.vue`]
  if (!importer) {
    const fallback = __createMissingFallback("card", cardType, path)
    componentCache.set(cardType, fallback)
    return fallback
  }

  const component = defineAsyncComponent({
    loader: async () => {
      const mod = (await (importer as () => Promise<{ default: Component }>)())
      return mod.default ?? (mod as unknown as Component)
    },
    errorComponent: __createMissingFallback("card", cardType, path),
    delay: 0,
    suspensible: false,
  })
  componentCache.set(cardType, component)
  return component
}

export function preloadCard(cardType: string): Promise<unknown> {
  const path = resolveCardPath(cardType)
  if (!path) {
    return Promise.resolve()
  }
  const importer = cardModules[`../components/compositions/cards/${path}.vue`]
  return importer ? importer() : Promise.resolve()
}

export function __clearCardCache(): void {
  componentCache.clear()
}
