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

import PostList from '@/components/PostList'
import TagDetailSidebar from '@/components/TagDetailSidebar'
import PostEditForm from '@/components/PostEditForm'
import PostEmbed from '@/components/PostEmbed'
import TabGroup, { Tab } from '@/components/common/TabGroup'
import MainArea from '@/components/layout/MainArea'
import { Button } from '@/components/ui/button'
import { toast } from '@/components/ui/use-toast'
import { API_BASE_URL, SITE_TITLE } from '@/config'
import { cn } from '@/lib/utils'
import NotFound from '@/pages/NotFound'
import ServiceUnavailable from '@/pages/ServiceUnavailable'

import type { FC } from 'react'

import type { Post, User } from '@/types'

type Props = { user: User | null }


export default (({ user }: Props) => {
  const { id } = useParams ()

  const [post, setPost] = useState<Post | null> (null)
  const [status, setStatus] = useState (200)

  const changeViewedFlg = async () => {
    const url = `${ API_BASE_URL }/posts/${ id }/viewed`
    const opt = { headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') || '' } }
    try
    {
      if (post!.viewed)
	await axios.delete (url, opt)
      else
	await axios.post (url, { }, opt)

      // 通信に成功したら “閲覧済” をトグル
      setPost (post => ({ ...post!, viewed: !(post!.viewed) }))
    }
    catch
    {
      toast ({ title: '失敗……', description: '通信に失敗しました……' })
    }
  }

  useEffect (() => {
    setPost (null)

    if (!(id))
      return

    const fetchPost = async () => {
      try
      {
	const res = await axios.get (`${ API_BASE_URL }/posts/${ id }`, { headers: {
	    'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } })
	setPost (toCamel (res.data as any, { deep: true }) as Post)
      }
      catch (err)
      {
	if (axios.isAxiosError (err))
	  setStatus (err.status ?? 200)
      }
    }
    fetchPost ()
  }, [id])

  switch (status)
  {
  case 404:
    return <NotFound/>
  case 503:
    return <ServiceUnavailable/>
  }

  const viewedClass = (post?.viewed
		       ? 'bg-blue-600 hover:bg-blue-700'
		       : 'bg-gray-500 hover:bg-gray-600')

  return (
      <div className="md:flex md:flex-1">
	<Helmet>
	  {(post?.thumbnail || post?.thumbnailBase) && (
	      <meta name="thumbnail" content={post.thumbnail || post.thumbnailBase}/>)}
	  {post && <title>{`${ post.title || post.url } | ${ SITE_TITLE }`}</title>}
	</Helmet>
	<div className="hidden md:block">
	  <TagDetailSidebar post={post}/>
	</div>
	<MainArea>
	  {post
	   ? (
	      <>
		<PostEmbed post={post}/>
		<Button onClick={changeViewedFlg}
			className={cn ('text-white', viewedClass)}>
		  {post.viewed ? '閲覧済' : '未閲覧'}
		</Button>
		<TabGroup>
		  <Tab name="関聯">
		    {post.related.length > 0
		     ? <PostList posts={post.related}/>
		     : 'まだないよ（笑）'}
		  </Tab>
		  {['admin', 'member'].some (r => user?.role === r) && (
		      <Tab name="編輯">
			<PostEditForm post={post}
				      onSave={newPost => {
					setPost (newPost)
					toast ({ description: '更新しました．' })
				      }}/>
		      </Tab>)}
		</TabGroup>
	      </>)
	   : 'Loading...'}
	</MainArea>
	<div className="md:hidden">
	  <TagDetailSidebar post={post}/>
	</div>
      </div>)
}) satisfies FC<Props>
