import axios from 'axios'
import React, { useEffect, useState } from 'react'
import { useNavigate, useLocation } from 'react-router-dom'

import { API_BASE_URL } from '@/config'

import TagSearchBox from './TagSearchBox'

import type { FC } from 'react'

import type { Tag } from '@/types'


export default (() => {
  const location = useLocation ()
  const navigate = useNavigate ()

  const [activeIndex, setActiveIndex] = useState (-1)
  const [search, setSearch] = useState ('')
  const [suggestions, setSuggestions] = useState<Tag[]> ([])
  const [suggestionsVsbl, setSuggestionsVsbl] = useState (false)

  const whenChanged = async (ev: React.ChangeEvent<HTMLInputElement>) => {
    setSearch (ev.target.value)

    const q = ev.target.value.trim ().split (' ').at (-1)
    if (!(q))
      {
	setSuggestions ([])
	return
      }

    const res = await axios.get (`${ API_BASE_URL }/tags/autocomplete`, { params: { q } })
    const data = res.data as Tag[]
    setSuggestions (data)
    if (suggestions.length > 0)
      setSuggestionsVsbl (true)
  }

  const handleKeyDown = (ev: React.KeyboardEvent<HTMLInputElement>) => {
    switch (ev.key)
    {
    case 'ArrowDown':
      ev.preventDefault ()
      setActiveIndex (i => Math.min (i + 1, suggestions.length - 1))
      setSuggestionsVsbl (true)
      break

    case 'ArrowUp':
      ev.preventDefault ()
      setActiveIndex (i => Math.max (i - 1, -1))
      setSuggestionsVsbl (true)
      break

    case 'Enter':
      if (activeIndex < 0)
	break
      ev.preventDefault ()
      const selected = suggestions[activeIndex]
      selected && handleTagSelect (selected)
      break

    case 'Escape':
      ev.preventDefault ()
      setSuggestionsVsbl (false)
      break
    }
    if (ev.key === 'Enter' && (!(suggestionsVsbl) || activeIndex < 0))
      {
	navigate (`/posts?${ (new URLSearchParams ({ tags: search })).toString () }`)
	setSuggestionsVsbl (false)
      }
  }

  const handleTagSelect = (tag: Tag) => {
    const parts = search.split (' ')
    parts[parts.length - 1] = tag.name
    setSearch (parts.join (' ') + ' ')
    setSuggestions ([])
    setActiveIndex (-1)
  }

  useEffect (() => {
    const query = new URLSearchParams (location.search)
    const tagsQuery = query.get ('tags') ?? ''
    setSearch (tagsQuery)
  }, [location.search])

  return (
      <div className="relative w-full">
	<input type="text"
	       placeholder="タグ検索..."
	       value={search}
	       onChange={whenChanged}
	       onFocus={() => setSuggestionsVsbl (true)}
	       onBlur={() => setSuggestionsVsbl (false)}
	       onKeyDown={handleKeyDown}
	       className="w-full px-3 py-2 border rounded dark:border-gray-600 dark:bg-gray-800 dark:text-white"/>
	<TagSearchBox suggestions={suggestionsVsbl && suggestions.length ? suggestions : [] as Tag[]}
		      activeIndex={activeIndex}
		      onSelect={handleTagSelect}/>
      </div>)
}) satisfies FC
