/**
 * Ontario Design System - Dynamic Sign-In Menu Manager
 *
 * This sample demonstrates how to dynamically generate 'Sign in' menu items
 * based on API data or other criteria.
 *
 * IMPORTANT: This script must load and run BEFORE ontario-header.js initializes.
 * Include this script in your HTML before the ontario-header.js script:
 *
 * <script src="ontario-sign-in-menu-dynamic.js"></script>
 * <script src="ontario-header.js"></script>
 *
 * Features:
 * - Fetches sign-in links from your API endpoint
 * - Dynamically renders menu items from data
 * - Maintains accessibility standards (ARIA roles, keyboard navigation)
 *
 */

(function () {
	'use strict';

	/* ===========================
        Configuration
	=========================== */

	/**
	 * API endpoint for fetching sign-in menu items
	 * Replace with your actual API endpoint and authentication method
	 */
	const API_CONFIG = {
		// For local testing, use the demo JSON file served by the dev server.
		endpoint: '/demos/sign-in-menu-dynamic/sign-in-menu.json',
		timeout: 15000,
	};

	/* ===========================
        DOM Elements
	=========================== */

	// Desktop sign-in menu
	const desktopSignInList = document.getElementById('sign-in-menu-list');
	const desktopSignInNav = desktopSignInList ? desktopSignInList.closest('.ontario-sign-in-navigation') : null;

	// Mobile sign-in menu
	const mobileSignInPanel = document.getElementById('ontario-mobile-menu-panel-sign-in');
	const mobileSignInList = mobileSignInPanel?.querySelector('[role="menu"]');
	const mobileSignInTab = document.getElementById('ontario-mobile-menu-tab-sign-in');

	// Debug: Log if elements were found
	if (!desktopSignInList) {
		console.warn('⚠️ Desktop sign-in menu list not found (id="sign-in-menu-list")');
	}
	if (!mobileSignInList) {
		console.warn('⚠️ Mobile sign-in menu list not found (checked id="ontario-mobile-sign-in-menu-list" and panel role="menu")');
	}

	/* ===========================
        Data Management
	=========================== */

	function setSignInMenuVisibility(isVisible) {
		if (desktopSignInNav) desktopSignInNav.hidden = !isVisible;
		if (mobileSignInPanel) mobileSignInPanel.hidden = !isVisible;
		if (mobileSignInTab) {
			mobileSignInTab.setAttribute('aria-hidden', isVisible ? 'false' : 'true');
			mobileSignInTab.tabIndex = isVisible ? 0 : -1;
		}
	}

	/**
	 * Fetches sign-in menu items from the API
	 * @param {boolean} useApi - Whether to attempt API fetch
	 * @returns {Promise<Array>} Array of menu item objects
	 */
	async function fetchSignInMenuItems(useApi = false) {
		// No default items: if useApi is false, return empty
		if (!useApi) {
			return [];
		}

		if (!API_CONFIG.endpoint) {
			console.warn('⚠️ Sign-in menu endpoint not configured. Menu will be hidden.');
			return [];
		}

		// Attempt to fetch from API
		try {
			const controller = new AbortController();
			const timeoutId = setTimeout(() => controller.abort(), API_CONFIG.timeout);

			const response = await fetch(API_CONFIG.endpoint, {
				signal: controller.signal,
			});

			clearTimeout(timeoutId);

			if (!response.ok) {
				throw new Error(`API request failed with status ${response.status}`);
			}

			const data = await response.json();

			// Validate and transform API response
			const validatedItems = validateMenuItems(data.items || data);
			return validatedItems;
		} catch (error) {
			console.warn('⚠️ Failed to fetch sign-in menu items from API:', error.message);
			return [];
		}
	}

	/**
	 * Validates menu item data structure
	 * @param {Array} items - Array of menu items to validate
	 * @returns {Array} Validated menu items
	 */
	function validateMenuItems(items) {
		if (!Array.isArray(items)) {
			console.error('Invalid menu items data: expected array');
			return [];
		}

		return items.filter(item => {
			const isValid = item && typeof item === 'object' && item.id && item.label && item.url;

			if (!isValid) {
				console.warn('Invalid menu item skipped:', item);
			}

			return isValid;
		});
	}

	/* ===========================
        Menu Item Rendering
	=========================== */

	/**
	 * Creates a sign-in menu item element
	 * @param {Object} item - Menu item data
	 * @param {boolean} isMobile - Whether this is for mobile menu
	 * @returns {HTMLElement} Menu item list element
	 */
	function createMenuItem(item, isMobile = false) {
		const li = document.createElement('li');
		li.className = 'ontario-header-navigation__menu-item';
		li.setAttribute('role', 'none');
		li.dataset.menuItemId = item.id;

		const link = document.createElement('a');
		link.href = item.url;
		link.setAttribute('role', 'menuitem');

		// Create label
		const labelSpan = document.createElement('span');
		labelSpan.className = 'ontario-header-navigation__menu-item-label';
		labelSpan.textContent = item.label;

		link.appendChild(labelSpan);

		// Add description if available
		if (item.description) {
			const descSpan = document.createElement('span');
			descSpan.className = 'ontario-header-navigation__menu-item-description';
			descSpan.id = `${item.id}-desc`;
			descSpan.textContent = item.description;
			link.appendChild(descSpan);

			// Link description to label for screen readers
			link.setAttribute('aria-describedby', `${item.id}-desc`);
		}

		li.appendChild(link);

		return li;
	}

	/**
	 * Renders menu items into the specified container
	 * @param {HTMLElement} container - Menu list container
	 * @param {Array} items - Menu items to render
	 * @param {boolean} isMobile - Whether this is for mobile menu
	 */
	function renderMenuItems(container, items, isMobile = false) {
		if (!container) return;

		// Clear existing items
		container.innerHTML = '';

		// Create and append menu items
		items.forEach(item => {
			const menuItem = createMenuItem(item, isMobile);
			container.appendChild(menuItem);
		});
	}

	/* ===========================
        Public API
	=========================== */

	/**
	 * Initializes the dynamic sign-in menu
	 * @param {Object} options - Configuration options
	 * @param {boolean} options.useApi - Set to true to fetch from your API
	 */
	async function initializeDynamicSignInMenu(options = {}) {
		const { useApi = false } = options;

		try {
			// Get menu items - uses mock data by default for this demo
			const menuItems = await fetchSignInMenuItems(useApi);

			if (!menuItems || menuItems.length === 0) {
				setSignInMenuVisibility(false);
				return [];
			}

			setSignInMenuVisibility(true);

			// Render to desktop menu
			if (desktopSignInList) {
				renderMenuItems(desktopSignInList, menuItems, false);
			}

			// Render to mobile menu
			if (mobileSignInList) {
				renderMenuItems(mobileSignInList, menuItems, true);
			}

			// Dispatch event to notify that menu is ready
			// This allows ontario-header.js to re-initialize if needed
			window.dispatchEvent(new CustomEvent('ontarioSignInMenuReady', { detail: { items: menuItems } }));

			return menuItems;
		} catch (error) {
			console.error('Failed to initialize dynamic sign-in menu:', error);
			setSignInMenuVisibility(false);
			return [];
		}
	}

	/* ===========================
        Expose Public API
	=========================== */

	// Expose to global scope for implementers
	window.OntarioSignInMenu = {
		initialize: initializeDynamicSignInMenu,
	};

	/* ===========================
        Auto-initialization
	=========================== */

	// Auto-initialize when DOM is ready
	// IMPORTANT: This must run before ontario-header.js initializes
	if (document.readyState === 'loading') {
		document.addEventListener('DOMContentLoaded', async () => {
			await initializeDynamicSignInMenu({ useApi: true });
		});
	} else {
		// DOM already loaded - initialize immediately
		initializeDynamicSignInMenu({ useApi: true });
	}
})();
