import axios from 'axios'
import toCamel from 'camelcase-keys'
import { useEffect, useState } from 'react'
import { Helmet } from 'react-helmet-async'
import { Link, useLocation, useNavigate, useParams } from 'react-router-dom'

import PostList from '@/components/PostList'
import TagLink from '@/components/TagLink'
import WikiBody from '@/components/WikiBody'
import PageTitle from '@/components/common/PageTitle'
import TabGroup, { Tab } from '@/components/common/TabGroup'
import MainArea from '@/components/layout/MainArea'
import { API_BASE_URL, SITE_TITLE } from '@/config'
import { WikiIdBus } from '@/lib/eventBus/WikiIdBus'

import type { Post, Tag, WikiPage } from '@/types'


export default () => {
  const params = useParams ()
  const title = params.title ?? ''

  const location = useLocation ()
  const navigate = useNavigate ()

  const defaultTag = { name: title, category: 'general' } as Tag

  const [posts, setPosts] = useState<Post[]> ([])
  const [tag, setTag] = useState (defaultTag)
  const [wikiPage, setWikiPage] = useState<WikiPage | null | undefined> (undefined)

  const query = new URLSearchParams (location.search)
  const version = query.get ('version')

  useEffect (() => {
    if (/^\d+$/.test (title))
      {
	void (async () => {
	  try
	  {
	    const res = await axios.get (`${ API_BASE_URL }/wiki/${ title }`)
	    const data = res.data as WikiPage
	    navigate (`/wiki/${ encodeURIComponent(data.title) }`, { replace: true })
	  }
	  catch
	  {
	    ;
	  }
	}) ()

	return
      }

    void (async () => {
      try
      {
	const res = await axios.get (
	    `${ API_BASE_URL }/wiki/title/${ encodeURIComponent (title) }`,
	    { params: version ? { version } : { } })
	const data = toCamel (res.data as any, { deep: true }) as WikiPage
	if (data.title !== title)
	  navigate (`/wiki/${ encodeURIComponent(data.title) }`, { replace: true })
	setWikiPage (data)
	WikiIdBus.set (data.id)
      }
      catch
      {
	setWikiPage (null)
      }
    }) ()

    setPosts ([])
    void (async () => {
      try
      {
	const res = await axios.get (
	    `${ API_BASE_URL }/posts?${ new URLSearchParams ({ tags:  title,
							       limit: '8' }) }`)
	const data = toCamel (res.data as any,
			      { deep: true }) as { posts:       Post[]
						   nextCursor:  string }
	setPosts (data.posts)
      }
      catch
      {
	;
      }
    }) ()

    void (async () => {
      try
      {
	const res = await axios.get (
	    `${ API_BASE_URL }/tags/name/${ encodeURIComponent (title) }`)
	setTag (toCamel (res.data as any, { deep: true }) as Tag)
      }
      catch
      {
	setTag (defaultTag)
      }
    }) ()

    return () => WikiIdBus.set (null)
  }, [title, location.search])

  return (
      <MainArea>
	<Helmet>
	  <title>{`${ title } Wiki | ${ SITE_TITLE }`}</title>
	  {!(wikiPage?.body) && <meta name="robots" content="noindex"/>}
	</Helmet>

	{(wikiPage && version) && (
	    <div className="text-sm flex gap-3 items-center justify-center border border-gray-700 rounded px-2 py-1 mb-4">
	      {wikiPage.pred ? (
		  <Link to={`/wiki/${ encodeURIComponent (title) }?version=${ wikiPage.pred }`}>
		    &lt; 古
		  </Link>) : '(最古)'}

	      <span>{wikiPage.updatedAt}</span>

	      {wikiPage.succ ? (
		  <Link to={`/wiki/${ encodeURIComponent (title) }?version=${ wikiPage.succ }`}>
		    新 &gt;
		  </Link>) : '(最新)'}
	    </div>)}

	<PageTitle>
	  <TagLink tag={tag}
		   withWiki={false}
		   withCount={false}
		   {...(version && { to: `/wiki/${ encodeURIComponent (title) }` })}/>
	</PageTitle>
	<div className="prose mx-auto p-4">
	  {wikiPage === undefined
	   ? 'Loading...'
	   : <WikiBody title={title} body={wikiPage?.body}/>}
	</div>

	{(!(version) && posts.length > 0) && (
	    <TabGroup>
	      <Tab name="広場">
		<PostList posts={posts}/>
	      </Tab>
	    </TabGroup>)}
      </MainArea>)
}
