/**
 * UI Selection Modal for MPV.Rocks Installer
 * Handles UI overlay selection (UOSC, ModernZ, None) for installation and change
 *
 * Integrates with:
 * - Install system (install.js)
 * - Job system (jobs.js)
 * - Toast notifications (toast.js)
 */

(function () {
	"use strict";

	// State for pending install/change operations
	let pendingData = null;
	let isConfirming = false; // Debounce flag

	/**
	 * Show UI selection modal for new installation
	 * @param {string} methodId - The installation method ID
	 * @param {string} appName - The application name
	 * @param {HTMLElement} button - The install button element
	 */
	async function showUISelectModalForInstall(methodId, appName, button) {
		try {
			// Check if this method needs UI selection via API
			const response = await fetch(
				`/api/ui/options?method_id=${encodeURIComponent(methodId)}&app_name=${encodeURIComponent(appName)}`,
			);

			if (!response.ok) {
				throw new Error(`HTTP error! status: ${response.status}`);
			}

			const data = await response.json();

			if (!data.needs_ui_selection) {
				// No UI selection needed, proceed with default (ModernZ)
				await performInstallWithUI(methodId, "modernz", button);
				return;
			}

			// Store pending data for install
			pendingData = { methodId, appName, button, isChange: false };

			// Reset and show modal
			resetModalForInstall();
			showModal(appName);
		} catch (error) {
			console.error("[UISelect] Error checking UI options:", error);
			// Fallback: proceed with default UI
			await performInstallWithUI(methodId, "modernz", button);
		}
	}

	/**
	 * Show UI selection modal for changing UI on installed app
	 * @param {string} appName - The application name
	 * @param {string} currentUI - The current UI type (uosc, modernz, or empty)
	 */
	async function showUISelectModalForChange(appName, currentUI) {
		// Store pending data for change
		pendingData = { appName, isChange: true };

		// Reset and show modal
		resetModalForChange();
		showModal(appName);

		// Pre-select current UI
		const currentUIValue = currentUI || "modernz";
		const currentInput = document.querySelector(
			`input[name="ui-type"][value="${currentUIValue}"]`,
		);
		if (currentInput) {
			currentInput.checked = true;
			updateSelectedOption(currentUIValue);
		}
	}

	/**
	 * Reset modal for install mode
	 */
	function resetModalForInstall() {
		if (!pendingData) return;
		pendingData.isChange = false;

		const confirmText = document.getElementById("ui-modal-confirm-text");
		const confirmBtn = document.getElementById("ui-modal-confirm");

		if (confirmText) confirmText.textContent = "Install";
		if (confirmBtn) {
			confirmBtn.innerHTML =
				'<i class="bx bx-archive-arrow-down"></i> <span id="ui-modal-confirm-text">Install</span>';
		}

		// Reset to ModernZ (recommended)
		const modernzInput = document.querySelector(
			'input[name="ui-type"][value="modernz"]',
		);
		if (modernzInput) {
			modernzInput.checked = true;
			updateSelectedOption("modernz");
		}
	}

	/**
	 * Reset modal for change mode
	 */
	function resetModalForChange() {
		if (!pendingData) return;
		pendingData.isChange = true;

		const confirmBtn = document.getElementById("ui-modal-confirm");
		if (confirmBtn) {
			confirmBtn.innerHTML =
				'<i class="bx bx-analyze"></i> <span id="ui-modal-confirm-text">Change UI</span>';
		}
	}

	/**
	 * Show the modal
	 * @param {string} appName - The application name to display
	 */
	function showModal(appName) {
		const modal = document.getElementById("ui-select-modal");
		const appNameEl = document.getElementById("ui-modal-app-name");

		if (appNameEl) {
			appNameEl.textContent = appName;
		}

		if (modal) {
			modal.classList.remove("hidden", "closing");
			modal.classList.add("flex");

			// Focus the first radio button for accessibility
			const firstRadio = modal.querySelector('input[name="ui-type"]');
			if (firstRadio) {
				setTimeout(() => firstRadio.focus(), 100);
			}
		}
	}

	/**
	 * Hide the modal
	 */
	function hideModal() {
		const modal = document.getElementById("ui-select-modal");

		if (modal) {
			modal.classList.add("closing");
			setTimeout(() => {
				modal.classList.add("hidden");
				modal.classList.remove("flex", "closing");
			}, 200);
		}

		pendingData = null;
	}

	/**
	 * Update the selected option visual state
	 * @param {string} uiType - The selected UI type
	 */
	function updateSelectedOption(uiType) {
		document.querySelectorAll(".ui-option").forEach((option) => {
			option.classList.remove("selected");
			if (option.dataset.uiType === uiType) {
				option.classList.add("selected");
			}
		});
	}

	/**
	 * Confirm the UI selection and execute action
	 */
	async function confirmUISelection() {
		// Prevent double-clicks
		if (isConfirming) return;
		if (!pendingData) return;

		isConfirming = true;

		// Disable confirm button immediately
		const confirmBtn = document.getElementById("ui-modal-confirm");
		if (confirmBtn) {
			confirmBtn.disabled = true;
			confirmBtn.innerHTML =
				'<i class="bx bx-loader-alt bx-spin"></i> Processing...';
		}

		const selectedUI =
			document.querySelector('input[name="ui-type"]:checked')?.value ||
			"modernz";
		const { methodId, appName, installMethod, button, isChange, isAdopt } =
			pendingData;

		try {
			hideModal();

			if (isAdopt) {
				await performAdoptApp(appName, installMethod, selectedUI);
			} else if (isChange) {
				await performUIChange(appName, selectedUI);
			} else {
				await performInstallWithUI(methodId, selectedUI, button);
			}
		} finally {
			isConfirming = false;
		}
	}

	/**
	 * Perform installation with selected UI
	 * @param {string} methodId - The installation method ID
	 * @param {string} uiType - The selected UI type
	 * @param {HTMLElement} button - The install button element
	 * @param {boolean} skipPasswordCheck - If true, skip password check (used by callback)
	 */
	async function performInstallWithUI(
		methodId,
		uiType,
		button,
		skipPasswordCheck = false,
	) {
		// Check if this method requires sudo and we need to prompt for password
		const requiresSudo = button?.dataset?.requiresSudo === "true";
		console.log(
			"[UISelect] Debug - methodId:",
			methodId,
			"requiresSudo:",
			requiresSudo,
			"PasswordModal exists:",
			!!window.PasswordModal,
			"skipPasswordCheck:",
			skipPasswordCheck,
		);

		if (!skipPasswordCheck && requiresSudo && window.PasswordModal) {
			// Ensure password is available before proceeding
			const hasPassword = await window.PasswordModal.ensurePassword(
				methodId,
				() => {
					// This callback is executed after password is confirmed
					// Re-call this function with skipPasswordCheck=true
					performInstallWithUI(methodId, uiType, button, true);
				},
			);

			// If modal was shown (no password stored), return and wait for callback
			if (!hasPassword) {
				console.log("[UISelect] Password modal shown, waiting for user input");
				return;
			}
		}

		// Check if job manager is available (new system)
		if (window.startInstallJobWithUI) {
			try {
				const job = await window.startInstallJobWithUI(methodId, uiType, false);
				console.log("[UISelect] Install job started:", job);

				// Show progress indicator on the button
				if (button) {
					button.disabled = true;
					button.dataset.originalText = button.innerHTML;
					button.innerHTML =
						'<i class="bx bx-loader-alt bx-spin"></i> Installing...';
					button.dataset.jobId = job.id;
				}

				// Register callback for job completion
				if (window.jobManager) {
					window.jobManager.onJobComplete(job.id, (completedJob) => {
						if (button) {
							button.disabled = false;
							button.innerHTML =
								button.dataset.originalText ||
								'<i class="bx bx-archive-arrow-down"></i> Install';
							delete button.dataset.jobId;
						}
					});
				}
			} catch (error) {
				console.error("[UISelect] Error starting install job:", error);
				if (button) {
					button.disabled = false;
					button.innerHTML =
						button.dataset.originalText ||
						'<i class="bx bx-archive-arrow-down"></i> Install';
				}
			}
			return;
		}

		// Fallback to legacy install
		console.log("[UISelect] Using legacy install system");

		try {
			const response = await fetch("/api/install", {
				method: "POST",
				headers: { "Content-Type": "application/json" },
				body: JSON.stringify({
					method_id: methodId,
					ui_type: uiType,
				}),
			});

			if (!response.ok) {
				throw new Error(`HTTP error! status: ${response.status}`);
			}

			const data = await response.json();
			console.log("[UISelect] Install started:", data);
		} catch (error) {
			console.error("[UISelect] Error starting installation:", error);
			if (window.showToast) {
				window.showToast(
					"Failed to start installation: " + error.message,
					"error",
				);
			}
		}
	}

	/**
	 * Perform UI change for installed app
	 * @param {string} appName - The application name
	 * @param {string} uiType - The new UI type
	 */
	async function performUIChange(appName, uiType) {
		try {
			const response = await fetch("/api/ui/change", {
				method: "POST",
				headers: { "Content-Type": "application/json" },
				body: JSON.stringify({
					app_name: appName,
					ui_type: uiType,
				}),
			});

			if (!response.ok) {
				throw new Error(`HTTP error! status: ${response.status}`);
			}

			const data = await response.json();
			console.log("[UISelect] UI change started:", data);

			// Show job progress if job system is available
			if (data.job_id && window.showJobOutput) {
				window.showJobOutput(data.job_id);
			} else if (data.session_id) {
				// Legacy session-based system
				console.log("[UISelect] Session ID:", data.session_id);
			}

			// Show toast
			if (window.showToast) {
				window.showToast(`Changing UI to ${uiType}...`, "info");
			}
		} catch (error) {
			console.error("[UISelect] Error changing UI:", error);
			if (window.showToast) {
				window.showToast("Failed to change UI: " + error.message, "error");
			}
		}
	}

	/**
	 * Initialize event handlers
	 */
	function init() {
		// Handle install button clicks - intercept for UI selection
		document.body.addEventListener(
			"click",
			async (e) => {
				const installButton = e.target.closest("[data-install]");
				if (installButton) {
					// Check if this is being handled by install.js
					// We intercept before install.js by checking if we should show UI selection
					const methodId = installButton.dataset.methodId;
					const appName = installButton.dataset.appName || methodId;

					// Only intercept if not already processing
					if (installButton.disabled) return;

					// Methods that need UI selection (MPV binary installs on all platforms)
					const methodsNeedingUI = [
						"mpv-binary", // Windows
						"mpv-binary-v3", // Windows v3
						"mpv-app", // macOS app bundle
					];

					// Prevent install.js from handling this immediately (for ALL methods)
					// This prevents the race condition that causes 409 errors
					e.preventDefault();
					e.stopPropagation();

					// Disable button to prevent double-clicks during async operations
					installButton.disabled = true;
					installButton.dataset.originalText = installButton.innerHTML;
					installButton.innerHTML =
						'<i class="bx bx-loader-alt bx-spin"></i> Loading...';

					if (methodsNeedingUI.includes(methodId)) {
						// Show UI selection modal
						try {
							await showUISelectModalForInstall(
								methodId,
								appName,
								installButton,
							);
						} catch (error) {
							console.error("[UISelect] Error showing modal:", error);
							// Re-enable button on error
							installButton.disabled = false;
							installButton.innerHTML =
								installButton.dataset.originalText || "Install";
						}
						return;
					}

					// For other methods, check via API if they need UI selection
					try {
						const response = await fetch(
							`/api/ui/options?method_id=${encodeURIComponent(methodId)}&app_name=${encodeURIComponent(appName)}`,
						);
						if (response.ok) {
							const data = await response.json();
							if (data.needs_ui_selection) {
								try {
									await showUISelectModalForInstall(
										methodId,
										appName,
										installButton,
									);
								} catch (error) {
									console.error("[UISelect] Error showing modal:", error);
									installButton.disabled = false;
									installButton.innerHTML =
										installButton.dataset.originalText || "Install";
								}
								return;
							}
						}
					} catch (error) {
						console.warn("[UISelect] Could not check UI options:", error);
					}

					// No UI selection needed - proceed with install directly
					const isUpdate = installButton.dataset.isUpdate === "true";
					const requiresSudo = installButton.dataset.requiresSudo === "true";

					// Check if this method requires sudo and we need to prompt for password
					if (requiresSudo && window.PasswordModal) {
						// Ensure password is available before proceeding
						const hasPassword = await window.PasswordModal.ensurePassword(
							methodId,
							() => {
								// This callback is executed after password is confirmed
								proceedWithInstallJob(installButton, methodId, isUpdate);
							},
						);

						// If modal was shown (no password stored), return and wait for callback
						if (!hasPassword) {
							return;
						}
					}

					// Proceed with install (no sudo needed or password already stored)
					await proceedWithInstallJob(installButton, methodId, isUpdate);
				}
			},
			true,
		); // Use capture phase to intercept before install.js

		/**
		 * Proceed with install job after password check (if needed)
		 */
		async function proceedWithInstallJob(installButton, methodId, isUpdate) {
			try {
				if (window.startInstallJob) {
					const job = await window.startInstallJob(methodId, isUpdate);
					console.log("[UISelect] Install job started:", job);

					// Update button to show progress
					installButton.innerHTML =
						'<i class="bx bx-loader-alt bx-spin"></i> ' +
						(isUpdate ? "Updating..." : "Installing...");
					installButton.dataset.jobId = job.id;

					// Register callback for job completion
					if (window.jobManager) {
						window.jobManager.onJobComplete(job.id, () => {
							setTimeout(() => {
								installButton.disabled = false;
								installButton.innerHTML =
									installButton.dataset.originalText ||
									(isUpdate ? "Update" : "Install");
								delete installButton.dataset.jobId;
							}, 500);
						});
					}
				}
			} catch (error) {
				console.error("[UISelect] Error starting install:", error);
				installButton.disabled = false;
				installButton.innerHTML =
					installButton.dataset.originalText || "Install";

				if (error.status !== 409 && window.showToast) {
					window.showToast(
						error.message || "Failed to start installation",
						"error",
					);
				}
			}
		}

		// Handle change UI button clicks
		document.body.addEventListener("click", (e) => {
			const changeUIButton = e.target.closest("[data-change-ui]");
			if (changeUIButton) {
				e.preventDefault();
				e.stopPropagation();

				const appName = changeUIButton.dataset.appName;
				const currentUI = changeUIButton.dataset.currentUi;
				showUISelectModalForChange(appName, currentUI);
			}
		});

		// Handle adopt/manage button clicks for externally installed apps
		document.body.addEventListener("click", (e) => {
			const adoptButton = e.target.closest("[data-adopt-app]");
			if (adoptButton) {
				e.preventDefault();
				e.stopPropagation();

				const appName = adoptButton.dataset.appName;
				const installMethod = adoptButton.dataset.installMethod;
				console.log("[UISelect] Adopt button clicked:", appName, installMethod);
				showUISelectModalForAdopt(appName, installMethod);
			}
		});

		// Modal close handlers
		document.addEventListener("click", (e) => {
			// Close button
			if (e.target.closest(".ui-modal-close")) {
				hideModal();
				return;
			}

			// Cancel button
			if (e.target.closest(".ui-modal-cancel")) {
				hideModal();
				return;
			}

			// Confirm button
			if (e.target.closest("#ui-modal-confirm")) {
				confirmUISelection();
				return;
			}

			// Click outside modal
			const modal = document.getElementById("ui-select-modal");
			if (e.target === modal) {
				hideModal();
			}
		});

		// Keyboard handlers
		document.addEventListener("keydown", (e) => {
			const modal = document.getElementById("ui-select-modal");
			if (!modal || modal.classList.contains("hidden")) return;

			if (e.key === "Escape") {
				hideModal();
			} else if (e.key === "Enter") {
				confirmUISelection();
			}
		});

		// Handle refresh button click
		const refreshBtn = document.getElementById("refresh-apps-btn");
		if (refreshBtn) {
			refreshBtn.addEventListener("click", async () => {
				// Prevent double-clicks
				if (refreshBtn.disabled) return;

				refreshBtn.disabled = true;
				const icon = refreshBtn.querySelector("i");
				if (icon) {
					icon.classList.add("bx-flashing");
				}

				try {
					await refreshAppsList();
					if (window.showToast) {
						window.showToast("Apps scanned successfully", "success");
					}
				} catch (error) {
					console.error("[UISelect] Error refreshing:", error);
				} finally {
					refreshBtn.disabled = false;
					if (icon) {
						icon.classList.remove("bx-flashing");
					}
				}
			});
		}

		// Option selection visual feedback - use event delegation for robustness
		document.body.addEventListener("click", (e) => {
			const option = e.target.closest(".ui-option");
			if (option) {
				const uiType = option.dataset.uiType;
				if (uiType) {
					updateSelectedOption(uiType);
				}
			}
		});

		// Radio button change handlers - use event delegation for robustness
		document.body.addEventListener("change", (e) => {
			if (e.target.matches('input[name="ui-type"]')) {
				updateSelectedOption(e.target.value);
			}
		});

		// Set initial selected state
		updateSelectedOption("modernz");

		console.log("[UISelect] Initialized");
	}

	/**
	 * Show UI selection modal for adopting an externally installed app
	 * @param {string} appName - The application name
	 * @param {string} installMethod - The install method ID
	 */
	async function showUISelectModalForAdopt(appName, installMethod) {
		console.log("[UISelect] Adopt button clicked for:", appName, installMethod);
		// Store pending data for adopt
		pendingData = { appName, installMethod, isAdopt: true };

		// Reset and show modal
		resetModalForAdopt();
		showModal(appName);
	}

	/**
	 * Reset modal for adopt mode
	 */
	function resetModalForAdopt() {
		if (!pendingData) return;
		pendingData.isAdopt = true;

		const confirmBtn = document.getElementById("ui-modal-confirm");
		if (confirmBtn) {
			confirmBtn.innerHTML =
				'<i class="bx bx-cog"></i> <span id="ui-modal-confirm-text">Manage App</span>';
		}

		// Reset to None (no UI overlay by default for adopt)
		const noneInput = document.querySelector(
			'input[name="ui-type"][value="none"]',
		);
		if (noneInput) {
			noneInput.checked = true;
			updateSelectedOption("none");
		}
	}

	/**
	 * Perform adopt operation for externally installed app
	 * @param {string} appName - The application name
	 * @param {string} installMethod - The install method ID
	 * @param {string} uiType - The selected UI type
	 */
	async function performAdoptApp(appName, installMethod, uiType) {
		try {
			const response = await fetch("/api/apps/adopt", {
				method: "POST",
				headers: { "Content-Type": "application/json" },
				body: JSON.stringify({
					app_name: appName,
					install_method: installMethod,
					ui_type: uiType,
				}),
			});

			if (!response.ok) {
				const error = await response.json();
				throw new Error(
					error.message || `HTTP error! status: ${response.status}`,
				);
			}

			const data = await response.json();
			console.log("[UISelect] Adopt started:", data);

			// Show job progress if job system is available
			if (data.id && window.showJobOutput) {
				window.showJobOutput(data.id);
			}

			// Show toast
			if (window.showToast) {
				window.showToast(`Adopting ${appName}...`, "info");
			}

			// Refresh the apps list after a short delay
			setTimeout(() => {
				refreshAppsList();
			}, 1500);
		} catch (error) {
			console.error("[UISelect] Error adopting app:", error);
			if (window.showToast) {
				window.showToast("Failed to adopt app: " + error.message, "error");
			}
		}
	}

	// Public API
	async function refreshAppsList() {
		try {
			const response = await fetch("/api/apps/refresh-installed", {
				method: "POST",
				headers: { "Content-Type": "application/json" },
			});

			if (!response.ok) {
				throw new Error(`HTTP error! status: ${response.status}`);
			}

			const html = await response.text();

			// Parse the HTML response and update the relevant sections
			const parser = new DOMParser();
			const doc = parser.parseFromString(html, "text/html");

			// Update installed apps list
			const installedAppsList = doc.getElementById("installed-apps-list");
			if (installedAppsList) {
				const currentList = document.getElementById("installed-apps-list");
				if (currentList) {
					currentList.innerHTML = installedAppsList.innerHTML;
				}
			}

			// Update available updates
			const availableUpdates = doc.getElementById("available-updates");
			if (availableUpdates) {
				const currentUpdates = document.getElementById("available-updates");
				if (currentUpdates) {
					currentUpdates.innerHTML = availableUpdates.innerHTML;
				}
			}

			// Update install methods section
			const installMethodsSection = doc.getElementById(
				"install-methods-section",
			);
			if (installMethodsSection) {
				const currentMethods = document.getElementById(
					"install-methods-section",
				);
				if (currentMethods) {
					currentMethods.innerHTML = installMethodsSection.innerHTML;
				}
			}

			console.log("[UISelect] Apps list refreshed successfully");
		} catch (error) {
			console.error("[UISelect] Error refreshing apps list:", error);
			// Fallback to page reload
			window.location.reload();
		}
	}

	// Public API
	window.MPVRocksUISelect = {
		showForInstall: showUISelectModalForInstall,
		showForChange: showUISelectModalForChange,
		showForAdopt: showUISelectModalForAdopt,
		hide: hideModal,
		refreshAppsList: refreshAppsList,
	};

	/**
	 * Helper function for job-based install with UI type
	 * This is called by this module but also exposed for other modules
	 */
	window.startInstallJobWithUI = async function (
		methodId,
		uiType,
		isUpdate = false,
	) {
		const endpoint = isUpdate ? "/api/apps/update/job" : "/api/install/job";

		try {
			const response = await fetch(endpoint, {
				method: "POST",
				headers: {
					"Content-Type": "application/json",
				},
				body: JSON.stringify({
					method_id: methodId,
					ui_type: uiType,
				}),
			});

			if (!response.ok) {
				const error = await response.json();
				throw new Error(
					error.error || `HTTP error! status: ${response.status}`,
				);
			}

			const job = await response.json();
			console.log("[UISelect] Started job with UI:", job);

			// Show progress indicator on the app card if job manager exists
			if (window.jobManager) {
				// Trigger job manager to handle the new job
				// The job will be received via SSE
			}

			return job;
		} catch (error) {
			console.error("[UISelect] Error starting install job:", error);
			if (window.showToast) {
				window.showToast(
					error.message || "Failed to start installation",
					"error",
				);
			}
			throw error;
		}
	};

	// Initialize on DOM ready
	if (document.readyState === "loading") {
		document.addEventListener("DOMContentLoaded", init);
	} else {
		init();
	}
})();
