import { useQueryClient } from '@tanstack/react-query'
import { useMemo } from 'react'
import { useNavigate } from 'react-router-dom'

import { useOverlayStore } from '@/components/RouteBlockerOverlay'
import { prefetchForURL } from '@/lib/prefetchers'
import { cn } from '@/lib/utils'

import type { AnchorHTMLAttributes, FC, MouseEvent, TouchEvent } from 'react'

type Props = AnchorHTMLAttributes<HTMLAnchorElement> & {
    to:             string
    replace?:       boolean
    className?:     string
    cancelOnError?: boolean }


export default (({ to,
		   replace,
		   className,
		   onMouseEnter,
		   onTouchStart,
		   onClick,
		   cancelOnError = false,
		   ...rest }: Props) => {
  const navigate = useNavigate ()
  const qc = useQueryClient ()
  const url = useMemo (() => (new URL (to, location.origin)).toString (), [to])
  const setOverlay = useOverlayStore (s => s.setActive)

  const doPrefetch = async () => {
    try
    {
      await prefetchForURL (qc, url)
      return true
    }
    catch (e)
    {
      console.error ('データ取得エラー', e)
      return false
    }
  }

  const handleMouseEnter = async (ev: MouseEvent<HTMLAnchorElement>) => {
    onMouseEnter?.(ev)
    doPrefetch ()
  }

  const handleTouchStart = async (ev: TouchEvent<HTMLAnchorElement>) => {
    onTouchStart?.(ev)
    doPrefetch ()
  }

  const handleClick = async (ev: MouseEvent<HTMLAnchorElement>) => {
    onClick?.(ev)

    if (ev.defaultPrevented
	|| ev.metaKey
	|| ev.ctrlKey
	|| ev.shiftKey
	|| ev.altKey)
      return

    ev.preventDefault ()

    setOverlay (true)
    const ok = await doPrefetch ()
    setOverlay (false)

    if (!(ok) && cancelOnError)
      return

    navigate (to, { replace })
  }

  return (
      <a href={to}
	 onMouseEnter={handleMouseEnter}
	 onTouchStart={handleTouchStart}
	 onClick={handleClick}
	 className={cn ('cursor-pointer', className)}
	 {...rest}/>)
}) satisfies FC<Props>
