import { useEffect, useState, useCallback, useRef } from 'react'
import { useSearchParams, useNavigate } from 'react-router-dom'
import { fetchAPI, putAPI } from '../api/client'
import { useToast } from '../components/Toast'
import StatusBadge from '../components/StatusBadge'
import Pagination from '../components/Pagination'
import ErrorBanner from '../components/ErrorBanner'
import Loading from '../components/Loading'

interface MediaItem {
  id: number
  media_type: string
  title: string
  year: number | null
  status: string
  monitored: boolean
  current_quality: { resolution?: string } | null
}

interface PaginatedResponse {
  data: MediaItem[]
  total: number
  page: number
  page_size: number
  total_pages: number
}

const MEDIA_TYPES = ['all', 'movie', 'series', 'music', 'book', 'audiobook', 'podcast', 'photo', 'other']
const STATUS_FILTERS = ['all', 'available', 'unavailable', 'downloading', 'failed']
const PAGE_SIZE = 50

export default function Library() {
  const [searchParams, setSearchParams] = useSearchParams()
  const navigate = useNavigate()
  const { showToast } = useToast()

  const [items, setItems] = useState<MediaItem[]>([])
  const [total, setTotal] = useState(0)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)

  const q = searchParams.get('q') ?? ''
  const typeFilter = searchParams.get('type') ?? 'all'
  const statusFilter = searchParams.get('status') ?? 'all'
  const page = Number(searchParams.get('page') ?? '1')

  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  const fetchMedia = useCallback(() => {
    setLoading(true)
    setError(null)
    const params = new URLSearchParams()
    if (q) params.set('q', q)
    if (typeFilter !== 'all') params.set('type', typeFilter)
    if (statusFilter !== 'all') params.set('status', statusFilter)
    params.set('page', String(page))
    params.set('page_size', String(PAGE_SIZE))

    fetchAPI<PaginatedResponse>(`/api/media?${params}`)
      .then(res => {
        setItems(res.data ?? [])
        setTotal(res.total)
      })
      .catch(err => setError(err.message || 'Something went wrong. Please try again.'))
      .finally(() => setLoading(false))
  }, [q, typeFilter, statusFilter, page])

  useEffect(() => {
    fetchMedia()
  }, [fetchMedia])

  const updateSearch = (key: string, value: string) => {
    setSearchParams(prev => {
      const next = new URLSearchParams(prev)
      if (value && value !== 'all') {
        next.set(key, value)
      } else {
        next.delete(key)
      }
      if (key !== 'page') next.set('page', '1')
      return next
    })
  }

  const handleSearchInput = (value: string) => {
    if (debounceRef.current) clearTimeout(debounceRef.current)
    debounceRef.current = setTimeout(() => updateSearch('q', value), 300)
  }

  const toggleMonitored = async (item: MediaItem) => {
    const prev = item.monitored
    setItems(items.map(i => i.id === item.id ? { ...i, monitored: !prev } : i))
    try {
      await putAPI(`/api/media/${item.media_type}/${item.id}`, { monitored: !prev })
    } catch {
      setItems(items.map(i => i.id === item.id ? { ...i, monitored: prev } : i))
      showToast('Failed to update monitoring status')
    }
  }

  const totalPages = Math.ceil(total / PAGE_SIZE)

  return (
    <div>
      <h2 className="text-2xl font-semibold mb-6 text-gray-100">Library</h2>

      <div className="flex gap-4 mb-6">
        <label htmlFor="lib-search" className="sr-only">Search media</label>
        <input
          id="lib-search"
          type="text"
          placeholder="Search across all media..."
          defaultValue={q}
          onChange={e => handleSearchInput(e.target.value)}
          className="flex-1 bg-gray-800 border border-gray-700 rounded-lg px-4 py-2 text-gray-100 placeholder-gray-500 text-sm"
        />
        <select
          value={typeFilter}
          onChange={e => updateSearch('type', e.target.value)}
          className="bg-gray-800 border border-gray-700 rounded-lg px-4 py-2 text-gray-100 text-sm"
        >
          {MEDIA_TYPES.map(t => (
            <option key={t} value={t}>{t === 'all' ? 'All Types' : t.charAt(0).toUpperCase() + t.slice(1)}</option>
          ))}
        </select>
        <select
          value={statusFilter}
          onChange={e => updateSearch('status', e.target.value)}
          className="bg-gray-800 border border-gray-700 rounded-lg px-4 py-2 text-gray-100 text-sm"
        >
          {STATUS_FILTERS.map(s => (
            <option key={s} value={s}>{s === 'all' ? 'All Statuses' : s.charAt(0).toUpperCase() + s.slice(1)}</option>
          ))}
        </select>
      </div>

      {error && <ErrorBanner error={error} onRetry={fetchMedia} />}

      {loading && !items.length ? (
        <div className="space-y-2">
          {[1, 2, 3].map(i => (
            <div key={i} className="bg-gray-900 border border-gray-800 rounded-lg p-4 animate-pulse">
              <div className="h-4 bg-gray-800 rounded w-1/3 mb-2" />
              <div className="h-3 bg-gray-800 rounded w-1/5" />
            </div>
          ))}
        </div>
      ) : items.length === 0 ? (
        <div className="text-gray-500 text-center py-20 text-sm">
          {q || typeFilter !== 'all' || statusFilter !== 'all'
            ? 'No media found matching your search'
            : 'Your library is empty. Add media or request new content.'}
        </div>
      ) : (
        <>
<div className="bg-gray-900 border border-gray-800 rounded-lg overflow-hidden">
        <div className="overflow-x-auto">
        <table className="w-full min-w-[640px]">
          <thead>
            <tr className="border-b border-gray-800">
              <th className="text-left px-4 py-3 text-xs font-semibold text-gray-400 uppercase">Title</th>
              <th className="text-left px-4 py-3 text-xs font-semibold text-gray-400 uppercase w-20">Type</th>
              <th className="text-left px-4 py-3 text-xs font-semibold text-gray-400 uppercase w-24">Status</th>
              <th className="text-left px-4 py-3 text-xs font-semibold text-gray-400 uppercase w-24">Quality</th>
              <th className="text-center px-4 py-3 text-xs font-semibold text-gray-400 uppercase w-16">Monitor</th>
            </tr>
          </thead>
          <tbody>
            {items.map(item => (
              <tr
                key={item.id}
                tabIndex={0}
                role="link"
                aria-label={`View ${item.title}`}
                className="border-b border-gray-800/50 hover:bg-gray-800/30 cursor-pointer"
                onClick={() => navigate(`/library/${item.media_type}/${item.id}`)}
                onKeyDown={e => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); navigate(`/library/${item.media_type}/${item.id}`) } }}
              >
                <td className="px-4 py-3">
                  <span className="text-sm text-gray-100 font-normal hover:text-indigo-400">{item.title}</span>
                  {item.year && <span className="text-xs text-gray-500 ml-2">{item.year}</span>}
                </td>
                <td className="px-4 py-3">
                  <span className="text-xs text-gray-400 capitalize">{item.media_type}</span>
                </td>
                <td className="px-4 py-3">
                  <StatusBadge status={item.status} />
                </td>
                <td className="px-4 py-3">
                  <span className="text-sm text-gray-400">
                    {item.current_quality?.resolution ?? '—'}
                  </span>
                </td>
                <td className="px-4 py-3 text-center">
                  <button
                    onClick={e => { e.stopPropagation(); toggleMonitored(item) }}
                    role="switch"
                    aria-checked={item.monitored}
                    className={`relative inline-flex h-5 w-9 items-center rounded-full transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-400 focus-visible:ring-offset-2 focus-visible:ring-offset-gray-900 ${
                      item.monitored ? 'bg-indigo-500' : 'bg-gray-700'
                    }`}
                  >
                    <span className={`inline-block h-3.5 w-3.5 transform rounded-full bg-white transition-transform ${
                      item.monitored ? 'translate-x-4' : 'translate-x-1'
                    }`} />
                  </button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
        </div>
      </div>

          <Pagination
            total={total}
            page={page}
            pageSize={PAGE_SIZE}
            onPageChange={p => setSearchParams(prev => { const n = new URLSearchParams(prev); n.set('page', String(p)); return n })}
          />
        </>
      )}
    </div>
  )
}
