import {forwardRef, AnchorHTMLAttributes} from 'react'

import {useHref} from 'react-router'

import {useNavigateWithTransition} from '../../hooks/navigation/useNavigateWithTransition'

/**
 * Navigation component that triggers animated page changes based on CSS View Transitions. Use instead of React Router's `Link` or `<a>` tags when you want smooth native feeling navigation within your Mini. Should be wrapped within a `MinisRouter`.
 *
 * > Caution: In order for the animation transitions to work, you need to enable view transitions in `MinisRouter`
 * @publicDocs
 */
export interface TransitionLinkDocProps {
  /** The target path to navigate to */
  to: string
  /** Click handler called before navigation */
  onClick?: React.MouseEventHandler<HTMLAnchorElement>
  /** Content to render inside the link */
  children?: React.ReactNode
}

export interface TransitionLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
  to: string
}

const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i

export const TransitionLink = forwardRef<
  HTMLAnchorElement,
  TransitionLinkProps
>(({onClick, to, children, ...props}, forwardedRef) => {
  const transitionNavigate = useNavigateWithTransition()

  const isAbsolute = typeof to === 'string' && ABSOLUTE_URL_REGEX.test(to)

  if (isAbsolute) {
    console.warn(
      `TransitionLink: absolute URLs are not supported. Please update to a valid relative path.`
    )
  }

  const href = useHref(to)

  const handleClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
    if (onClick) onClick(event)

    if (!event.defaultPrevented) {
      event.preventDefault()
      transitionNavigate(to)
    }
  }

  return (
    <a
      {...props}
      onClick={handleClick}
      href={isAbsolute ? undefined : href}
      ref={forwardedRef}
    >
      {children}
    </a>
  )
})
