/**
 * Preset Registry System
 *
 * Provides a modular, developer-friendly system for registering
 * layout presets in the Price Builder.
 */

import type { PriceScenario, CanvasElement, ContainerSettings } from "../types";

/** Bundled preset asset types shipped from pro/includes/Export/presets/. */
export interface PresetCustomCode {
  css?: boolean;
  js?: boolean;
  html?: boolean;
}

// Preset definition interface
export interface PresetDefinition {
  id: string;
  name: string;
  description: string;
  scenario: PriceScenario;
  // Preview image component or SVG string
  preview: React.FC | string;
  // Full preview image component or SVG string
  fullPreview?: string;
  // Elements to create for this preset
  elements: Partial<CanvasElement>[];
  // Container settings for this preset
  containerSettings?: Partial<ContainerSettings>;
  // Advanced presets with animations/custom JS
  isAdvanced?: boolean;
  // Bundled CSS/JS/HTML assets (Pro export pipeline)
  customCode?: PresetCustomCode;
}

/** Whether a preset ships any bundled custom code assets. */
export function presetHasCustomCode(customCode?: PresetCustomCode): boolean {
  return !!(customCode?.css || customCode?.js || customCode?.html);
}

/** Whether preset CSS/HTML replaces canvas-generated styles on the frontend. */
export function presetOverridesCanvasStyles(customCode?: PresetCustomCode): boolean {
  return !!(customCode?.css || customCode?.html);
}

// Registry storage
const presetRegistry = new Map<string, PresetDefinition>();

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

/**
 * Register a new preset
 */
export function registerPreset(definition: PresetDefinition): void {
  if (presetRegistry.has(definition.id)) {
    console.warn(`Preset "${definition.id}" is already registered. Overwriting.`);
  }
  presetRegistry.set(definition.id, definition);
  notifyListeners();
}

/**
 * Unregister a preset
 */
export function unregisterPreset(id: string): boolean {
  const result = presetRegistry.delete(id);
  if (result) {
    notifyListeners();
  }
  return result;
}

/**
 * Get preset definition by ID
 */
export function getPresetDefinition(id: string): PresetDefinition | undefined {
  return presetRegistry.get(id);
}

/**
 * Get all registered presets
 */
export function getAllPresets(): PresetDefinition[] {
  return Array.from(presetRegistry.values());
}

/**
 * Get presets available for a specific scenario
 */
export function getPresetsForScenario(scenario: PriceScenario): PresetDefinition[] {
  return getAllPresets().filter((def) => def.scenario === scenario);
}

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

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

/**
 * Check if preset is registered
 */
export function isPresetRegistered(id: string): boolean {
  return presetRegistry.has(id);
}
