import { AnimatePresence, motion } from 'framer-motion'
import { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'

import TagLink from '@/components/TagLink'
import TagSearch from '@/components/TagSearch'
import SectionTitle from '@/components/common/SectionTitle'
import SubsectionTitle from '@/components/common/SubsectionTitle'
import SidebarComponent from '@/components/layout/SidebarComponent'
import { CATEGORIES } from '@/consts'

import type { FC, ReactNode } from 'react'

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

type TagByCategory = { [key in Category]: Tag[] }


const renderTagTree = (
    tag:        Tag,
    nestLevel:  number,
    path:       string,
): ReactNode[] => {
  const key = `${ path }-${ tag.id }`

  const self = (
      <motion.li
	  key={key}
	  layout
	  transition={{ duration: .2, ease: 'easeOut' }}
	  className="mb-1">
	<TagLink tag={tag} nestLevel={nestLevel}/>
      </motion.li>)

  return [self,
	  ...((tag.children
	       ?.sort ((a, b) => a.name < b.name ? -1 : 1)
	       .flatMap (child => renderTagTree (child, nestLevel + 1, key)))
	      ?? [])]
}


type Props = { post: Post | null }


export default (({ post }: Props) => {
  const [tags, setTags] = useState ({ } as TagByCategory)

  const categoryNames: Record<Category, string> = {
      deerjikist: 'ニジラー',
      meme:       '原作・ネタ元・ミーム等',
      character:  'キャラクター',
      general:    '一般',
      material:   '素材',
      meta:       'メタタグ',
      nico:       'ニコニコタグ' }

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

    const tagsTmp = { } as TagByCategory

    for (const tag of post.tags)
      {
	if (!(tag.category in tagsTmp))
	  tagsTmp[tag.category] = []
	tagsTmp[tag.category].push (tag)
      }

    for (const cat of Object.keys (tagsTmp) as (keyof typeof tagsTmp)[])
      tagsTmp[cat].sort ((tagA: Tag, tagB: Tag) => tagA.name < tagB.name ? -1 : 1)

    setTags (tagsTmp)
  }, [post])

  return (
      <SidebarComponent>
	<TagSearch/>
	<motion.div key={post?.id ?? 0} layout>
	  {CATEGORIES.map ((cat: Category) => cat in tags && (
	      <motion.div layout className="my-3" key={cat}>
		<SubsectionTitle>{categoryNames[cat]}</SubsectionTitle>

		<motion.ul layout>
		  <AnimatePresence initial={false}>
		    {tags[cat].map (tag => renderTagTree (tag, 0, `cat-${ cat }`))}
		  </AnimatePresence>
		</motion.ul>
	      </motion.div>))}
	  {post && (
	      <div>
		<SectionTitle>情報</SectionTitle>
		<ul>
		  <li>Id.: {post.id}</li>
		  {/* TODO: uploadedUser の取得を対応したらコメント外す */}
		  {/*
		  <li>
		    <>耕作者: </>
		    {post.uploadedUser
		     ? (
			<Link to={`/users/${ post.uploadedUser.id }`}>
			  {post.uploadedUser.name || '名もなきニジラー'}
			</Link>)
		     : 'bot操作'}
		  </li>
		  */}
		  <li>耕作日時: {(new Date (post.createdAt)).toLocaleString ()}</li>
		  <li>
		    <>リンク: </>
		    <a
			className="break-all"
			href={post.url}
			target="_blank"
			rel="noopener noreferrer nofollow">
		      {post.url}
		    </a>
		  </li>
		  <li>
		    {/* TODO: 表示形式きしょすぎるので何とかする */}
		    <>オリジナルの投稿日時: </>
		    {!(post.originalCreatedFrom) && !(post.originalCreatedBefore)
		     ? '不明'
		     : (
			<>
			  {post.originalCreatedFrom
			   && `${ (new Date (post.originalCreatedFrom)).toLocaleString () } 以降 `}
			  {post.originalCreatedBefore
			   && `${ (new Date (post.originalCreatedBefore)).toLocaleString () } より前`}
			</>)}
		  </li>
		  <li>
		    <Link to={`/posts/changes?id=${ post.id }`}>履歴</Link>
		  </li>
		</ul>
	      </div>)}
	</motion.div>
      </SidebarComponent>)
}) satisfies FC<Props>
