import { useState } from 'react'
import { postAPI } from '../api/client'
import { useToast } from './Toast'

interface SearchResult {
  title: string
  guid: string
  size: number
  pub_date: string
  indexer_name: string
  indexer_priority: number
  quality: {
    title: string
    resolution: string
    source: string
    video_codec: string
    release_group: string
    parse_warning: boolean
  }
  quality_tier: {
    name: string
    rank: number
    resolution: string
  } | null
  seeders: number
  peers: number
  category: string
  download_url: string
  source_indexers: string[]
}

interface GrabPayload {
  download_url: string
  title: string
  media_type: string
  quality: SearchResult['quality']
  indexer_name: string
  media_id: number
}

interface ReleaseSearchResultsProps {
  results: SearchResult[]
  mediaId: number
  mediaType: string
  loading?: boolean
}

type SortCol = 'quality' | 'size' | 'seeders' | 'age'
type SortDir = 'asc' | 'desc'

function formatFileSize(bytes: number): string {
  if (bytes >= 1024 * 1024 * 1024) {
    return `${(bytes / 1024 / 1024 / 1024).toFixed(2)} GB`
  }
  if (bytes >= 1024 * 1024) {
    return `${(bytes / 1024 / 1024).toFixed(1)} MB`
  }
  return `${(bytes / 1024).toFixed(0)} KB`
}

function formatAge(dateStr: string): string {
  const diff = Date.now() - new Date(dateStr).getTime()
  const minutes = Math.floor(diff / 60000)
  if (minutes < 1) return 'now'
  if (minutes < 60) return `${minutes}m`
  const hours = Math.floor(minutes / 60)
  if (hours < 24) return `${hours}h`
  const days = Math.floor(hours / 24)
  if (days < 30) return `${days}d`
  const months = Math.floor(days / 30)
  return `${months}mo`
}

export function ReleaseSearchResults({ results, mediaId, mediaType, loading }: ReleaseSearchResultsProps) {
  const [sortCol, setSortCol] = useState<SortCol>('quality')
  const [sortDir, setSortDir] = useState<SortDir>('asc')
  const [grabbing, setGrabbing] = useState<Set<string>>(new Set())
  const { showToast } = useToast()

  function handleSort(col: SortCol) {
    if (sortCol === col) {
      setSortDir(prev => (prev === 'asc' ? 'desc' : 'asc'))
    } else {
      setSortCol(col)
      setSortDir('asc')
    }
  }

  const sorted = [...results].sort((a, b) => {
    let cmp = 0
    switch (sortCol) {
      case 'quality':
        cmp = (a.quality_tier?.rank ?? 999) - (b.quality_tier?.rank ?? 999)
        break
      case 'size':
        cmp = a.size - b.size
        break
      case 'seeders':
        cmp = a.seeders - b.seeders
        break
      case 'age':
        cmp = new Date(a.pub_date).getTime() - new Date(b.pub_date).getTime()
        break
    }
    return sortDir === 'asc' ? cmp : -cmp
  })

  async function handleGrab(result: SearchResult) {
    setGrabbing(prev => new Set(prev).add(result.guid))
    try {
      await postAPI<{ queue_id: number }>('/api/releases/grab', {
        download_url: result.download_url,
        title: result.title,
        media_type: mediaType,
        quality: result.quality,
        indexer_name: result.indexer_name,
        media_id: mediaId,
      } satisfies GrabPayload)
      showToast(`✓ Grabbed "${result.title}"`)
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Unknown error'
      showToast(`✗ Failed to grab: ${message}`)
    } finally {
      setGrabbing(prev => {
        const next = new Set(prev)
        next.delete(result.guid)
        return next
      })
    }
  }

  function SortHeader({ col, label }: { col: SortCol; label: string }) {
    const active = sortCol === col
    return (
      <button
        onClick={() => handleSort(col)}
        className={`text-left text-xs font-semibold uppercase tracking-wide transition-colors ${
          active ? 'text-indigo-400 hover:text-indigo-300' : 'text-gray-400 hover:text-gray-200'
        }`}
      >
        {label} {active && (sortDir === 'asc' ? '▲' : '▼')}
      </button>
    )
  }

  if (loading) {
    return (
      <div className="animate-pulse space-y-3">
        <div className="h-10 bg-gray-800 rounded" />
        <div className="h-10 bg-gray-800 rounded" />
        <div className="h-10 bg-gray-800 rounded" />
      </div>
    )
  }

  if (results.length === 0) {
    return <div className="text-gray-500 text-sm text-center py-12">No releases found</div>
  }

  return (
    <div className="bg-gray-900 border border-gray-800 rounded-lg overflow-hidden">
      <table className="w-full">
        <thead>
          <tr className="border-b border-gray-800">
            <th className="px-4 py-3"><SortHeader col="quality" label="Quality" /></th>
            <th className="px-4 py-3 text-left text-xs font-semibold text-gray-400 uppercase tracking-wide">Title</th>
            <th className="px-4 py-3"><SortHeader col="size" label="Size" /></th>
            <th className="px-4 py-3 text-left text-xs font-semibold text-gray-400 uppercase tracking-wide">Indexer</th>
            <th className="px-4 py-3"><SortHeader col="seeders" label="Seeders" /></th>
            <th className="px-4 py-3"><SortHeader col="age" label="Age" /></th>
            <th className="px-4 py-3 text-left text-xs font-semibold text-gray-400 uppercase tracking-wide w-20">Action</th>
          </tr>
        </thead>
        <tbody>
          {sorted.map(result => {
            const isGrabbing = grabbing.has(result.guid)
            const noUrl = !result.download_url
            return (
              <tr key={result.guid} className="border-b border-gray-800/50 hover:bg-gray-800/30">
                <td className="px-4 py-3 text-sm">
                  {result.quality_tier ? (
                    <span className="text-gray-200">{result.quality_tier.name}</span>
                  ) : result.quality.resolution || result.quality.source ? (
                    <span className="text-gray-200">{result.quality.resolution} {result.quality.source}</span>
                  ) : (
                    <span className="text-gray-500">Unknown</span>
                  )}
                </td>
                <td className="px-4 py-3 text-sm text-gray-200 max-w-lg truncate" title={result.title}>
                  {result.title}
                </td>
                <td className="px-4 py-3 text-sm text-gray-400">{formatFileSize(result.size)}</td>
                <td className="px-4 py-3 text-sm text-gray-400">{result.indexer_name}</td>
                <td className="px-4 py-3 text-sm text-gray-400">
                  <span className={result.seeders > 0 ? 'text-green-400' : ''}>{result.seeders}</span>
                  {' / '}
                  <span>{result.peers}</span>
                </td>
                <td className="px-4 py-3 text-sm text-gray-400">{formatAge(result.pub_date)}</td>
                <td className="px-4 py-3">
                  <button
                    disabled={isGrabbing || noUrl}
                    onClick={() => handleGrab(result)}
                    className="px-3 py-1 text-xs font-semibold rounded bg-indigo-600 hover:bg-indigo-500 text-white disabled:opacity-50 disabled:cursor-not-allowed"
                  >
                    {isGrabbing ? 'Grabbing...' : noUrl ? 'N/A' : 'Grab'}
                  </button>
                </td>
              </tr>
            )
          })}
        </tbody>
      </table>
    </div>
  )
}

export default ReleaseSearchResults
