import React, { useEffect, useState, useRef } from 'react'
import { Link, useLocation, useParams, useNavigate } from 'react-router-dom'
import axios from 'axios'
import { API_BASE_URL, SITE_TITLE } from '../config'
import NicoViewer from '../components/NicoViewer'
import { Button } from '@/components/ui/button'
import { toast } from '@/components/ui/use-toast'
import { cn } from '@/lib/utils'

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


type Props = { posts:     Post[]
               setPosts:  (posts: Post[]) => void }


const PostNewPage = () => {
  const location = useLocation ()
  const navigate = useNavigate ()

  const [title, setTitle] = useState ('')
  const [titleAutoFlg, setTitleAutoFlg] = useState (true)
  const [titleLoading, setTitleLoading] = useState (false)
  const [url, setURL] = useState ('')
  const [thumbnailFile, setThumbnailFile] = useState<File | null> (null)
  const [thumbnailPreview, setThumbnailPreview] = useState<string> ('')
  const [thumbnailAutoFlg, setThumbnailAutoFlg] = useState (true)
  const [thumbnailLoading, setThumbnailLoading] = useState (false)
  const [tags, setTags] = useState<Tag[]> ([])
  const [tagIds, setTagIds] = useState<number[]> ([])
  const previousURLRef = useRef ('')

  const handleSubmit = () => {
    const formData = new FormData ()
    formData.append ('title', title)
    formData.append ('url', url)
    formData.append ('tags', JSON.stringify (tagIds))
    formData.append ('thumbnail', thumbnailFile)

    void (axios.post (`${ API_BASE_URL }/posts`, formData, { headers: {
              'Content-Type':     'multipart/form-data',
              'X-Transfer-Code':  localStorage.getItem ('user_code') || '' } })
          .then (() => {
            toast ({ title: '投稿成功!' })
            navigate ('/posts')
          })
          .catch (e => toast ({ title:        '投稿失敗',
                                description:  '入力を確認してください。' })))
  }

  document.title = `広場に投稿を追加 | ${ SITE_TITLE }`

  useEffect (() => {
    void (axios.get ('/api/tags')
          .then (res => setTags (res.data))
          .catch (() => toast ({ title: 'タグ一覧の取得失敗' })))
  }, [])

  useEffect (() => {
    if (titleAutoFlg && url)
      fetchTitle ()
  }, [titleAutoFlg])

  useEffect (() => {
    if (thumbnailAutoFlg && url)
      fetchThumbnail ()
  }, [thumbnailAutoFlg])

  const handleURLBlur = () => {
    if (!(url) || url === previousURLRef.current)
      return

    if (titleAutoFlg)
      fetchTitle ()
    if (thumbnailAutoFlg)
      fetchThumbnail ()
    previousURLRef.current = url
  }

  const fetchTitle = () => {
    setTitle ('')
    setTitleLoading (true)
    void (axios.get (`${ API_BASE_URL }/preview/title`, {
              params:   { url },
              headers:  { 'X-Transfer-Code': localStorage.getItem ('user_code') || '' } })
          .then (res => {
            setTitle (res.data.title || '')
            setTitleLoading (false)
          })
          .finally (() => setTitleLoading (false)))
  }

  const fetchThumbnail = () => {
    setThumbnailPreview ('')
    setThumbnailFile (null)
    setThumbnailLoading (true)
    if (thumbnailPreview)
      URL.revokeObjectURL (thumbnailPreview)
    void (axios.get (`${ API_BASE_URL }/preview/thumbnail`, {
              params:       { url },
              headers:      { 'X-Transfer-Code': localStorage.getItem ('user_code') || '' },
              responseType: 'blob' })
          .then (res => {
            const imageURL = URL.createObjectURL (res.data)
            setThumbnailPreview (imageURL)
            setThumbnailFile (new File ([res.data],
                                        'thumbnail.png',
                                        { type: res.data.type || 'image/png' }))
            setThumbnailLoading (false)
          })
          .finally (() => setThumbnailLoading (false)))
  }

  return (
      <div className="max-w-xl mx-auto p-4 space-y-4">
        <h1 className="text-2xl font-bold mb-2">広場に投稿を追加する</h1>

        {/* URL */}
        <div>
          <label className="block font-semibold mb-1">URL</label>
          <input type="text"
                 placeholder="例：https://www.nicovideo.jp/watch/..."
                 value={url}
                 onChange={e => setURL (e.target.value)}
                 className="w-full border p-2 rounded"
                 onBlur={handleURLBlur} />
        </div>

        {/* タイトル */}
        <div>
          <div className="flex gap-2 mb-1">
            <label className="flex-1 block font-semibold">タイトル</label>
            <label className="flex items-center block gap-1">
              <input type="checkbox"
                     checked={titleAutoFlg}
                     onChange={e => setTitleAutoFlg (e.target.checked)} />
              自動
            </label>
          </div>
          <input type="text"
                 className="w-full border rounded p-2"
                 value={title}
                 placeholder={titleLoading ? 'Loading...' : ''}
                 onChange={e => setTitle (e.target.value)}
                 disabled={titleAutoFlg} />
        </div>

        {/* サムネール */}
        <div>
          <div className="flex gap-2 mb-1">
            <label className="block font-semibold flex-1">サムネール</label>
            <label className="flex items-center gap-1">
              <input type="checkbox"
                     checked={thumbnailAutoFlg}
                     onChange={e => setThumbnailAutoFlg (e.target.checked)} />
              自動
            </label>
          </div>
          {thumbnailAutoFlg
           ? (thumbnailLoading
              ? <p className="text-gray-500 text-sm">Loading...</p>
              : !(thumbnailPreview) && (
                  <p className="text-gray-500 text-sm">
                    URL から自動取得されます。
                  </p>))
           : (
              <input type="file"
                     accept="image/*"
                     onChange={e => {
                       const file = e.target.files?.[0]
                       if (file)
                         {
                           setThumbnailFile (file)
                           setThumbnailPreview (URL.createObjectURL (file))
                         }
                     }} />)}
          {thumbnailPreview && (
              <img src={thumbnailPreview}
                   alt="preview"
                   className="mt-2 max-h-48 rounded border" />)}
        </div>

        {/* タグ */}
        <div>
          <label className="block font-semibold">タグ</label>
          <select multiple
                  value={tagIds.map (String)}
                  onChange={e => {
                    const values = Array.from (e.target.selectedOptions).map (o => Number (o.value))
                    setTagIds (values)
                  }}
                  className="w-full p-2 border rounded h-32">
            {tags.map ((tag: Tag) => (
                <option key={tag.id} value={tag.id}>
                  {tag.name}
                </option>))}
          </select>
        </div>

        {/* 送信 */}
        <button onClick={handleSubmit}
                className="px-4 py-2 bg-blue-600 text-white rounded disabled:bg-gray-400"
                disabled={titleLoading || thumbnailLoading}>
          追加
        </button>
      </div>)
}


export default PostNewPage
