import { ready } from '../../utilities/ready';

const pwdBlocks = (function (exports) {
	'use strict';

	const blockPlaceholders = [];

	// Web Component for Password Blocks
	class PWPPwdBlocks extends HTMLElement {
		connectedCallback() {
			ready(this);
		}

		readyInit() {
			// Check on a block-id, password and contained <template>
			if (this.blockId && !blockPlaceholders[this.blockId]) {
				const template = this.querySelector("template")?.content;
				if ( ! template ) {
					return;
				}
				// Push the element to the placeholder array
				blockPlaceholders[this.blockId] = {
					postId: this.postId ?? false, // Only used in legacy mode.
					template: template,
					content: undefined,
					element: this,
				};
			}
		}

		/**
		 * Return post ID, only used in legacy mode.
		 */
		get postId() {
			return this.getAttribute("post-id");
		}

		get blockId() {
			return this.getAttribute("block-id");
		}
	}
	window.customElements.define('pwp-block-pwd', PWPPwdBlocks);

	/**
	 * Parse DOM placeholders for blocks requiring password access
	 */
	async function populatePlaceholders() {
		const { callApi } = PersonalizeWP.utils;
		Object.keys(blockPlaceholders).forEach((blockId) => {
			if (!blockPlaceholders[blockId]) {
				return;
			}

			const { postId, template, content, element } = blockPlaceholders[blockId];

			// Append the template/content to the element
			// If content is already available, use it, otherwise use the template
			element.append(content ? content : template.cloneNode(true));

			// Add listener to form submit
			const form = element.querySelector("form");
			if (form) {
				form.addEventListener("submit", async (event) => {
					event.preventDefault();
					const input = element.querySelector(
						"input[type='password']",
					);
					const errorEl = element.querySelector("[role='alert']");

					// Reset form inputs attributes to default
					input.setAttribute("aria-invalid", false);
					errorEl.hidden = true;

					const isLegacy = !!postId;
					const apiUrlVersion = isLegacy ? 'v1' : 'v2';
					const apiData = {
						block_id: blockId,
						location: location.pathname,
						password: input.value,
					}
					if ( isLegacy ) {
						// Legacy mode requires po
						apiData.post_id = postId;
					}
					// Call Password Block endpoint
					const blocks = await callApi( `${apiUrlVersion}/blocks-pwd`, apiData );
					if (blocks && blocks.success && blocks.data) {
						insertContentToDom(element, blocks.data);
						blockPlaceholders[blockId] = {
							...blockPlaceholders[blockId],
							content: blocks.data,
						};
					} else {
						// Show password error message element
						if (blocks && blocks.data) {
							input.setAttribute("aria-invalid", true);
							errorEl.hidden = false;
						} else {
							// data is null maybe the html code is already been removed then let's remove the web component from the DOM and array placeholders
							element.remove();
							blockPlaceholders[blockId] = undefined;
						}
					}
				});
			}
		});
	}

	function insertContentToDom(element, data) {
		const { nodeScriptReplace } = PersonalizeWP.utils;
		const placeholderContainer = element.parentNode;
		let container = document.createElement("div");
		// Set the inner content of the div. This sets the API response as a string and is parsed as DOM elements, but doesn't process scripts.
		container.innerHTML = data;
		// Re-Process the element to restore any <script>s
		container = nodeScriptReplace(container);

		// Finally replace the web component placeholder in the DOM with the new elements' children, as there could be many elements.
		element.replaceWith(...container.childNodes);

		// Allow triggering functionality when individual blocks are inserted.
		const blockEvent = new CustomEvent("PWP:parsePlaceholder", {
			bubbles: true,
			cancelable: true,
			detail: {
				container: placeholderContainer,
			},
		});
		placeholderContainer.dispatchEvent(blockEvent);

		// Re-trigger standard browser event for any setup that plugins might be doing.
		document.dispatchEvent(new CustomEvent("DOMContentLoaded"));

		// Allow triggering functionality when batches of blocks are inserted.
		const batchEvent = new CustomEvent("PWP:parsedPlaceholders", {
			bubbles: true,
			cancelable: true,
		});
		document.dispatchEvent(batchEvent);
	}

	/**
	 * Called automatically by PersonalizeWP after module has been initiated.
	 */
	function moduleReady() {
		populatePlaceholders();
	}

	/**
	 * Called automatically once PersonalizeWP is available for loading this module.
	 */
	function readyInit() {
		// Double check
		if ( window.PersonalizeWP ) {
			PersonalizeWP.module('pwd-blocks', this);
		}
	}

	// Export the public functions of Password Blocks
	exports.ready = moduleReady;
	exports.readyInit = readyInit;

	return exports;
})({});

// Check and delay until PersonalizeWP object available.
ready(pwdBlocks);
