import { partial } from 'lodash';

/**
 * This is a custom link component that mimics the behavior of the @woocommerce/components/link component.
 */

interface LinkProps {
	/** Type of link. For wp-admin and wc-admin, the correct prefix is appended. */
	type?: 'wc-admin' | 'wp-admin' | 'external';
	/** The resource to link to. */
	href: string;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type LinkOnClickHandlerFunction = ( ...props: any ) => any; // we don't want to restrict this function at all
type LinkOnclickHandler = (
	onClick: LinkOnClickHandlerFunction | undefined,
	event: React.MouseEvent< Element > | undefined
) => void;

/**
 * Use `Link` to create a link to another resource. It accepts a type to automatically
 * create wp-admin links, wc-admin links, and external links.
 */
export const Link = ( {
	href,
	children,
	type = 'wc-admin',
	...props
}: React.AnchorHTMLAttributes< HTMLAnchorElement > &
	LinkProps ): React.ReactElement => {
	// ( { children, href, type, ...props } ) => {
	// @todo Investigate further if we can use <Link /> directly.
	// With React Router 5+, <RouterLink /> cannot be used outside of the main <Router /> elements,
	const wcAdminLinkHandler: LinkOnclickHandler = ( onClick, event ) => {
		// If cmd, ctrl, alt, or shift are used, use default behavior to allow opening in a new tab.
		if (
			event?.ctrlKey ||
			event?.metaKey ||
			event?.altKey ||
			event?.shiftKey
		) {
			return;
		}

		event?.preventDefault();

		// If there is an onclick event, execute it.
		const onClickResult = onClick && event ? onClick( event ) : true;

		// Mimic browser behavior and only continue if onClickResult is not explicitly false.
		if ( onClickResult === false ) {
			return;
		}

		if ( event?.target instanceof Element ) {
			const closestEventTarget = event.target
				.closest( 'a' )
				?.getAttribute( 'href' );
			if ( closestEventTarget ) {
				window.history.pushState( {}, '', closestEventTarget );
			} else {
				// eslint-disable-next-line no-console
				console.error(
					'Link is trying to push an undefined state into navigation stack'
				); // This shouldn't happen as we wrap with <a> below
			}
		}
	};

	const passProps = {
		...props,
		'data-link-type': type,
	};

	if ( type === 'wc-admin' ) {
		passProps.onClick = partial( wcAdminLinkHandler, passProps.onClick );
	}

	return (
		<a href={ href } { ...passProps }>
			{ children }
		</a>
	);
};
