"use client"
import NextLink from "next/link"
import { usePathname, useRouter, useSearchParams } from "next/navigation"
import { startTransition, useCallback, useMemo } from "react"

import useRouterTransitionStore from "@/stores/router-transition"

import { useCheckIfExternalLink } from "@/hooks/useCheckIfExternalLink"
import { trackClick, trackPageViewStart } from "@/utils/tracking"

import { linkVariants } from "./variants"

import type { LinkProps } from "./link"

export default function Link({
  active,
  className,
  color,
  href,
  partialMatch = false,
  textDecoration,
  size,
  scroll = true,
  prefetch,
  variant,
  weight,
  trackingId,
  onClick,
  /**
   * Decides if the link should include the current search params in the URL
   */
  keepSearchParams,
  ...props
}: LinkProps) {
  const currentPageSlug = usePathname()
  const searchParams = useSearchParams()
  let isActive = active || currentPageSlug === href

  if (partialMatch && !isActive) {
    isActive = currentPageSlug === href
  }

  const classNames = linkVariants({
    active: isActive,
    className,
    textDecoration,
    color,
    size,
    weight,
    variant,
  })

  const router = useRouter()

  const fullUrl = useMemo(() => {
    if (!keepSearchParams || !searchParams.size) return href

    const delimiter = href.includes("?") ? "&" : "?"
    return `${href}${delimiter}${searchParams}`
  }, [href, searchParams, keepSearchParams])

  // TODO: Remove this check (and hook) and only return <Link /> when current web is deleted
  const isExternal = useCheckIfExternalLink(href)

  const startRouterTransition = useRouterTransitionStore(
    (state) => state.startRouterTransition
  )

  const trackClickById = useCallback(() => {
    if (trackingId) {
      trackClick(trackingId)
    }
  }, [trackingId])

  const linkProps = {
    href: fullUrl,
    className: classNames,
  }

  return isExternal ? (
    <a
      {...linkProps}
      {...props}
      onClick={(e) => {
        if (onClick) {
          onClick(e)
        }
      }}
    />
  ) : (
    <NextLink
      scroll={scroll}
      prefetch={prefetch}
      onClick={(e) => {
        if (onClick) {
          onClick(e)
        }
        if (trackingId) {
          trackClickById()
        }
        if (props.target === "_blank") {
          // If link should open in new tab, we don't want to
          // track navigation nor start a router transition.
          return
        }
        if (href.startsWith("tel:") || href.startsWith("mailto:")) {
          // If href contains tel or mailto protocols we don't want to
          // track navigation nor start a router transition.
          return
        }
        e.preventDefault()
        trackPageViewStart()
        startTransition(() => {
          startRouterTransition()
          router.push(fullUrl, { scroll })
        })
      }}
      id={trackingId}
      {...props}
      {...linkProps}
    />
  )
}
