import type { FC } from 'react'

import { useQuery } from '@tanstack/react-query'
import { useEffect, useMemo } from 'react'
import { Helmet } from 'react-helmet-async'
import { useLocation, useNavigate, useParams } from 'react-router-dom'

import PostList from '@/components/PostList'
import PrefetchLink from '@/components/PrefetchLink'
import TagLink from '@/components/TagLink'
import WikiBody from '@/components/WikiBody'
import TabGroup, { Tab } from '@/components/common/TabGroup'
import MainArea from '@/components/layout/MainArea'
import { SITE_TITLE } from '@/config'
import { WikiIdBus } from '@/lib/eventBus/WikiIdBus'
import { fetchPosts } from '@/lib/posts'
import { postsKeys, tagsKeys, wikiKeys } from '@/lib/queryKeys'
import { fetchTagByName } from '@/lib/tags'
import { fetchWikiPage, fetchWikiPageByTitle } from '@/lib/wiki'

import type { Tag } from '@/types'


const WikiDetailPage: FC = () => {
  const params = useParams ()
  const title = params.title ?? ''

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

  const defaultTag = useMemo (() => ({ name: title, category: 'general' } as Tag), [title])

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

  const { data: wikiPage, isLoading: loading } = useQuery ({
      enabled:  Boolean (title) && !(/^\d+$/.test (title)),
      queryKey: wikiKeys.show (title, { version }),
      queryFn:  () => fetchWikiPageByTitle (title, { version }) })

  const effectiveTitle = wikiPage?.title ?? title
  const deprecated = wikiPage?.deprecatedAt != null

  const { data: tag } = useQuery ({
      enabled:  Boolean (effectiveTitle),
      queryKey: tagsKeys.show (effectiveTitle),
      queryFn:  () => fetchTagByName (effectiveTitle) })

  const keys = {
      tags: effectiveTitle, match: 'all', page: 1, limit: 8, url: '', title: '',
      originalCreatedFrom: '', originalCreatedTo: '',
      createdFrom: '', createdTo: '', updatedFrom: '', updatedTo: '',
      order: 'original_created_at:desc' } as const
  const { data } = useQuery ({
      enabled:  Boolean (effectiveTitle) && !(version),
      queryKey: postsKeys.index (keys),
      queryFn:  () => fetchPosts (keys) })
  const posts = data?.posts || []

  useEffect (() => {
    if (!(wikiPage))
      return

    WikiIdBus.set (wikiPage.id)

    if (wikiPage.title !== title)
      navigate (`/wiki/${ encodeURIComponent(wikiPage.title) }`, { replace: true })

    return () => WikiIdBus.set (null)
  }, [wikiPage, title, navigate])

  useEffect (() => {
    if (!(/^\d+$/.test (title)))
      return

    void (async () => {
      try
      {
	const data = await fetchWikiPage (title, { })
	navigate (`/wiki/${ encodeURIComponent(data.title) }`, { replace: true })
      }
      catch
      {
	;
      }
    }) ()
  }, [title, navigate])

  return (
      <MainArea>
	<Helmet>
	  <title>{`${ effectiveTitle }${ deprecated ? '（廃止）' : '' } 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 ? (
		  <PrefetchLink to={`/wiki/${ encodeURIComponent (title) }?version=${ wikiPage.pred }`}>
		    &lt; 古
		  </PrefetchLink>) : '(最古)'}

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

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

	<article className="prose dark:prose-invert mx-auto p-4">
	  <h1 className="prose-a:no-underline">
	    <TagLink tag={tag ?? { ...defaultTag,
				   name: effectiveTitle,
				   deprecatedAt: wikiPage?.deprecatedAt ?? null }}
		     withWiki={false}
		     withCount={false}
		     {...(version && { to: `/wiki/${ encodeURIComponent (title) }` })}/>
	    {deprecated && <span>（廃止）</span>}
	  </h1>
	  {loading ? <div>Loading...</div> : <WikiBody title={title} body={wikiPage?.body}/>}

	  {(!(version) && posts.length > 0) && (
	      <div className="not-prose">
		<TabGroup>
		  <Tab name="広場">
		    <PostList posts={posts}/>
		  </Tab>
		</TabGroup>
	      </div>)}
	</article>
      </MainArea>)
}

export default WikiDetailPage
