/**
 * Component Registry
 * Runtime registry for component theme variants
 */

'use client';

import React from 'react';
import { Theme } from '../themes';

// The registry stores components with different prop types
// We use React.ComponentType (without generics) to store components dynamically
// This is type-safe because the generic registerThemeVariant function ensures correct types at registration
// and components are retrieved and used dynamically at runtime
const registry = new Map<string, Map<string, React.ComponentType<unknown>>>();

// Generic function accepts any component type without requiring type assertions at call sites
// The component is stored with type erasure internally, but callers have full type safety
export function registerThemeVariant<P = unknown>(
  componentName: string,
  theme: string,
  component: React.ComponentType<P>
) {
  if (!registry.has(componentName)) {
    registry.set(componentName, new Map());
  }
  registry.get(componentName)!.set(theme, component as React.ComponentType<unknown>);
}

export function getThemedComponent(
  componentName: string,
  theme: Theme = 'classic'
): React.ComponentType<unknown> {
  const variants = registry.get(componentName);
  
  if (!variants || variants.size === 0) {
    throw new Error(`No theme variants registered for "${componentName}"`);
  }
  
  if (variants.has(theme)) {
    return variants.get(theme)!;
  }
  
  if (theme === 'classic') {
    throw new Error(`No classic variant for "${componentName}" - use base component`);
  }
  
  throw new Error(`No variant available for "${componentName}.${theme}"`);
}

export function getRegistry() {
  const result: Record<string, string[]> = {};
  registry.forEach((variants, name) => {
    result[name] = Array.from(variants.keys());
  });
  return result;
}
