/**
 * @file
 * FlowDrop Schema Form Integration for Drupal
 *
 * @description
 * Provides Drupal behavior for initializing and managing SchemaForm components.
 * This script automatically mounts SchemaForm instances for elements with the
 * [data-schema-form] attribute.
 *
 * Requires the shared FlowDrop library (flowdrop_ui_components/flowdrop).
 */

(function (once, Drupal, drupalSettings) {
	"use strict";

	/**
	 * Drupal behavior for mounting SchemaForm components
	 *
	 * @type {Drupal~behavior}
	 */
	Drupal.behaviors.flowdropSchemaForm = {
		/**
		 * Attach behavior to schema form containers
		 *
		 * @param {HTMLElement} context - The context element to search within
		 * @param {object} settings - Drupal settings object
		 */
		attach: function (context, settings) {
			once("flowdrop-schema-form", "[data-schema-form]", context).forEach(
				function (formContainer) {
					initializeSchemaForm(formContainer, settings);
				}
			);
		},

		/**
		 * Detach behavior and cleanup mounted components
		 *
		 * @param {HTMLElement} context - The context element to search within
		 * @param {object} settings - Drupal settings object
		 * @param {string} trigger - The trigger for detachment
		 */
		detach: function (context, settings, trigger) {
			if (trigger !== "unload") {
				return;
			}

			const containers = context.querySelectorAll("[data-schema-form]");
			containers.forEach(function (formContainer) {
				if (
					formContainer.schemaFormInstance &&
					typeof formContainer.schemaFormInstance.destroy === "function"
				) {
					formContainer.schemaFormInstance.destroy();
					formContainer.schemaFormInstance = null;
				}
			});
		}
	};

	/**
	 * Initialize a SchemaForm component in the given container
	 *
	 * @param {HTMLElement} formContainer - The container element for the form
	 * @param {object} settings - Drupal settings object
	 */
	async function initializeSchemaForm(formContainer, settings) {
		if (formContainer.dataset.flowdropInitialized === "true") {
			return;
		}

		// Check if shared FlowDrop library is available
		if (typeof window.FlowDrop === "undefined") {
			showError(
				formContainer,
				"FlowDrop Library Not Available",
				"The FlowDrop library could not be loaded. Please ensure flowdrop_ui_components module is enabled."
			);
			return;
		}

		if (typeof window.FlowDrop.mountSchemaForm !== "function") {
			showError(
				formContainer,
				"SchemaForm mount function not available",
				"The mountSchemaForm function is not available in the FlowDrop library."
			);
			return;
		}

		// Parse schema from data attribute
		let schema;
		try {
			const schemaStr = formContainer.dataset.schema;
			if (!schemaStr) {
				throw new Error("No schema provided");
			}
			schema = JSON.parse(schemaStr);
		} catch (error) {
			showError(
				formContainer,
				"Invalid JSON Schema",
				"Failed to parse the JSON Schema: " + error.message
			);
			return;
		}

		// Parse initial values
		let values = {};
		try {
			const valuesStr = formContainer.dataset.values;
			if (valuesStr) {
				values = JSON.parse(valuesStr);
			}
		} catch (error) {
			console.warn("[SchemaForm] Failed to parse initial values, using empty object:", error);
		}

		// Parse configuration
		const showActions = formContainer.dataset.showActions === "true";
		const saveLabel = formContainer.dataset.saveLabel || "Save";
		const cancelLabel = formContainer.dataset.cancelLabel || "Cancel";
		const enableCodeEditor = formContainer.dataset.enableCodeEditor === "true";

		// Clear loading state
		const loadingElement = formContainer.querySelector(".fd-schema-form__loading");
		if (loadingElement) {
			loadingElement.style.display = "none";
		}

		// Set initialized flag immediately to prevent duplicate initialization
		formContainer.dataset.flowdropInitialized = "true";
		try {
			// Register code editor field if enabled (async — loads CodeMirror chunk on demand)
			if (enableCodeEditor && typeof window.FlowDrop.registerCodeEditorField === "function") {
				await window.FlowDrop.registerCodeEditorField();
			}

			// Mount the SchemaForm component
			const formInstance = window.FlowDrop.mountSchemaForm(formContainer, {
				schema: schema,
				values: values,
				showActions: showActions,
				saveLabel: saveLabel,
				cancelLabel: cancelLabel,
				onChange: function (newValues) {
					formContainer.dispatchEvent(new CustomEvent("flowdrop:schemaform:change", {
						detail: { formId: formContainer.id, values: newValues },
						bubbles: true
					}));

					formContainer.dataset.values = JSON.stringify(newValues);

					if (typeof Drupal.behaviors.formUpdated !== "undefined") {
						const formElement = formContainer.closest("form");
						if (formElement) {
							formElement.classList.add("form-updated");
						}
					}
				},
				onSave: function (savedValues) {
					formContainer.dispatchEvent(new CustomEvent("flowdrop:schemaform:save", {
						detail: { formId: formContainer.id, values: savedValues },
						bubbles: true
					}));
				},
				onCancel: function () {
					formContainer.dispatchEvent(new CustomEvent("flowdrop:schemaform:cancel", {
						detail: { formId: formContainer.id },
						bubbles: true
					}));
				}
			});

			formContainer.schemaFormInstance = formInstance;

			formContainer.dispatchEvent(new CustomEvent("flowdrop:schemaform:init", {
				detail: { formId: formContainer.id, instance: formInstance },
				bubbles: true
			}));
		} catch (error) {
			// Clear initialization flag so retry is possible
			formContainer.removeAttribute("data-flowdrop-initialized");
			showError(
				formContainer,
				"Failed to initialize form",
				"An error occurred while initializing the SchemaForm: " + error.message
			);
			console.error("[SchemaForm] Initialization error:", error);
		}
	}

	/**
	 * Display an error message in the form container
	 *
	 * @param {HTMLElement} container - The container element
	 * @param {string} title - Error title
	 * @param {string} message - Error message details
	 */
	function showError(container, title, message) {
		var loadingElement = container.querySelector(".fd-schema-form__loading");
		if (loadingElement) {
			loadingElement.remove();
		}

		// Clear container safely
		while (container.firstChild) {
			container.removeChild(container.firstChild);
		}

		// Build error UI with safe DOM construction
		var errorDiv = document.createElement("div");
		errorDiv.className = "fd-schema-form__error";

		var iconDiv = document.createElement("div");
		iconDiv.className = "fd-schema-form__error-icon";
		var svgNS = "http://www.w3.org/2000/svg";
		var svg = document.createElementNS(svgNS, "svg");
		svg.setAttribute("xmlns", svgNS);
		svg.setAttribute("width", "24");
		svg.setAttribute("height", "24");
		svg.setAttribute("viewBox", "0 0 24 24");
		svg.setAttribute("fill", "none");
		svg.setAttribute("stroke", "currentColor");
		svg.setAttribute("stroke-width", "2");
		var circle = document.createElementNS(svgNS, "circle");
		circle.setAttribute("cx", "12");
		circle.setAttribute("cy", "12");
		circle.setAttribute("r", "10");
		svg.appendChild(circle);
		var line1 = document.createElementNS(svgNS, "line");
		line1.setAttribute("x1", "12");
		line1.setAttribute("y1", "8");
		line1.setAttribute("x2", "12");
		line1.setAttribute("y2", "12");
		svg.appendChild(line1);
		var line2 = document.createElementNS(svgNS, "line");
		line2.setAttribute("x1", "12");
		line2.setAttribute("y1", "16");
		line2.setAttribute("x2", "12.01");
		line2.setAttribute("y2", "16");
		svg.appendChild(line2);
		iconDiv.appendChild(svg);
		errorDiv.appendChild(iconDiv);

		var h4 = document.createElement("h4");
		h4.className = "fd-schema-form__error-title";
		h4.textContent = Drupal.checkPlain(title);
		errorDiv.appendChild(h4);

		var p = document.createElement("p");
		p.className = "fd-schema-form__error-message";
		p.textContent = Drupal.checkPlain(message);
		errorDiv.appendChild(p);

		container.appendChild(errorDiv);
		container.classList.add("fd-schema-form--error");
	}

	/**
	 * Public API for SchemaForm
	 */
	Drupal.flowdropSchemaForm = {
		getValues: function (formIdOrElement) {
			const container = typeof formIdOrElement === "string"
				? document.getElementById(formIdOrElement)
				: formIdOrElement;

			if (!container) {
				console.warn("[SchemaForm] Form container not found:", formIdOrElement);
				return null;
			}

			try {
				return JSON.parse(container.dataset.values || "{}");
			} catch (error) {
				console.error("[SchemaForm] Failed to get form values:", error);
				return null;
			}
		},

		destroy: function (formIdOrElement) {
			const container = typeof formIdOrElement === "string"
				? document.getElementById(formIdOrElement)
				: formIdOrElement;

			if (
				container &&
				container.schemaFormInstance &&
				typeof container.schemaFormInstance.destroy === "function"
			) {
				container.schemaFormInstance.destroy();
				container.schemaFormInstance = null;
				container.removeAttribute("data-flowdrop-initialized");
			}
		}
	};
})(once, Drupal, drupalSettings);
