/**
 * Node Type Registry
 *
 * Maps node types to their UI components.
 * Apps register their custom node components here.
 */

import React from 'react';
import type { UINodeState } from './types';

// =============================================================================
// Types
// =============================================================================

/**
 * Props passed to node type components.
 */
export interface NodeTypeComponentProps {
	/** Full node state */
	nodeData: UINodeState;
	/** Whether the node is being resized */
	isResizing?: boolean;
}

/**
 * A component that renders a specific node type.
 */
export type NodeTypeComponent = React.ComponentType<NodeTypeComponentProps>;

// =============================================================================
// Registry
// =============================================================================

const nodeTypeRegistry = new Map<string, NodeTypeComponent>();

/**
 * Register a component for a node type.
 *
 * @example
 * ```tsx
 * registerNodeType('widget', WidgetNodeComponent);
 * registerNodeType('data-source', DataSourceNodeComponent);
 * ```
 */
export function registerNodeType(nodeType: string, component: NodeTypeComponent): void {
	nodeTypeRegistry.set(nodeType, component);
}

/**
 * Register multiple node types at once.
 *
 * @example
 * ```tsx
 * registerNodeTypes({
 *   'widget': WidgetNodeComponent,
 *   'data-source': DataSourceNodeComponent,
 *   'puck': PuckNodeComponent,
 * });
 * ```
 */
export function registerNodeTypes(types: Record<string, NodeTypeComponent>): void {
	for (const [nodeType, component] of Object.entries(types)) {
		nodeTypeRegistry.set(nodeType, component);
	}
}

/**
 * Unregister a node type component.
 * Returns true if the type was registered and removed.
 */
export function unregisterNodeType(nodeType: string): boolean {
	return nodeTypeRegistry.delete(nodeType);
}

/**
 * Get the component for a node type.
 * Returns undefined if no component is registered.
 */
export function getNodeTypeComponent(nodeType: string | null | undefined): NodeTypeComponent | undefined {
	if (!nodeType) return undefined;
	return nodeTypeRegistry.get(nodeType);
}

/**
 * Check if a node type has a registered component.
 */
export function hasNodeTypeComponent(nodeType: string | null | undefined): boolean {
	if (!nodeType) return false;
	return nodeTypeRegistry.has(nodeType);
}

/**
 * Get all registered node types.
 */
export function getRegisteredNodeTypes(): string[] {
	return Array.from(nodeTypeRegistry.keys());
}

/**
 * Clear all registered node types.
 * Useful for testing.
 */
export function clearNodeTypeRegistry(): void {
	nodeTypeRegistry.clear();
}

// =============================================================================
// Default Fallback Component
// =============================================================================

/**
 * Default fallback component for unknown node types.
 */
export const FallbackNodeTypeComponent: NodeTypeComponent = ({ nodeData }) => {
	return (
		<div
			style={{
				padding: '12px',
				display: 'flex',
				flexDirection: 'column',
				alignItems: 'center',
				justifyContent: 'center',
				height: '100%',
				color: '#666',
				fontSize: '12px',
			}}
		>
			<div>Unknown type: {nodeData.dbData.node_type || 'none'}</div>
			<div style={{ marginTop: '4px', opacity: 0.7 }}>{nodeData.id.substring(0, 8)}</div>
		</div>
	);
};
