'use client';

import { cn } from "../../utils/cn.mjs";
import { Button } from "../Button/Button.mjs";
import { Input, inputVariants } from "../Input/Input.mjs";
import { ArrowLeft, ArrowRight, RotateCw } from "lucide-react";
import { useEffect, useImperativeHandle, useRef, useState } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
import { useIntlayer } from "react-intlayer";

//#region src/components/Browser/Browser.tsx
const Browser = ({ initialUrl = "https://example.com", path, className, style, size = "md", "aria-label": ariaLabel, sandbox = "allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-downloads", ref, domainRestriction, ...props }) => {
	const [inputUrl, setInputUrl] = useState(initialUrl);
	const [currentUrl, setCurrentUrl] = useState(initialUrl);
	const [history, setHistory] = useState([initialUrl]);
	const [currentIndex, setCurrentIndex] = useState(0);
	const [error, setError] = useState(null);
	const [submitted, setSubmitted] = useState(false);
	const internalIframeRef = useRef(null);
	useImperativeHandle(ref, () => internalIframeRef.current, []);
	const content = useIntlayer("browser");
	useEffect(() => {
		setInputUrl(initialUrl);
		setCurrentUrl(initialUrl);
		setHistory([initialUrl]);
		setCurrentIndex(0);
		setError(null);
		setSubmitted(false);
	}, [initialUrl]);
	useEffect(() => {
		if (!path) return;
		try {
			const baseOrigin = domainRestriction ?? initialUrl;
			const fullUrl = `${new URL(baseOrigin).origin}${path}`;
			setInputUrl(fullUrl);
			let isAlreadyAtUrl = false;
			if (internalIframeRef.current?.contentWindow) try {
				const currentIframeHref = internalIframeRef.current.contentWindow.location.href;
				if (new URL(currentIframeHref).href === new URL(fullUrl).href) isAlreadyAtUrl = true;
			} catch {}
			if (history[currentIndex] !== fullUrl) {
				setHistory((prev) => {
					const newHistory = prev.slice(0, currentIndex + 1);
					newHistory.push(fullUrl);
					return newHistory;
				});
				setCurrentIndex((prev) => prev + 1);
			}
			if (!isAlreadyAtUrl) setCurrentUrl(fullUrl);
			setError(null);
		} catch {}
	}, [
		path,
		domainRestriction,
		initialUrl
	]);
	const handleNavigateTo = (url) => {
		try {
			const validated = normalizeUrl(url);
			if (validated === currentUrl) {
				handleReload();
				return;
			}
			setCurrentUrl(validated);
			setInputUrl(validated);
			setError(null);
			const newHistory = history.slice(0, currentIndex + 1);
			newHistory.push(validated);
			setHistory(newHistory);
			setCurrentIndex(newHistory.length - 1);
		} catch (e) {
			if (e instanceof Error && e.message === "URL does not match allowed domain" && domainRestriction) setError(content.domainRestrictionError?.value ?? `Only URLs from ${domainRestriction} are allowed.`);
			else setError(content.errorMessage.value);
		}
	};
	const handleBack = () => {
		if (currentIndex > 0) {
			const newIndex = currentIndex - 1;
			const prevUrl = history[newIndex];
			setCurrentIndex(newIndex);
			setCurrentUrl(prevUrl);
			setInputUrl(prevUrl);
			setError(null);
		}
	};
	const handleForward = () => {
		if (currentIndex < history.length - 1) {
			const newIndex = currentIndex + 1;
			const nextUrl = history[newIndex];
			setCurrentIndex(newIndex);
			setCurrentUrl(nextUrl);
			setInputUrl(nextUrl);
			setError(null);
		}
	};
	const handleSubmit = (e) => {
		e.preventDefault();
		setSubmitted(true);
		handleNavigateTo(inputUrl);
	};
	const handleReload = () => {
		if (internalIframeRef.current) {
			const src = internalIframeRef.current.src;
			internalIframeRef.current.src = "";
			setTimeout(() => {
				if (internalIframeRef.current) internalIframeRef.current.src = src;
			}, 50);
		}
	};
	const isValidHostname = (host) => {
		if (host === "localhost") return true;
		if (/^(\d{1,3}\.){3}\d{1,3}$/.test(host)) return true;
		if (/^[a-f0-9:]+$/i.test(host)) return true;
		if (!/^[a-z0-9.-]+$/i.test(host)) return false;
		if (/^[-.]/.test(host) || /[-.]$/.test(host)) return false;
		if (host.includes("..")) return false;
		if (!host.includes(".")) return false;
		return true;
	};
	const getRestrictionOrigin = () => {
		if (!domainRestriction) return null;
		try {
			return new URL(domainRestriction);
		} catch {
			return null;
		}
	};
	const normalizeUrl = (raw) => {
		const trimmed = raw.trim();
		if (!trimmed || /\s/.test(trimmed)) throw new Error("Invalid");
		const restrictionOrigin = getRestrictionOrigin();
		if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
			if (restrictionOrigin) return new URL(`${restrictionOrigin.origin}${trimmed}`).toString();
			return new URL(`${new URL(currentUrl).origin}${trimmed}`).toString();
		}
		const candidate = /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed) ? trimmed : `https://${trimmed}`;
		const url = new URL(candidate);
		if (url.protocol !== "http:" && url.protocol !== "https:") throw new Error("Only http(s) is allowed");
		if (!isValidHostname(url.hostname)) throw new Error("Invalid host");
		if (restrictionOrigin) {
			if (!(url.hostname === restrictionOrigin.hostname && url.protocol === restrictionOrigin.protocol && (restrictionOrigin.port === "" || url.port === restrictionOrigin.port || url.host === restrictionOrigin.host))) throw new Error("URL does not match allowed domain");
		}
		return url.toString();
	};
	const showError = submitted && !!error;
	const canGoBack = currentIndex > 0;
	const canGoForward = currentIndex < history.length - 1;
	return /* @__PURE__ */ jsxs("section", {
		className: cn("flex w-full flex-col overflow-hidden rounded-xl bg-background shadow-[0_4px_12px_rgba(0,0,0,0.4),0_0_1px_rgba(0,0,0,0.2)]", className),
		style,
		"aria-label": ariaLabel ?? content.ariaLabel.value,
		children: [/* @__PURE__ */ jsxs("div", {
			className: "relative z-10 flex shrink-0 items-center gap-3 rounded-t-xl bg-text/15 px-4 py-2",
			children: [
				/* @__PURE__ */ jsxs("div", {
					className: "flex items-center gap-1",
					children: [/* @__PURE__ */ jsx(Button, {
						type: "button",
						onClick: handleBack,
						disabled: !canGoBack,
						variant: "hoverable",
						size: "icon-md",
						label: content.backButtonLabel.value,
						Icon: ArrowLeft
					}), /* @__PURE__ */ jsx(Button, {
						type: "button",
						onClick: handleForward,
						disabled: !canGoForward,
						variant: "hoverable",
						size: "icon-md",
						label: content.forwardButtonLabel.value,
						Icon: ArrowRight
					})]
				}),
				/* @__PURE__ */ jsxs("form", {
					onSubmit: handleSubmit,
					noValidate: true,
					className: cn(inputVariants(), "flex w-full gap-2 rounded-xl p-0.5! supports-[corner-shape:squircle]:rounded-2xl", "bg-neutral/10 text-text/50 placeholder:text-neutral/80"),
					children: [
						/* @__PURE__ */ jsx("label", {
							htmlFor: "browser-url",
							className: "sr-only",
							children: content.urlLabel.value
						}),
						/* @__PURE__ */ jsx(Input, {
							id: "browser-url",
							type: "text",
							inputMode: "url",
							spellCheck: false,
							autoCapitalize: "off",
							variant: "invisible",
							className: "ml-3 p-0!",
							size: "sm",
							autoCorrect: "off",
							value: inputUrl,
							onChange: (e) => {
								setInputUrl(e.target.value);
								if (showError) setError(null);
							},
							placeholder: content.urlPlaceholder.value,
							"aria-label": content.urlLabel.value,
							"aria-invalid": showError,
							"aria-describedby": showError ? "browser-url-error" : void 0
						}),
						/* @__PURE__ */ jsx(Button, {
							type: "button",
							onClick: handleReload,
							variant: "hoverable",
							size: "icon-md",
							className: "p-1!",
							label: "content.reloadButtonTitle.value",
							Icon: RotateCw
						}),
						/* @__PURE__ */ jsx("button", {
							type: "submit",
							className: "sr-only absolute",
							tabIndex: -1
						})
					]
				}),
				showError && /* @__PURE__ */ jsx("div", {
					className: "absolute top-full left-4 z-20 mt-1",
					children: /* @__PURE__ */ jsx("p", {
						id: "browser-url-error",
						role: "alert",
						"aria-live": "assertive",
						className: "rounded-md bg-red-900/90 px-3 py-1.5 text-red-100 text-xs shadow-md backdrop-blur-sm",
						children: error
					})
				})
			]
		}), /* @__PURE__ */ jsx("div", {
			className: "relative z-0 flex min-h-0 w-full flex-1 flex-col overflow-hidden rounded-b-xl bg-background",
			children: /* @__PURE__ */ jsx("iframe", {
				ref: internalIframeRef,
				src: currentUrl,
				title: content.iframeTitle.value,
				className: "size-full flex-1",
				sandbox,
				loading: "lazy",
				"aria-live": "polite",
				...props
			})
		})]
	});
};

//#endregion
export { Browser };
//# sourceMappingURL=Browser.mjs.map