/**
 * FlowDrop Shared Library for Drupal
 *
 * This module provides a unified export of FlowDrop functionality for use
 * in Drupal Single Directory Components (SDC). It combines both the workflow
 * editor and schema form capabilities into a single shared library.
 *
 * @description
 * This library is designed to be loaded once and shared across multiple
 * SDC components, reducing bundle duplication and improving caching.
 *
 * @example
 * // The library exposes window.FlowDrop with all exports
 * const { mountFlowDropApp, mountSchemaForm } = window.FlowDrop;
 *
 * // Mount workflow editor
 * const editor = await mountFlowDropApp(container, { workflow, endpointConfig });
 *
 * // Mount schema form
 * const form = mountSchemaForm(container, { schema, values, onChange });
 */

/**
 * Import base styles from the FlowDrop package
 */
import "@d34dman/flowdrop/styles/base.css";

// ============================================================================
// Schema Form Exports
// ============================================================================

import { mount, unmount } from "svelte";
import type { SchemaFormProps } from "@d34dman/flowdrop/form";
import { SchemaForm } from "@d34dman/flowdrop/form";
import { registerCodeEditorField } from "@d34dman/flowdrop/form/code";

/**
 * Type alias for the Svelte component instance
 */
type SchemaFormComponent = ReturnType<typeof mount>;

/**
 * Interface for the mounted SchemaForm instance
 */
export interface MountedSchemaForm {
	/** Unmount the SchemaForm component and clean up resources */
	destroy: () => void;
	/** Update the form's props (for reactive updates, manage state externally) */
	update: (newProps: Partial<SchemaFormProps>) => void;
	/** Reference to the underlying Svelte component instance */
	component: SchemaFormComponent;
}

/**
 * Mount options for the SchemaForm component
 */
export interface MountSchemaFormOptions {
	/** JSON Schema defining the form structure */
	schema: SchemaFormProps["schema"];
	/** Current form values as key-value pairs */
	values?: SchemaFormProps["values"];
	/** Callback fired when form values change */
	onChange?: SchemaFormProps["onChange"];
	/** Whether to display Save and Cancel action buttons */
	showActions?: SchemaFormProps["showActions"];
	/** Label text for the save button */
	saveLabel?: SchemaFormProps["saveLabel"];
	/** Label text for the cancel button */
	cancelLabel?: SchemaFormProps["cancelLabel"];
	/** Callback fired when the Save button is clicked */
	onSave?: SchemaFormProps["onSave"];
	/** Callback fired when the Cancel button is clicked */
	onCancel?: SchemaFormProps["onCancel"];
	/** Whether the form is in a loading state */
	loading?: SchemaFormProps["loading"];
	/** Whether the form is disabled */
	disabled?: SchemaFormProps["disabled"];
	/** Custom CSS class to apply to the form container */
	class?: SchemaFormProps["class"];
}

/**
 * Mounts a SchemaForm component into the specified container element
 *
 * @param container - The DOM element or CSS selector to mount the form into
 * @param options - Configuration options for the SchemaForm
 * @returns A MountedSchemaForm object with methods to control the mounted instance
 */
export function mountSchemaForm(
	container: HTMLElement | string,
	options: MountSchemaFormOptions
): MountedSchemaForm {
	const targetElement =
		typeof container === "string"
			? document.querySelector<HTMLElement>(container)
			: container;

	if (!targetElement) {
		throw new Error(
			`SchemaForm mount error: Container element not found. ` +
				`Provided: ${typeof container === "string" ? container : "HTMLElement"}`
		);
	}

	if (!options.schema) {
		throw new Error("SchemaForm mount error: 'schema' prop is required");
	}

	const props: Record<string, unknown> = {
		schema: options.schema
	};

	if (options.values !== undefined) props.values = options.values;
	if (options.onChange !== undefined) props.onChange = options.onChange;
	if (options.showActions !== undefined) props.showActions = options.showActions;
	if (options.saveLabel !== undefined) props.saveLabel = options.saveLabel;
	if (options.cancelLabel !== undefined) props.cancelLabel = options.cancelLabel;
	if (options.onSave !== undefined) props.onSave = options.onSave;
	if (options.onCancel !== undefined) props.onCancel = options.onCancel;
	if (options.loading !== undefined) props.loading = options.loading;
	if (options.disabled !== undefined) props.disabled = options.disabled;
	if (options.class !== undefined) props.class = options.class;

	const mountOptions = {
		target: targetElement,
		props
	};

	const component = mount(
		SchemaForm,
		mountOptions as Parameters<typeof mount>[1]
	);

	const mountedInstance: MountedSchemaForm = {
		destroy: () => {
			unmount(component);
		},
		update: () => {
			console.warn(
				"SchemaForm update() called - for reactive updates, manage state externally and use onChange callback"
			);
		},
		component
	};

	return mountedInstance;
}

// Re-export schema form types and utilities
export type { SchemaFormProps };
export { SchemaForm, registerCodeEditorField };

// ============================================================================
// Workflow Editor Exports
// ============================================================================

export {
	// Main mounting functions
	mountFlowDropApp,
	mountWorkflowEditor,
	unmountFlowDropApp,
	// Components
	WorkflowEditor,
	App,
	NodeSidebar,
	Navbar,
	Logo,
	// Services
	FlowDropApiClient,
	EnhancedFlowDropApiClient,
	ApiError,
	// Workflow store and actions
	workflowStore,
	workflowActions,
	workflowId,
	workflowName,
	workflowNodes,
	workflowEdges,
	workflowMetadata,
	isDirty,
	markAsSaved,
	getWorkflowFromStore,
	// Global save
	globalSaveWorkflow,
	globalExportWorkflow,
	initializeGlobalSave,
	// Toast notifications
	showSuccess,
	showError,
	showWarning,
	showInfo,
	showLoading,
	dismissToast,
	// Dynamic schema services
	fetchDynamicSchema,
	resolveExternalEditUrl,
	clearSchemaCache,
	// Draft storage
	saveDraft,
	loadDraft,
	deleteDraft,
	hasDraft
} from "@d34dman/flowdrop/editor";

// Re-export editor types
export type {
	FlowDropMountOptions,
	MountedFlowDropApp,
	NavbarAction,
	Workflow,
	WorkflowNode,
	WorkflowEdge,
	NodeMetadata,
	EndpointConfig
} from "@d34dman/flowdrop/editor";
