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

import TagLink from '@/components/TagLink'
import WikiBody from '@/components/WikiBody'
import Label from '@/components/common/Label'
import PageTitle from '@/components/common/PageTitle'
import TabGroup, { Tab } from '@/components/common/TabGroup'
import TagInput from '@/components/common/TagInput'
import MainArea from '@/components/layout/MainArea'
import { Button } from '@/components/ui/button'
import { toast } from '@/components/ui/use-toast'
import { SITE_TITLE } from '@/config'
import { apiGet, apiPut } from '@/lib/api'

import type { FC } from 'react'

import type { Material, Tag } from '@/types'

type MaterialWithTag = Material & { tag: Tag }


export default (() => {
  const { id } = useParams ()

  const [file, setFile] = useState<File | null> (null)
  const [filePreview, setFilePreview] = useState ('')
  const [loading, setLoading] = useState (false)
  const [material, setMaterial] = useState<MaterialWithTag | null> (null)
  const [sending, setSending] = useState (false)
  const [tag, setTag] = useState ('')
  const [url, setURL] = useState ('')

  const handleSubmit = async () => {
    const formData = new FormData
    if (tag.trim ())
      formData.append ('tag', tag)
    if (file)
      formData.append ('file', file)
    if (url.trim ())
      formData.append ('url', url)

    try
    {
      setSending (true)
      const data = await apiPut<Material> (`/materials/${ id }`, formData)
      setMaterial (data)
      toast ({ title: '更新成功!' })
    }
    catch
    {
      toast ({ title: '更新失敗……', description: '入力を見直してください．' })
    }
    finally
    {
      setSending (false)
    }
  }

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

    void (async () => {
      try
      {
	setLoading (true)
	const data = await apiGet<MaterialWithTag> (`/materials/${ id }`)
	setMaterial (data)
	setTag (data.tag.name)
	if (data.file && data.contentType)
	  {
	    setFilePreview (data.file)
	    setFile (new File ([await (await fetch (data.file)).blob ()],
			       data.file,
			       { type: data.contentType }))
	  }
	setURL (data.url ?? '')
      }
      finally
      {
	setLoading (false)
      }
    }) ()
  }, [id])

  return (
      <MainArea>
	{material && (
	    <Helmet>
	      <title>{`${ material.tag.name } 素材照会 | ${ SITE_TITLE }`}</title>
	    </Helmet>)}

	{loading ? 'Loading...' : (material && (
	    <>
	      <PageTitle>
		<TagLink
		    tag={material.tag}
		    withWiki={false}
		    withCount={false}/>
	      </PageTitle>

	      {(material.file && material.contentType) && (
		  (/image\/.*/.test (material.contentType) && (
		      <img src={material.file} alt={material.tag.name || undefined}/>))
		  || (/video\/.*/.test (material.contentType) && (
		      <video src={material.file} controls/>))
		  || (/audio\/.*/.test (material.contentType) && (
		      <audio src={material.file} controls/>)))}

	      <TabGroup>
		<Tab name="Wiki">
		  <WikiBody
		      title={material.tag.name}
		      body={material.wikiPageBody ?? undefined}/>
		</Tab>

		<Tab name="編輯">
		  <div className="max-w-wl pt-2 space-y-4">
		    {/* タグ */}
		    <div>
		      <Label>タグ</Label>
		      <TagInput value={tag} setValue={setTag}/>
		    </div>

		    {/* ファイル */}
		    <div>
		      <Label>ファイル</Label>
		      <input
			  type="file"
			  accept="image/*,video/*,audio/*"
			  onChange={e => {
			    const f = e.target.files?.[0]
			    setFile (f ?? null)
			    setFilePreview (f ? URL.createObjectURL (f) : '')
			  }}/>
		      {(file && filePreview) && (
			  (/image\/.*/.test (file.type) && (
			      <img
				  src={filePreview}
				  alt="preview"
				  className="mt-2 max-h-48 rounded border"/>))
			  || (/video\/.*/.test (file.type) && (
			      <video
				  src={filePreview}
				  controls
				  className="mt-2 max-h-48 rounded border"/>))
			  || (/audio\/.*/.test (file.type) && (
			      <audio
				  src={filePreview}
				  controls
				  className="mt-2 max-h-48"/>))
			  || (
			      <p className="text-red-600 dark:text-red-400">
				その形式のファイルには対応していません．
			      </p>))}
		    </div>

		    {/* 参考 URL */}
		    <div>
		      <Label>参考 URL</Label>
		      <input
			  type="url"
			  value={url}
			  onChange={e => setURL (e.target.value)}
			  className="w-full border p-2 rounded"/>
		    </div>

		    {/* 送信 */}
		    <Button
			onClick={handleSubmit}
			className="px-4 py-2 bg-blue-600 text-white rounded disabled:bg-gray-400"
			disabled={sending}>
		      更新
		    </Button>
		  </div>
		</Tab>
	      </TabGroup>
	    </>))}
      </MainArea>)
}) satisfies FC
