/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-d4ad2ea | Cube Dev Team */
import { mergeProps as mergeProps$1 } from "../../utils/react/mergeProps.js";
import { useEvent } from "../../_internal/hooks/use-event.js";
import { useFocus as useFocus$1 } from "../../utils/react/interactions.js";
import { UIKitContext } from "../../provider.js";
import { useTracking } from "../../providers/TrackingProvider.js";
import { filterBaseProps } from "@tenphi/tasty";
import { useContext } from "react";
import { useButton, useHover } from "react-aria";
import { useFocusableRef } from "@react-spectrum/utils";

//#region src/components/actions/use-action.ts
const LINK_PRESS_EVENT = "Link Press";
const BUTTON_PRESS_EVENT = "Button Press";
const FILTER_OPTIONS = { propNames: new Set(["onMouseEnter", "onMouseLeave"]) };
/**
* Helper to open link.
* @param {String} href
* @param {String|Boolean} [target]
*/
function openLink(href, target) {
	const link = document.createElement("a");
	link.href = href;
	if (target) {
		link.target = target === true ? "_blank" : target;
		link.rel = "noopener noreferrer";
	}
	document.body.appendChild(link);
	link.click();
	document.body.removeChild(link);
}
/**
* Checks if a URL is external (absolute HTTP(S), protocol-relative, or non-http protocols)
*/
function isExternalUrl(url) {
	return url.startsWith("http://") || url.startsWith("https://") || url.startsWith("//") || url.includes(":") && !url.startsWith("#");
}
function parseTo(to) {
	if (typeof to === "number") return {
		newTab: false,
		nativeRoute: false,
		cleanTo: void 0,
		isHistoryNavigation: true,
		historyDelta: to,
		isHashNavigation: false,
		isExternal: false
	};
	if (to && typeof to === "object") return {
		newTab: false,
		nativeRoute: false,
		cleanTo: to,
		isHistoryNavigation: false,
		isHashNavigation: false,
		isExternal: false
	};
	if (!to || typeof to !== "string") return {
		newTab: false,
		nativeRoute: false,
		cleanTo: void 0,
		isHistoryNavigation: false,
		isHashNavigation: false,
		isExternal: false
	};
	const newTab = to.startsWith("!");
	const nativeRoute = to.startsWith("@");
	const isHashNavigation = to.startsWith("#");
	const cleanTo = newTab || nativeRoute ? to.slice(1) : to;
	return {
		newTab,
		nativeRoute,
		cleanTo,
		isHistoryNavigation: false,
		isHashNavigation,
		isExternal: typeof cleanTo === "string" && isExternalUrl(cleanTo)
	};
}
function sanitizePressEvent(evt) {
	const safeEvt = {
		type: "type" in evt ? evt.type : void 0,
		pointerType: "pointerType" in evt ? evt.pointerType : void 0,
		shiftKey: "shiftKey" in evt ? !!evt.shiftKey : false,
		metaKey: "metaKey" in evt ? !!evt.metaKey : false,
		ctrlKey: "ctrlKey" in evt ? !!evt.ctrlKey : false,
		altKey: "altKey" in evt ? !!evt.altKey : false
	};
	try {
		Object.defineProperty(safeEvt, "target", {
			value: "target" in evt ? evt.target : void 0,
			enumerable: false,
			configurable: true
		});
	} catch (e) {}
	return safeEvt;
}
function performClickHandler(evt, { navigate, resolvedHref, to, onPress, tracking, navigationOptions }) {
	const { newTab, nativeRoute, cleanTo, isHistoryNavigation, historyDelta, isHashNavigation, isExternal } = parseTo(to);
	const element = evt.target;
	const qa = element?.getAttribute("data-qa");
	onPress?.(sanitizePressEvent(evt));
	if (to == null) {
		tracking.event(BUTTON_PRESS_EVENT, { qa }, element);
		return;
	}
	if (isHistoryNavigation && typeof historyDelta === "number") {
		tracking.event(LINK_PRESS_EVENT, {
			qa,
			delta: historyDelta,
			type: "router-history"
		}, element);
		navigate(historyDelta);
		return;
	}
	if (isHashNavigation && typeof to === "string") {
		const id = to.slice(1);
		const targetElement = document.getElementById(id);
		tracking.event(LINK_PRESS_EVENT, {
			qa,
			href: to,
			type: "hash",
			target: id
		}, element);
		if (targetElement) targetElement.scrollIntoView({
			behavior: "smooth",
			block: "start",
			inline: "nearest"
		});
		return;
	}
	if (evt.shiftKey || evt.metaKey || evt.ctrlKey || newTab) {
		openLink(resolvedHref, true);
		tracking.event(LINK_PRESS_EVENT, {
			qa,
			href: resolvedHref,
			type: "tab"
		}, element);
		return;
	}
	if (nativeRoute) {
		if (cleanTo === "" || cleanTo === void 0) {
			tracking.event(LINK_PRESS_EVENT, {
				qa,
				type: "native"
			}, element);
			window.location.reload();
		} else {
			tracking.event(LINK_PRESS_EVENT, {
				qa,
				href: resolvedHref,
				type: "native"
			}, element);
			window.location.assign(resolvedHref);
		}
		return;
	}
	if (isExternal && typeof cleanTo === "string") {
		tracking.event(LINK_PRESS_EVENT, {
			qa,
			href: cleanTo,
			type: "native"
		}, element);
		window.location.assign(cleanTo);
		return;
	}
	if (cleanTo !== void 0) {
		tracking.event(LINK_PRESS_EVENT, {
			qa,
			href: resolvedHref,
			type: "router"
		}, element);
		navigate(cleanTo, navigationOptions);
	}
}
const useAction = function useAction({ to, as, htmlType, label, mods, onPress, navigationOptions, ...props }, ref) {
	const tracking = useTracking();
	const navigation = useContext(UIKitContext).navigation;
	const isDisabled = props.isDisabled;
	const { newTab, nativeRoute, cleanTo, isHistoryNavigation, isHashNavigation, isExternal } = parseTo(to);
	const fallbackTo = to || ".";
	const navigate = navigation.useNavigate();
	const resolvedHref = navigation.useHref(fallbackTo);
	const cleanToHref = navigation.useHref(cleanTo || ".");
	as = to && !isHistoryNavigation ? "a" : as || "button";
	const target = newTab ? "_blank" : props.target;
	let href;
	if (as === "a" && cleanTo !== void 0) if (newTab || nativeRoute) href = typeof cleanTo === "string" && isExternal ? cleanTo : cleanToHref;
	else href = resolvedHref;
	const domRef = useFocusableRef(ref);
	const mergedNavigationOptions = navigationOptions;
	const customOnPress = useEvent((evt) => {
		performClickHandler(evt, {
			navigate,
			resolvedHref: href || resolvedHref,
			to,
			onPress,
			tracking,
			navigationOptions: mergedNavigationOptions
		});
	});
	let { buttonProps, isPressed } = useButton({
		"aria-label": label,
		...props,
		onPress: customOnPress
	}, domRef);
	let { hoverProps, isHovered } = useHover({ isDisabled });
	let { focusProps, isFocused } = useFocus$1({ isDisabled }, true);
	const customProps = to && !isHistoryNavigation ? { onClick(evt) {
		evt.preventDefault();
	} } : {};
	return {
		isPressed,
		actionProps: {
			mods: {
				hovered: isHovered && !isDisabled,
				pressed: isPressed && !isDisabled,
				focused: isFocused && !isDisabled,
				disabled: isDisabled,
				...mods
			},
			...mergeProps$1(buttonProps, hoverProps, focusProps, customProps, filterBaseProps(props, FILTER_OPTIONS)),
			ref: domRef,
			type: htmlType || "button",
			rel: as === "a" && newTab ? "noopener noreferrer" : void 0,
			as,
			isDisabled,
			target,
			href
		}
	};
};

//#endregion
export { openLink, parseTo, performClickHandler, useAction };
//# sourceMappingURL=use-action.js.map