// AGPL-3.0-only
//
// This is free software for the public good of a permacomputer
// hosted at permacomputer.com, an always-on computer by the people, for the
// people. One which is durable, easy to repair, and distributed like tap water
// for machine learning intelligence.
//
// The permacomputer is community-owned infrastructure optimized around
// four values:
//
//   TRUTH    - First principles, math & science, open source code
//   FREEDOM  - Voluntary partnerships, freedom from tyranny & corporate control
//   HARMONY  - Minimal waste, self-renewing systems with diverse connections
//   LOVE     - Be yourself without hurting others, cooperation through natural law
//
// This software contributes to that vision by making machine learning
// accessible to everyone through a free, open, embeddable chat interface.
// Code is seeds to sprout on any abandoned technology.
//
// Learn more: https://www.permacomputer.com
//
// NO WARRANTY. THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
//
// Copyright 2025-2026 TimeHexOn & foxhop & russell@unturf
// https://www.permacomputer.com

// Translation Modal functionality
import { initializeChunkFiveFont } from "./ui-themes.js";
import { getUIText } from "./ui-translations.js";
import { extractWebpageContent } from "./content.js";
import { translateCurrentPage, translateText, translateHTML, SUPPORTED_LANGUAGES, NATIVE_LANGUAGE_NAMES } from "./translation.js";

// Function to fetch full HTML content from a remote URL using CORS proxy
async function fetchRemotePageHTML(url) {
	try {
		// Auto-add https:// if no scheme is provided
		let normalizedUrl = url.trim();
		if (!normalizedUrl.startsWith('http://') && !normalizedUrl.startsWith('https://')) {
			normalizedUrl = 'https://' + normalizedUrl;
		}
		
		// Validate URL format using regex - more permissive than URL constructor
		const urlPattern = /^https?:\/\/[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*(\.[a-zA-Z]{2,})(:\d+)?(\/[^\s]*)?$/;
		if (!urlPattern.test(normalizedUrl)) {
			throw new Error(`Please enter a valid website URL (e.g., example.com or https://example.com)`);
		}
		
		// Use our CORS proxy at cors-proxy.uncloseai.com with query parameter
		const proxyUrl = `https://cors-proxy.uncloseai.com/api/fetch?uri_target=${encodeURIComponent(normalizedUrl)}`;
		
		const response = await fetch(proxyUrl, {
			method: 'GET',
			headers: {
				'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
			}
		});
		
		if (!response.ok) {
			throw new Error(`Failed to fetch URL via proxy: ${response.status} ${response.statusText}`);
		}
		
		const htmlContent = await response.text();
		
		// Parse the HTML and clean it up like translateCurrentPage does
		const parser = new DOMParser();
		const doc = parser.parseFromString(htmlContent, 'text/html');
		
		// Remove modals and popups that shouldn't be translated
		const modalsToRemove = doc.querySelectorAll(
			'dialog[open], [id*="modal"], [class*="modal"], [class*="popup"], [class*="overlay"]'
		);
		modalsToRemove.forEach((modal) => modal.remove());
		
		// Remove script and noscript elements (but keep styles for layout)
		const scriptsToRemove = doc.querySelectorAll('script, noscript');
		scriptsToRemove.forEach(el => el.remove());
		
		// Return the cleaned full HTML
		return doc.documentElement.outerHTML;
		
	} catch (error) {
		console.error('Remote fetch error:', error);
		throw new Error(`Failed to fetch remote content: ${error.message}`);
	}
}

// Function to translate remote HTML content - reuses translateCurrentPage logic with URL resolution
async function translateRemoteHTML(htmlContent, targetLanguage, sourceUrl) {
	// Use the same translateHTML function but with URL resolution for remote content
	const translatedHTML = await translateHTML(htmlContent, targetLanguage, sourceUrl);
	
	return translatedHTML;
}

export function openTranslateModal() {
	// Load appropriate CSS based on whether we're using PicoCSS or built-in styles
	// Detect if PicoCSS is actually present on the page
	const hasPicoCSS = document.querySelector('link[href*="pico"]') !== null;
	
	// Load appropriate CSS based on actual PicoCSS presence
	const cssFile = hasPicoCSS ? 'uncloseai-modal-pico.css' : 'uncloseai-modal-builtin.css';
	
	if (!document.querySelector(`link[href*="${cssFile}"]`)) {
		const link = document.createElement('link');
		link.rel = 'stylesheet';
		link.href = `https://uncloseai.com/src/${cssFile}`;
		document.head.appendChild(link);
	}

	// Ensure ChunkFive font is loaded
	initializeChunkFiveFont();

	// Check if Hermes modal is open to set appropriate z-index
	const hermesModal = document.getElementById("uncloseai-embedded-modal");
	const zIndex = hermesModal ? "2001" : "1001";

	const modal = document.createElement("dialog");
	modal.id = "translate-modal";
	modal.style.zIndex = zIndex;

	const article = document.createElement("article");
	modal.appendChild(article);

	const header = document.createElement("header");
	header.className = "translate-modal-header";
	article.appendChild(header);

	const h1 = document.createElement("h1");
	h1.innerHTML = `<span style="font-family: 'ChunkFiveRegular', monospace;">uncloseai.</span> ${getUIText("translateModalTitle")}`;
	header.appendChild(h1);

	const closeButton = document.createElement("button");
	closeButton.textContent = "X";
	closeButton.className = "close-btn";
	closeButton.onclick = () => {
		modal.close();
		document.body.removeChild(modal);
	};
	header.appendChild(closeButton);

	// Translation mode tabs
	const tabNav = document.createElement("nav");
	// CSS class already handles margin-bottom

	const tabList = document.createElement("ul");
	tabList.setAttribute("role", "tablist");
	tabList.className = "translate-tab-nav";

	// Page tab
	const pageTabItem = document.createElement("li");
	const pageTabLink = document.createElement("a");
	pageTabLink.setAttribute("role", "tab");
	pageTabLink.setAttribute("aria-selected", "true");
	pageTabLink.setAttribute("aria-controls", "page-panel");
	pageTabLink.href = "#page-panel";
	pageTabLink.textContent = getUIText("translatePageTab");
	pageTabLink.setAttribute("data-i18n", "translatePageTab");
	pageTabItem.appendChild(pageTabLink);

	// Custom text tab
	const customTabItem = document.createElement("li");
	const customTabLink = document.createElement("a");
	customTabLink.setAttribute("role", "tab");
	customTabLink.setAttribute("aria-selected", "false");
	customTabLink.setAttribute("aria-controls", "custom-panel");
	customTabLink.href = "#custom-panel";
	customTabLink.textContent = getUIText("customTextTab");
	customTabLink.setAttribute("data-i18n", "customTextTab");
	customTabItem.appendChild(customTabLink);

	// Remote URL tab
	const remoteTabItem = document.createElement("li");
	const remoteTabLink = document.createElement("a");
	remoteTabLink.setAttribute("role", "tab");
	remoteTabLink.setAttribute("aria-selected", "false");
	remoteTabLink.setAttribute("aria-controls", "remote-panel");
	remoteTabLink.href = "#remote-panel";
	remoteTabLink.textContent = getUIText("remoteUrlTab");
	remoteTabLink.setAttribute("data-i18n", "remoteUrlTab");
	remoteTabItem.appendChild(remoteTabLink);

	tabList.appendChild(pageTabItem);
	tabList.appendChild(remoteTabItem);
	tabList.appendChild(customTabItem);
	tabNav.appendChild(tabList);
	article.appendChild(tabNav);

	// Content areas with proper IDs and attributes for tabs
	const pageContent = document.createElement("div");
	pageContent.id = "page-panel";
	pageContent.setAttribute("role", "tabpanel");
	pageContent.setAttribute("aria-labelledby", "page-tab");
	pageContent.className = "translate-tab-content active"; // Start with page tab active
	
	const customContent = document.createElement("div");
	customContent.id = "custom-panel";
	customContent.setAttribute("role", "tabpanel");
	customContent.setAttribute("aria-labelledby", "custom-tab");
	customContent.className = "translate-tab-content";

	const remoteContent = document.createElement("div");
	remoteContent.id = "remote-panel";
	remoteContent.setAttribute("role", "tabpanel");
	remoteContent.setAttribute("aria-labelledby", "remote-tab");
	remoteContent.className = "translate-tab-content";

	// Page translation content
	const pageInfo = document.createElement("p");
	pageInfo.textContent = getUIText("translatePageInfo");
	pageInfo.setAttribute("data-i18n", "translatePageInfo");
	pageContent.appendChild(pageInfo);

	// Custom text content
	const textArea = document.createElement("textarea");
	textArea.className = "translate-textarea";
	textArea.placeholder = getUIText("translatePlaceholder");
	customContent.appendChild(textArea);

	// Remote URL content
	const remoteInfo = document.createElement("p");
	remoteInfo.textContent = getUIText("remoteUrlInfo");
	remoteInfo.setAttribute("data-i18n", "remoteUrlInfo");
	remoteContent.appendChild(remoteInfo);

	const urlInput = document.createElement("input");
	urlInput.type = "url";
	urlInput.className = "translate-url-input"; // Use specific URL input styling
	urlInput.placeholder = getUIText("remoteUrlPlaceholder");
	urlInput.setAttribute("data-i18n-placeholder", "remoteUrlPlaceholder");
	urlInput.setAttribute("aria-label", "Enter URL to translate");
	remoteContent.appendChild(urlInput);

	article.appendChild(pageContent);
	article.appendChild(remoteContent);
	article.appendChild(customContent);

	// Language selection
	const languageContainer = document.createElement("div");
	languageContainer.className = "translate-language-container";

	const languageLabel = document.createElement("label");
	languageLabel.textContent = getUIText("translateToLabel");
	languageLabel.setAttribute("data-i18n", "translateToLabel");
	languageLabel.className = "translate-label";

	const languageSelect = document.createElement("select");
	languageSelect.className = "translate-language-select";

	Object.entries(SUPPORTED_LANGUAGES).forEach(([code, name]) => {
		const option = document.createElement("option");
		option.value = code;
		const nativeName = NATIVE_LANGUAGE_NAMES[code];
		// Show both English and native names, unless they're the same
		option.textContent = nativeName && nativeName !== name ? `${name} - ${nativeName}` : name;
		languageSelect.appendChild(option);
	});

	languageContainer.appendChild(languageLabel);
	languageContainer.appendChild(languageSelect);
	article.appendChild(languageContainer);

	// Translate button
	const translateButton = document.createElement("button");
	translateButton.textContent = getUIText("translateButton");
	translateButton.setAttribute("data-i18n", "translateButton");
	translateButton.className = "translate-btn";

	// Result area
	const resultContainer = document.createElement("div");
	resultContainer.className = "translate-result-container";

	const resultLabel = document.createElement("h3");
	resultLabel.textContent = "Translation:";

	const resultArea = document.createElement("div");
	resultArea.className = "translate-result";

	resultContainer.appendChild(resultLabel);
	resultContainer.appendChild(resultArea);
	article.appendChild(resultContainer);

	article.appendChild(translateButton);

	// Tab switching using PicoCSS tab navigation
	let activeTab = "page"; // "page", "custom", or "remote"

	function switchToTab(targetTab) {
		// Reset all tabs
		pageTabLink.setAttribute("aria-selected", "false");
		customTabLink.setAttribute("aria-selected", "false");
		remoteTabLink.setAttribute("aria-selected", "false");
		
		pageContent.classList.remove("active");
		customContent.classList.remove("active");
		remoteContent.classList.remove("active");
		
		// Activate target tab
		if (targetTab === "page") {
			pageTabLink.setAttribute("aria-selected", "true");
			pageContent.classList.add("active");
			translateButton.textContent = getUIText("translatePageButton");
		} else if (targetTab === "custom") {
			customTabLink.setAttribute("aria-selected", "true");
			customContent.classList.add("active");
			translateButton.textContent = getUIText("translateTextButton");
		} else if (targetTab === "remote") {
			remoteTabLink.setAttribute("aria-selected", "true");
			remoteContent.classList.add("active");
			translateButton.textContent = getUIText("fetchAndTranslate");
		}
		
		activeTab = targetTab;
	}

	pageTabLink.onclick = (e) => {
		e.preventDefault();
		switchToTab("page");
	};

	customTabLink.onclick = (e) => {
		e.preventDefault();
		switchToTab("custom");
	};

	remoteTabLink.onclick = (e) => {
		e.preventDefault();
		switchToTab("remote");
	};

	// Translation logic
	translateButton.onclick = async () => {
		const targetLanguage = languageSelect.value;
		const targetLanguageName = SUPPORTED_LANGUAGES[targetLanguage];

		try {
			translateButton.textContent = getUIText("processingText");
			translateButton.disabled = true;
			resultContainer.classList.remove("show");

			// Get exact tokenization for the UI progress indicator
			const { extractPageContent, preserveSpecialContent, estimateProcessingTime, SUPPORTED_LANGUAGES } = await import("./translation.js");
			const { countTokensWithUpstream } = await import("./token_estimator.js");
			const { getSelectedModel, getSelectedModelMaxTokens } = await import("./models.js");
			
			const selectedModel = getSelectedModel();
			
			let rawContent;
			let remoteUrl; // Store URL for remote translations
			if (activeTab === "page") {
				rawContent = extractPageContent();
			} else if (activeTab === "custom") {
				rawContent = textArea.value.trim();
			} else if (activeTab === "remote") {
				remoteUrl = urlInput.value.trim();
				if (!remoteUrl) {
					throw new Error("Please enter a URL to translate");
				}
				// Auto-add https:// if no scheme is provided
				if (!remoteUrl.startsWith('http://') && !remoteUrl.startsWith('https://')) {
					remoteUrl = 'https://' + remoteUrl;
				}
				// Fetch full HTML content from remote URL
				rawContent = await fetchRemotePageHTML(remoteUrl);
			}
				
			// Limit content length to avoid overwhelming the AI
			const maxLength = 50000;
			const contentToProcess = rawContent.length > maxLength
				? `${rawContent.substring(0, maxLength)}...`
				: rawContent;
				
			// Calculate actual tokens that will be sent to AI (including preservation and chunking)
			let totalTokens = 0;
			
			// Simulate the same chunking logic that translateHTML will use
			const maxTokens = getSelectedModelMaxTokens() || 8192;
			const reserveTokens = 1000;
			const availableTokens = Math.max(maxTokens - reserveTokens, 2000);
			
			const contentTokens = await countTokensWithUpstream(contentToProcess, getSelectedModel());
			const estimatedOutputTokens = Math.floor(contentTokens.totalTokens * 1.8);
			const totalEstimatedTokens = contentTokens.totalTokens + estimatedOutputTokens;
			
			if (totalEstimatedTokens <= availableTokens) {
				// Single request - calculate preserved content tokens
				const { preservedText } = preserveSpecialContent(contentToProcess);
				const prompt = `Translate the following HTML content into ${SUPPORTED_LANGUAGES[targetLanguage]}. The input is in English and formatted as HTML, which includes formatting, code blocks, and technical content. Ensure the output preserves the structure, syntax, and formatting of the original. Do not translate or modify placeholders like __CODE_0__, __URI_0__, __HTML_0__, etc., as they represent code blocks, URLs, or HTML elements that should remain unchanged. Only translate the surrounding text. Here is the text to translate:

${preservedText}`;
				const promptTokens = await countTokensWithUpstream(prompt, getSelectedModel());
				totalTokens = promptTokens.totalTokens;
			} else {
				// Multiple chunks - estimate tokens per chunk and multiply
				const maxChunkInputTokens = Math.floor(availableTokens / 2.8);
				const estimatedChunks = Math.ceil(contentTokens.totalTokens / maxChunkInputTokens);
				const avgTokensPerChunk = Math.floor(contentTokens.totalTokens / estimatedChunks);
				
				// Estimate tokens for one chunk with preservation and prompt
				const sampleChunk = contentToProcess.substring(0, Math.floor(contentToProcess.length / estimatedChunks));
				const { preservedText: samplePreserved } = preserveSpecialContent(sampleChunk);
				const samplePrompt = `Translate the following HTML content into ${SUPPORTED_LANGUAGES[targetLanguage]}. The input is in English and formatted as HTML, which includes formatting, code blocks, and technical content. Ensure the output preserves the structure, syntax, and formatting of the original. Do not translate or modify placeholders like __CODE_0__, __URI_0__, __HTML_0__, etc., as they represent code blocks, URLs, or HTML elements that should remain unchanged. Only translate the surrounding text. Here is the text to translate:

${samplePreserved}`;
				const sampleTokens = await countTokensWithUpstream(samplePrompt, getSelectedModel());
				totalTokens = sampleTokens.totalTokens * estimatedChunks;
			}
			
			const estimatedSeconds = estimateProcessingTime(totalTokens);

			// Create progress indicator
			const progressContainer = document.createElement("div");
			progressContainer.className = "translate-progress-container";

			const progressText = document.createElement("div");
			progressText.className = "translate-progress-text";
			progressText.textContent = getUIText("processingTokens", { tokens: totalTokens });

			const etaText = document.createElement("div");
			etaText.className = "translate-eta-text";
			etaText.textContent = `Estimated time: ${estimatedSeconds} seconds`;

			const progressBar = document.createElement("div");
			progressBar.className = "translate-progress-bar";

			const progressFill = document.createElement("div");
			progressFill.className = "translate-progress-fill";
			progressBar.appendChild(progressFill);

			const statusText = document.createElement("div");
			statusText.className = "translate-status-text";
			statusText.textContent = "Initializing translation...";

			progressContainer.appendChild(progressText);
			progressContainer.appendChild(etaText);
			progressContainer.appendChild(progressBar);
			progressContainer.appendChild(statusText);

			// Insert progress before result container
			resultContainer.parentNode.insertBefore(
				progressContainer,
				resultContainer,
			);

			// Start progress animation
			const startTime = Date.now();
			const progressInterval = setInterval(() => {
				const elapsed = Date.now() - startTime;
				const progress = Math.min(
					(elapsed / (estimatedSeconds * 1000)) * 100,
					95,
				);
				progressFill.style.width = `${progress}%`; // Dynamic width needs to stay inline

				const remainingTime = Math.max(
					0,
					estimatedSeconds - Math.floor(elapsed / 1000),
				);
				etaText.textContent =
					remainingTime > 0
						? `Time remaining: ${remainingTime}s`
						: "Almost done...";

				if (elapsed < 3000) statusText.textContent = "Analyzing content...";
				else if (elapsed < estimatedSeconds * 500)
					statusText.textContent = `Translating with ${selectedModel}...`;
				else statusText.textContent = "Finalizing translation...";
			}, 500);

			let translatedText;

			if (activeTab === "page") {
				translatedText = await translateCurrentPage(targetLanguage);
			} else if (activeTab === "custom") {
				const customText = textArea.value.trim();
				if (!customText) {
					alert(getUIText("pleaseEnterTranslateText"));
					return;
				}
				translatedText = await translateText(customText, targetLanguage);
			} else if (activeTab === "remote") {
				// For remote URLs, translate the full HTML structure like page translation
				// Use translateHTML directly since rawContent is already clean HTML from fetchRemotePageHTML
				const { translateHTML } = await import("./translation.js");
				translatedText = await translateHTML(rawContent, targetLanguage, remoteUrl);
			}

			resultLabel.textContent = `Translation (${targetLanguageName}):`;

			// Check if the translated content looks like HTML or if it's from a remote URL
			const isHTML =
				activeTab === "remote" || // Always treat remote translations as HTML
				(translatedText.includes("<") &&
				translatedText.includes(">") &&
				(translatedText.includes("<h") ||
					translatedText.includes("<p") ||
					translatedText.includes("<div") ||
					translatedText.includes("<section")));

			if (isHTML) {
				// Auto-open preview in new tab
				const previewWindow = window.open("", "_blank");
				if (previewWindow) {
					// Inject base URL for relative resources to work
					const baseUrl =
						window.location.origin +
						window.location.pathname.substring(
							0,
							window.location.pathname.lastIndexOf("/") + 1,
						);

					let htmlWithBase;
					const scriptTag = `
            <script>
              window.UNCLOSEAI_SKIP_INIT = true;
            </script>
            <script src="https://uncloseai.com/uncloseai.js" type="module"></script>`;

					if (translatedText.includes("<!DOCTYPE")) {
						// Already has DOCTYPE, just add base and script
						htmlWithBase = translatedText.includes("<head>")
							? translatedText.replace(
									"<head>",
									`<head><base href="${baseUrl}">${scriptTag}`,
								)
							: translatedText.replace(
									"<html>",
									`<html><head><base href="${baseUrl}">${scriptTag}</head>`,
								);
					} else if (translatedText.includes("<head>")) {
						// Has head but no DOCTYPE
						htmlWithBase = `<!DOCTYPE html>\n${translatedText.replace("<head>", `<head><base href="${baseUrl}">${scriptTag}`)}`;
					} else {
						// No DOCTYPE or head
						htmlWithBase = `<!DOCTYPE html>\n<html><head><base href="${baseUrl}">${scriptTag}</head><body>${translatedText}</body></html>`;
					}

					previewWindow.document.write(htmlWithBase);
					previewWindow.document.close();
					
					// Set title based on translation source
					let windowTitle;
					if (activeTab === "remote") {
						const urlInput = document.querySelector('.translate-url-input');
						const sourceUrl = urlInput ? urlInput.value.trim() : 'Remote URL';
						windowTitle = `${sourceUrl} - translated into ${targetLanguageName}`;
					} else if (activeTab === "custom") {
						windowTitle = `Custom Text - translated into ${targetLanguageName}`;
					} else {
						windowTitle = `${document.title} - translated into ${targetLanguageName}`;
					}
					previewWindow.document.title = windowTitle;

					// Add a notice about AI functionality only in preview window (wait for body to be available)
					const addNotice = () => {
						if (
							previewWindow &&
							previewWindow.document &&
							previewWindow.document.body
						) {
							console.log("Adding AI notice to preview window");
							const notice = previewWindow.document.createElement("div");
							notice.className = "translate-ai-notice";
							notice.textContent = `🤖 AI features should work in ${targetLanguageName}!`;
							previewWindow.document.body.appendChild(notice);

							// Auto-hide notice after 5 seconds
							setTimeout(() => {
								if (notice.parentNode) notice.parentNode.removeChild(notice);
							}, 5000);
						} else if (previewWindow) {
							// Wait a bit and try again
							setTimeout(addNotice, 100);
						}
					};

					// Only add notice if we have a valid preview window
					if (previewWindow) {
						addNotice();
					}
				}

				// Show raw HTML toggle in modal
				resultArea.innerHTML = `
          <div style="margin-bottom: 15px;">
            <button onclick="this.nextElementSibling.style.display = this.nextElementSibling.style.display === 'none' ? 'block' : 'none'; this.textContent = this.textContent.includes('Raw') ? 'Show Raw HTML' : 'Hide Raw HTML'" class="translate-raw-toggle-btn">Show Raw HTML</button>
            <div style="display: none; margin: 10px 0; padding: 15px; background: #f0f0f0; border-radius: 4px; white-space: pre-wrap; font-family: monospace; font-size: 0.85em; max-height: 300px; overflow-y: auto; border: 1px solid #ddd;">${translatedText.replace(/</g, "&lt;").replace(/>/g, "&gt;")}</div>
          </div>
          <div style="border: 2px solid #4CAF50; border-radius: 8px; background: #f0fff0; padding: 15px; text-align: center;">
            <div style="color: #4CAF50; font-weight: bold; margin-bottom: 10px;">✅ Preview Opened in New Window</div>
            <p style="margin: 0; color: #666;">The translated HTML page has opened in a new window with full AI functionality!</p>
            ${previewWindow ? "" : '<p style="margin: 10px 0 0 0; color: #d32f2f;"><strong>Note:</strong> Please allow popups for preview window</p>'}
          </div>
        `;
				resultArea.className = "translate-result-area";
			} else {
				resultArea.textContent = translatedText;
				resultArea.className = "translate-result-area pre-wrap";
			}

			resultContainer.classList.add("show");

			// Complete progress bar
			clearInterval(progressInterval);
			progressFill.style.width = "100%";
			etaText.textContent = "Translation completed!";
			statusText.textContent = "✅ Ready to preview";

			// Hide progress after a moment
			setTimeout(() => {
				if (progressContainer.parentNode) {
					progressContainer.parentNode.removeChild(progressContainer);
				}
			}, 2000);

			// Scroll to result
			resultContainer.scrollIntoView({ behavior: "smooth", block: "nearest" });
		} catch (error) {
			// Clean up progress on error
			if (typeof progressInterval !== "undefined") {
				clearInterval(progressInterval);
			}
			const progressContainer = document.querySelector(
				'.translate-progress-container',
			);
			if (progressContainer && progressContainer.parentNode) {
				progressContainer.parentNode.removeChild(progressContainer);
			}
			alert(error.message);
		} finally {
			// Reset button text based on active tab
			if (activeTab === "page") {
				translateButton.textContent = getUIText("translatePageButton");
			} else if (activeTab === "custom") {
				translateButton.textContent = getUIText("translateTextButton");
			} else if (activeTab === "remote") {
				translateButton.textContent = getUIText("fetchAndTranslate");
			}
			translateButton.disabled = false;
		}
	};

	document.body.appendChild(modal);

	// Use showModal() for proper mobile support and backdrop
	modal.showModal();

	// Close modal when clicking backdrop
	modal.addEventListener("click", (e) => {
		if (e.target === modal) {
			modal.close();
			document.body.removeChild(modal);
		}
	});
}
