import axios from 'axios'
import { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'

import { API_BASE_URL } from '@/config'
import { LIGHT_COLOUR_SHADE, DARK_COLOUR_SHADE, TAG_COLOUR } from '@/consts'
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 }

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

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

type Props = PropsWithLink | PropsWithoutLink


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

  const wikiExists = async (tagName: string) => {
    try
    {
      await axios.get (`${ API_BASE_URL }/wiki/title/${ encodeURIComponent (tagName) }/exists`)
      setHavingWiki (true)
    }
    catch
    {
      setHavingWiki (false)
    }
  }

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

    wikiExists (tag.name)
  }, [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
	       ? (
		  <Link to={`/wiki/${ encodeURIComponent (tag.name) }`}
			className={linkClass}>
		    ?
		  </Link>)
	       : (
		  <Link 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 が存在しません．`}>
		    !
		  </Link>)}
	    </span>)}
	{nestLevel > 0 && (
	    <span
		className="ml-1 mr-1"
		style={{ paddingLeft: `${ (nestLevel - 1) }rem` }}>
	      ↳
	    </span>)}
	{linkFlg
	 ? (
	    <Link to={`/posts?${ (new URLSearchParams ({ tags: tag.name })).toString () }`}
		  className={linkClass}
		  {...props}>
	      {tag.name}
	    </Link>)
	 : (
	    <span className={spanClass}
		  {...props}>
	      {tag.name}
	    </span>)}
	{withCount && (
	    <span className="ml-1">{tag.postCount}</span>)}
      </>)
}) satisfies FC<Props>
