import { useEffect, useState } from 'react'

import PrefetchLink from '@/components/PrefetchLink'
import { LIGHT_COLOUR_SHADE, DARK_COLOUR_SHADE, TAG_COLOUR } from '@/consts'
import { apiGet } from '@/lib/api'
import { cn } from '@/lib/utils'

import type { ComponentProps, FC, HTMLAttributes } from 'react'

import type { Tag } from '@/types'

type CommonProps = { 
    tag:        Tag
    nestLevel?: number
    withWiki?:  boolean
    withCount?: boolean
    prefetch?:  boolean }

type PropsWithLink =
    & CommonProps
    & { linkFlg?: true }
    & Partial<ComponentProps<typeof PrefetchLink>>

type PropsWithoutLink =
    & CommonProps
    & { linkFlg: false }
    & Partial<HTMLAttributes<HTMLSpanElement>>

type Props =
    | PropsWithLink
    | PropsWithoutLink


export default (({ tag,
		   nestLevel = 0,
		   linkFlg   = true,
		   withWiki  = true,
		   withCount = true,
		   prefetch  = false,
		   ...props }: Props) => {
  const [havingWiki, setHavingWiki] = useState (true)

  const wikiExists = async (tag: Tag) => {
    if ('hasWiki' in tag)
      {
	setHavingWiki (tag.hasWiki)
	return
      }

    const tagName = (tag as Tag).name

    try
    {
      await apiGet (`/wiki/title/${ encodeURIComponent (tagName) }/exists`)
      setHavingWiki (true)
    }
    catch
    {
      setHavingWiki (false)
    }
  }

  useEffect (() => {
    if (!(linkFlg) || !(withWiki))
      return

    wikiExists (tag)
  }, [tag.name, linkFlg, withWiki])

  const spanClass = cn (
      `text-${ TAG_COLOUR[tag.category] }-${ LIGHT_COLOUR_SHADE }`,
      `dark:text-${ TAG_COLOUR[tag.category] }-${ DARK_COLOUR_SHADE }`)
  const linkClass = cn (
      spanClass,
      `hover:text-${ TAG_COLOUR[tag.category] }-${ LIGHT_COLOUR_SHADE - 200 }`,
      `dark:hover:text-${ TAG_COLOUR[tag.category] }-${ DARK_COLOUR_SHADE - 200 }`)

  return (
      <>
	{(linkFlg && withWiki) && (
	    <span className="mr-1">
	      {havingWiki
	       ? (
		  <PrefetchLink to={`/wiki/${ encodeURIComponent (tag.name) }`}
			className={linkClass}>
		    ?
		  </PrefetchLink>)
	       : (
		  <PrefetchLink to={`/wiki/${ encodeURIComponent (tag.name) }`}
			className="animate-[wiki-blink_.25s_steps(2,end)_infinite]
				   dark:animate-[wiki-blink-dark_.25s_steps(2,end)_infinite]"
			title={`${ tag.name } Wiki が存在しません．`}>
		    !
		  </PrefetchLink>)}
	    </span>)}
	{nestLevel > 0 && (
	    <span
		className="ml-1 mr-1"
		style={{ paddingLeft: `${ (nestLevel - 1) }rem` }}>
	      ↳
	    </span>)}
	{tag.matchedAlias != null && (
	    <>
	      <span className={spanClass} {...props}>
		{tag.matchedAlias}
	      </span>
	      <> → </>
	    </>)}
	{linkFlg
	 ? (
	    prefetch
	    ? <PrefetchLink
		  to={`/posts?${ (new URLSearchParams ({ tags: tag.name })).toString () }`}
		  className={linkClass}
		  {...props}>
		{tag.name}
	      </PrefetchLink>
	    : <PrefetchLink
		  to={`/posts?${ (new URLSearchParams ({ tags: tag.name })).toString () }`}
		  className={linkClass}
		  {...props}>
		{tag.name}
	      </PrefetchLink>)
	 : (
	    <span className={spanClass}
		  {...props}>
	      {tag.name}
	    </span>)}
	{withCount && (
	    <span className="ml-1">{tag.postCount}</span>)}
      </>)
}) satisfies FC<Props>
