/**
 * Element Renderer Registry
 *
 * Maps element types to their renderer components.
 * 3rd party developers can register custom renderers here.
 */

import type {ComponentType} from "react";
import type {CanvasElement, ElementType} from "@/types";

// Generic props interface for element renderers
export interface ElementRendererProps {
  element: CanvasElement;
}

// Type for renderer components
export type ElementRendererComponent = ComponentType<ElementRendererProps>;

// Registry storage
const rendererRegistry = new Map<ElementType, ElementRendererComponent>();

// Event listeners for registry changes
type RegistryListener = () => void;
const listeners: Set<RegistryListener> = new Set();

/**
 * Register a renderer for an element type
 */
export function registerRenderer(
  type: ElementType,
  renderer: ElementRendererComponent
): void {
  rendererRegistry.set(type, renderer);
  notifyListeners();
}

/**
 * Unregister a renderer
 */
export function unregisterRenderer(type: ElementType): boolean {
  const result = rendererRegistry.delete(type);
  if (result) {
    notifyListeners();
  }
  return result;
}

/**
 * Get renderer for an element type
 */
export function getRenderer(
  type: ElementType
): ElementRendererComponent | undefined {
  return rendererRegistry.get(type);
}

/**
 * Check if a renderer is registered
 */
export function hasRenderer(type: ElementType): boolean {
  return rendererRegistry.has(type);
}

/**
 * Subscribe to registry changes
 */
export function subscribeToRendererRegistry(
  listener: RegistryListener
): () => void {
  listeners.add(listener);
  return () => {
    listeners.delete(listener);
  };
}

/**
 * Notify all listeners of registry changes
 */
function notifyListeners(): void {
  listeners.forEach((listener) => listener());
}

/**
 * Get all registered renderer types
 */
export function getRegisteredTypes(): ElementType[] {
  return Array.from(rendererRegistry.keys());
}
