const globalConfig = {"lsUIKeys":["_ud"],"ckUIKeys":[""],"urlUIParamKeys":[""],"aISelectors":[],"fProviders":["calendly","typeform"]};
// Ensure the document is loaded before initializing

/*************************** Intialization Logic  ************************/
// globalConfig is injected before response to page

console.log("*****Script Loaded and running*****");

function initWhenReady() {
	if (documentIsReady()) {
		attemptToInit();
	} else {
		document.addEventListener("DOMContentLoaded", attemptToInit);
	}
}

function documentIsReady() {
	return (
		document.readyState === "complete" ||
		(document.readyState !== "loading" && !document.documentElement.doScroll)
	);
}

function attemptToInit() {
	if (weNavIsReady()) {
		initMain();
	} else {
		document.removeEventListener("DOMContentLoaded", attemptToInit);
		enqueInitTillWeNavReady();
	}
}
const weNavIsReady = () => {
	console.log("weNavIsReady");
	return (
		typeof window.weNav !== "undefined" &&
		window.weNav?.getState()?.context?.initialized &&
		typeof window.weNav?.getState()?.user?.anonymousId === "string"
	);
};

function enqueInitTillWeNavReady() {
	window.weNavQ = window.weNavQ || [];

	(window.jitsuQ = window.jitsuQ || []).push(function (wenav) {
		//send events to Jitsu here
		wenav.on("ready", initMain);
	});
}

const initMain = () => {
	const dataAttributes = getDataAttributesFromScript();

	const {
		localStorageUserIDKeys,
		cookieUserIDKeys,
		urlEmailParams,
		anonymousIdInputSelectors,
		formProviders,
	} = validateAndParseDataAttributes(dataAttributes);

	identifyEmailFromStorage(localStorageUserIDKeys);
	identifyEmailFromURL(urlEmailParams);
	identifyUserOnBlur();
	preFillHiddenDomainIdInput(anonymousIdInputSelectors);
	providersAppendUtmTerm(formProviders);
	initializeGlobalWindowMethods(anonymousIdInputSelectors, formProviders);

	initShopify();
};

const initializeGlobalWindowMethods = (
	anonymousIdInputSelectors,
	formProviders
) => {
	window.weNavGlobal = {
		reInitializeForPopup: ((selectors, providers) => {
			return function () {
				identifyUserOnBlur();
				preFillHiddenDomainIdInput(selectors);
				providersAppendUtmTerm(providers);
			};
		})(anonymousIdInputSelectors, formProviders),
	};
};

const initShopify = async () => {
	if (!window.Shopify) {
		return;
	}

	try {
		let cart = await fetch(window.Shopify.routes.root + "cart.js", {
			method: "GET",
		})
			.then((response) => {
				return response.json();
			})
			.catch((error) => {
				console.error("Error:", error);
			});

		let cartAttributes = cart.attributes || {};
		let anonymousId = weNav?.user()?.anonymousId;
		let cartAnonymousId = cartAttributes.weNavID;

		if (cartAnonymousId === anonymousId || !anonymousId) {
			return;
		}

		cartAttributes.weNavID = anonymousId;

		var formData = new FormData();
		for (let key in cartAttributes) {
			if (cartAttributes.hasOwnProperty(key)) {
				formData.append(`attributes[${key}]`, cartAttributes[key]);
			}
		}

		await fetch(window.Shopify.routes.root + "cart/update.js", {
			method: "POST",
			body: formData,
		})
			.then((response) => response.json())
			.then((data) => console.log(data));
	} catch (error) {
		console.error("Error initializing Shopify:", error);
	}
};

// const getCookie = (name) => {
// 	const value = `; ${document.cookie}`;
// 	const parts = value.split(`; ${name}=`);
// 	if (parts.length === 2) return parts.pop().split(";").shift();
// };

// const getWeNavShopifyFromStorage = () => {
// 	const weNavShopify =
// 		localStorage.getItem("weNavShopify") || getCookie("weNavShopify");
// 	return weNavShopify;
// };

/* Main Global Methods */
const identifyEmailFromStorage = (localStorageKeys) => {
	let identifiedEmail = null;

	// Iterate over each local storage key to find a valid email
	for (let key of localStorageKeys) {
		const value = localStorage.getItem(key);

		if (value) {
			try {
				// Attempt to parse the stored JSON, if applicable
				const parsedValue = JSON.parse(value);
				// Check for a valid email, either in the parsed object or directly in the value
				const potentialEmail =
					typeof parsedValue === "string" ? parsedValue : parsedValue.email;

				if (isValidEmail(potentialEmail)) {
					identifiedEmail = potentialEmail;
					break; // Exit loop on first valid email found
				}
			} catch (e) {
				// Fallback for values that aren't JSON strings
				if (isValidEmail(value)) {
					identifiedEmail = value;
					break; // Exit loop on first valid email found
				}
			}
		}
	}

	// If a valid email is identified, call the identify method
	if (identifiedEmail) {
		weNav.identify(
			identifiedEmail,
			{ email: identifiedEmail },
			{ anonymousId: weNav.user().anonymousId }
		);
	}
};

const identifyEmailFromURL = () => {
	const urlEmailParams = ["email", "invitee_email", "mail", "username"];
	const urlPhoneParams = ["phone", "invitee_phone", "mobile"];

	const urlParams = new URLSearchParams(window.location.search);
	const email = urlEmailParams.find((param) => urlParams.has(param));
	const phone = urlPhoneParams.find((param) => urlParams.has(param));

	if (email && isValidEmail(urlParams.get(email))) {
		weNav.identify(
			urlParams.get(email),
			{ email: urlParams.get(email) },
			{ anonymousId: weNav.user().anonymousId }
		);
	}
	if (phone && isValidPhone(urlParams.get(phone))) {
		weNav.identify({ phone: urlParams.get(phone) });
	}
};

const identifyUserOnBlur = (
	emailInputSelectors = [],
	phoneInputSelectors = []
) => {
	const defaultEmailInputSelectors = [
		"input[type=email]",
		"input[type=text][name=email]",
		"input[type=text][name=username]",
		"input[type=text][name=mail]",
		"input[type=text][name=email_address]",
		"input[type=text][name=emailAddress]",
		"input[type=text][name=Email]",
	];

	const defaultPhoneInputSelectors = [
		"input[type=tel]",
		"input[type=text][name=phone]",
		"input[type=text][name=mobile]",
		"input[type=text][name=phoneNumber]",
		"input[type=text][name=phoneNumber]",
		"input[type=text][name=phone_number]",
		"input[type=text][name=phoneNo]",
		"input[type=text][name=phone_no]",
		"input[type=text][name=phoneNum]",
		"input[type=text][name=phone_number]",
	];

	const allEmailSelectors = emailInputSelectors.concat(
		defaultEmailInputSelectors
	);

	const allPhoneSelectors = phoneInputSelectors.concat(
		defaultPhoneInputSelectors
	);

	// Function to add blur event listeners to input fields
	const addBlurListeners = (inputField, type) => {
		if (!inputField._hasBlurListener) {
			if (type === "email") {
				inputField.addEventListener("blur", function () {
					const email = this.value;
					if (isValidEmail(email)) {
						weNav.identify(
							email,
							{ email },
							{ anonymousId: weNav.user().anonymousId }
						);
					}
				});
			} else if (type === "phone") {
				inputField.addEventListener("blur", function () {
					const phone = this.value;
					if (isValidPhone(phone)) {
						weNav.identify({ phone });
					}
				});
			}
			inputField._hasBlurListener = true; // Mark that the listener has been added
		}
	};

	// Add blur event listeners to existing input fields
	allEmailSelectors.forEach((selector) => {
		document.querySelectorAll(selector).forEach((inputField) => {
			addBlurListeners(inputField, "email");
		});
	});

	allPhoneSelectors.forEach((selector) => {
		document.querySelectorAll(selector).forEach((inputField) => {
			addBlurListeners(inputField, "phone");
		});
	});

	// Set up the MutationObserver to watch for new elements
	const observer = new MutationObserver((mutationsList) => {
		mutationsList.forEach((mutation) => {
			if (mutation.type === "childList") {
				mutation.addedNodes.forEach((node) => {
					if (node.nodeType === Node.ELEMENT_NODE) {
						// Check for email inputs in the newly added nodes
						allEmailSelectors.forEach((selector) => {
							node.querySelectorAll(selector).forEach((inputField) => {
								addBlurListeners(inputField, "email");
							});
						});

						// Check for phone inputs in the newly added nodes
						allPhoneSelectors.forEach((selector) => {
							node.querySelectorAll(selector).forEach((inputField) => {
								addBlurListeners(inputField, "phone");
							});
						});
					}
				});
			}
		});
	});

	// Specify the target node and the observer options
	const targetNode = document.body;
	const config = { childList: true, subtree: true };

	// Start observing the target node for configured mutations
	observer.observe(targetNode, config);
};

const preFillHiddenDomainIdInput = (selectors = []) => {
	const defaultSelectors = [
		"[name=we_nav_d]",
		".we_nav_d",
		"[name=we_nav_ai]",
		".we_nav_ai",
		"[data-q=we_nav_ai]",
	];
	const allSelectors = selectors.concat(defaultSelectors);

	allSelectors.forEach((selector) => {
		const element = document.querySelector(selector);
		if (element) {
			element.type = "hidden";
			element.value = weNav.user().anonymousId;
		}
	});
};

const validateAndParseDataAttributes = (dataAttributes) => {
	const optionalKeys = [
		"lsUIKeys",
		"ckUIKeys",
		"urlUIParamKeys",
		"aISelectors",
		"fProviders",
	];
	const parsedAttributes = {};

	optionalKeys.forEach((key) => {
		try {
			// Attempt to parse; use empty array as fallback if undefined or invalid JSON
			parsedAttributes[key] = JSON.parse(dataAttributes[key] || "[]");
		} catch (e) {
			console.warn(
				`Warning: Invalid JSON for key '${key}'. Using empty array as fallback.`
			);
			parsedAttributes[key] = []; // Use empty array as fallback for invalid JSON
		}
	});

	return {
		localStorageUserIDKeys: parsedAttributes["lsUIKeys"],
		cookieUserIDKeys: parsedAttributes["ckUIKeys"],
		urlEmailParams: parsedAttributes["urlUIParamKeys"],
		anonymousIdInputSelectors: parsedAttributes["aISelectors"],
		formProviders: parsedAttributes["fProviders"],
	};
};

const getDataAttributesFromScript = () => ({
	lsUIKeys: globalConfig.lsUIKeys || "[]",
	ckUIKeys: globalConfig.ckUIKeys || "[]",
	urlUIParamKeys: globalConfig.urlUIParamKeys || "[]",
	aISelectors: globalConfig.aISelectors || "[]",
	fProviders: globalConfig.fProviders || "[]",
});

const isValidEmail = (email) => {
	const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
	return emailRegex.test(email);
};

const isValidPhone = (phone) => {
	const startsWithPlus = phone.startsWith("+");

	const normalizedPhone = phone
		.replace(/[^0-9]/g, "") // Remove all non-digit characters
		.replace(/^0+/, ""); // Remove leading zeros

	const formattedPhone = startsWithPlus
		? "+" + normalizedPhone
		: normalizedPhone;

	const phoneRegex = /^\+?[0-9]{1,15}$/;

	return phoneRegex.test(formattedPhone);
};

/****** Provider UTM Term Appending  ******/

const providersAppendUtmTerm = (providers = []) => {
	providers.forEach((provider) => {
		try {
			if (provider === "typeform") {
				typeformAppendUtmTerm();
			} else if (provider === "calendly") {
				calendlyAppendUtmTerm();
			}
		} catch (error) {
			console.error(`Error appending UTM term for ${provider}:`, error);
		}
	});
};

const typeformAppendUtmTerm = () => {
	try {
		const anonymousId = weNav.user()?.anonymousId;
		if (!anonymousId) {
			console.warn("Anonymous ID is not available.");
			return;
		}
		const typeformIframes = document.querySelectorAll(
			'iframe[src*="typeform.com"]'
		);
		typeformIframes.forEach((iframe) => {
			const url = new URL(iframe.src);
			url.searchParams.append("utm_term", anonymousId);
			iframe.setAttribute("src", url.toString());
		});
	} catch (error) {
		console.error("Error appending UTM term to Typeform iframes:", error);
	}
};

const calendlyAppendUtmTerm = () => {
	try {
		const anonymousId = weNav.user()?.anonymousId;
		if (!anonymousId) {
			console.warn("Anonymous ID is not available.");
			return;
		}
		const calendlyIframes = document.querySelectorAll(
			'iframe[src*="calendly.com"]'
		);
		calendlyIframes.forEach((iframe) => {
			const url = new URL(iframe.src);
			url.searchParams.append("utm_term", anonymousId);
			iframe.setAttribute("src", url.toString());
		});
	} catch (error) {
		console.error("Error appending UTM term to Calendly iframes:", error);
	}
};

(() => {
	initWhenReady();
})();
