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

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

	const userPlaceholders = [];

	// Web Component for User Data
	class PWPUserData extends HTMLElement {
		connectedCallback() {
			if (this.user_data) {
				if (undefined === userPlaceholders[this.user_data]) {
					userPlaceholders[this.user_data] = {
						elements: [],
					};
				}
				// Placeholders are grouped by their data key
				userPlaceholders[this.user_data].elements.push(this);
			}
		}

		get user_data() {
			return this.getAttribute('data');
		}
	}
	window.customElements.define('pwp-user-data', PWPUserData);

	let user = null,
		userData = {};

	/**
	 * Parse DOM placeholders for visitor data content
	 */
	async function populatePlaceholders() {
		const { callApi } = PersonalizeWP.utils;
		const dataKeys = Object.keys(userPlaceholders);

		if (dataKeys && dataKeys.length > 0) {
			// Filter out any data already retrieved.
			const filteredKeys = dataKeys.filter(
				(key) => !(key in userData),
			);

			// Request any data not retrieved.
			// Let's only call the visitor data if we have any dataKeys need to retrieve
			if (filteredKeys.length > 0) {
				const { data } = await callApi('v1/visitor-data', {
					uid: user.id,
					data: filteredKeys,
				});
				// Loop through response, setting values against this.userData
				userData = { ...userData, ...data };
			}
		}

		// Loop through each placeholder item, setting the innerText to what is stored within userData.
		dataKeys.forEach((dataKey) => {
			const elements = userPlaceholders[dataKey].elements;

			elements.forEach((placeholder) => {
				const dataKey = placeholder.getAttribute("data");
				if (userData[dataKey]) {
					placeholder.innerText = userData[dataKey];
				}
			});
		});
	}

	/**
	 * Validates a user object
	 * @param {object} u User
	 * @returns
	 */
	function validateUser(u) {
		if (null !== u && Object.hasOwn(u,'id') && '' !== u?.id) {
			return true;
		}
		return false;
	}

	/**
	 * Initiates the module once PersonaliseWP has loaded.
	 */
	function moduleInit() {
		const { pwpGet } = PersonalizeWP.utils;
		// Grab the user and store internally for further use.
		user = pwpGet("tracked_user", true, "pwp");
		if (validateUser(user)) {
			// track against any PWP block changes to re-process
			window.addEventListener("PWP:parsedPlaceholders", () => {
				populatePlaceholders();
			});
		}
	}

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

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

	// Export the public functions of Visitor Data
	exports.init = moduleInit;
	exports.ready = moduleReady;
	exports.readyInit = readyInit;

	return exports;
})({});

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