import { useEffect, useState, useCallback, useRef } from 'react'
import { fetchAPI, deleteAPI, postAPI } from '../api/client'
import { useToast } from '../components/Toast'
import StatusBadge from '../components/StatusBadge'
import ErrorBanner from '../components/ErrorBanner'
import Loading from '../components/Loading'
import ConfirmModal from '../components/ConfirmModal'
import Pagination from '../components/Pagination'

interface QueueItem {
  id: number
  media_id: number
  release_title: string
  indexer: string
  download_client: string
  quality: { resolution?: string } | null
  size: number | null
  status: string
  progress: number
  error_message: string | null
  protocol: string
  created_at: string
  updated_at: string
}

interface ImportReport {
  imported: number
  skipped: number
  errors: number
  results: ImportResult[]
}

interface ImportResult {
  media_id: number
  media_type: string
  source_path: string
  dest_path: string
  file_size: number
  quality: string
  status: string
}

interface ImportHistoryItem {
  id: number
  media_id: number
  media_type: string
  action: string
  release_title: string
  quality: string
  created_at: string
}

const TABS = ['all', 'downloading', 'pending', 'failed', 'imported', 'history'] as const

export default function Queue() {
  const { showToast } = useToast()
  const [items, setItems] = useState<QueueItem[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [activeTab, setActiveTab] = useState<string>('all')
  const [cancelTarget, setCancelTarget] = useState<QueueItem | null>(null)
  const [clearAllConfirm, setClearAllConfirm] = useState(false)
  const [importing, setImporting] = useState(false)
  const [importHistory, setImportHistory] = useState<ImportHistoryItem[]>([])
  const [historyPage, setHistoryPage] = useState(1)
  const [historyTotal, setHistoryTotal] = useState(0)
  const historyPageSize = 50
  const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null)

  const fetchQueue = useCallback(() => {
    setError(null)
    const params = new URLSearchParams()
    if (activeTab !== 'all') params.set('status', activeTab)

    fetchAPI<{ data: QueueItem[] }>(`/api/queue?${params}`)
      .then(res => setItems(res.data ?? []))
      .catch(err => {
        setError(err.message || 'Something went wrong. Please try again.')
        if (intervalRef.current) {
          clearInterval(intervalRef.current)
          intervalRef.current = null
        }
      })
      .finally(() => setLoading(false))
  }, [activeTab])

  useEffect(() => {
    setLoading(true)
    fetchQueue()

    intervalRef.current = setInterval(fetchQueue, 5000)
    return () => {
      if (intervalRef.current) clearInterval(intervalRef.current)
    }
  }, [fetchQueue])

  const fetchImportHistory = useCallback(() => {
    fetchAPI<{ data: ImportHistoryItem[]; total: number; page: number; page_size: number; total_pages: number }>(`/api/imports/history?page=${historyPage}&page_size=${historyPageSize}`)
      .then(res => {
        setImportHistory(res.data ?? [])
        setHistoryTotal(res.total)
      })
      .catch(() => {
        setImportHistory([])
        setHistoryTotal(0)
      })
  }, [historyPage])

  useEffect(() => {
    if (activeTab === 'history') {
      fetchImportHistory()
    }
  }, [activeTab, fetchImportHistory])

  const cancelItem = async (item: QueueItem) => {
    try {
      await deleteAPI(`/api/queue/${item.id}`)
      setItems(items.filter(i => i.id !== item.id))
      showToast('Download cancelled')
    } catch {
      showToast('Failed to cancel download')
    }
    setCancelTarget(null)
  }

  const retryItem = async (item: QueueItem) => {
    try {
      await postAPI(`/api/queue/${item.id}/retry`, {})
      showToast('Retrying download')
      fetchQueue()
    } catch {
      showToast('Failed to retry download')
    }
  }

  const retryAllFailed = async () => {
    try {
      await postAPI('/api/queue/retry-failed', {})
      showToast('Retrying all failed downloads')
      fetchQueue()
    } catch {
      showToast('Failed to retry downloads')
    }
  }

  const clearCompleted = async () => {
    try {
      await postAPI('/api/queue/clear', {})
      showToast('Completed downloads cleared')
      fetchQueue()
    } catch {
      showToast('Failed to clear downloads')
    }
  }

  const triggerImport = async () => {
    setImporting(true)
    try {
      const report = await postAPI<ImportReport>('/api/imports/trigger', {})
      showToast(`Import complete: ${report.imported} imported, ${report.skipped} skipped, ${report.errors} errors`)
      fetchQueue()
      if (activeTab === 'history') fetchImportHistory()
    } catch {
      showToast('Failed to trigger import')
    } finally {
      setImporting(false)
    }
  }

  const formatSize = (bytes: number | null): string => {
    if (!bytes) return '—'
    const gb = bytes / 1e9
    return gb >= 1 ? `${gb.toFixed(1)} GB` : `${(bytes / 1e6).toFixed(1)} MB`
  }

  const failedCount = items.filter(i => i.status === 'failed').length
  const completedCount = items.filter(i => i.status === 'imported').length

  return (
    <div>
      <div className="flex justify-between items-center mb-6">
        <h2 className="text-2xl font-semibold text-gray-100">Download Queue</h2>
        <div className="flex gap-2">
          <button
            onClick={triggerImport}
            disabled={importing}
            className="bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 px-4 py-2 rounded text-sm font-semibold min-h-[36px]"
          >
            {importing ? 'Importing...' : 'Check for Completed Downloads'}
          </button>
          {completedCount > 0 && (
            <button onClick={clearCompleted} className="bg-orange-600 hover:bg-orange-500 px-4 py-2 rounded text-sm font-semibold min-h-[36px]">
              Clear Completed
            </button>
          )}
          {failedCount > 0 && (
            <button onClick={retryAllFailed} className="bg-gray-700 hover:bg-gray-600 px-4 py-2 rounded text-sm font-semibold min-h-[36px]">
              Retry All Failed
            </button>
          )}
        </div>
      </div>

      <div className="flex gap-1 mb-4">
        {TABS.map(tab => (
          <button
            key={tab}
            onClick={() => { setActiveTab(tab); setLoading(true) }}
            className={`px-4 py-2 text-sm rounded capitalize ${activeTab === tab ? 'bg-indigo-400 text-gray-950' : 'bg-gray-800 text-gray-400 hover:bg-gray-700'}`}
          >
            {tab}
          </button>
        ))}
      </div>

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

      {loading ? (
        <Loading />
      ) : items.length === 0 ? (
        <div className="text-gray-500 text-center py-20 text-sm">No active downloads</div>
      ) : (
        <div className="space-y-2">
          {items.map(item => (
            <div key={item.id} className="bg-gray-900 border border-gray-800 rounded-lg p-4">
              <div className="flex items-center justify-between mb-2">
                <div className="flex-1 min-w-0 mr-4">
                  <p className="text-sm text-gray-100 truncate">{item.release_title}</p>
                  <div className="flex items-center gap-3 mt-1">
                    <StatusBadge status={item.status} />
                    <span className="text-xs text-gray-500">{item.download_client}</span>
                    {item.quality?.resolution && (
                      <span className="text-xs text-gray-400">{item.quality.resolution}</span>
                    )}
                    <span className="text-xs text-gray-500">{formatSize(item.size)}</span>
                  </div>
                </div>
                <div className="flex items-center gap-2">
                  {item.status === 'failed' && (
                    <button onClick={() => retryItem(item)} className="text-xs text-indigo-400 hover:text-indigo-300 min-h-[36px] px-2">
                      Retry
                    </button>
                  )}
                  {(item.status === 'downloading' || item.status === 'pending' || item.status === 'failed') && (
                    <button
                      onClick={() => {
                        if (item.status === 'downloading') {
                          setCancelTarget(item)
                        } else {
                          cancelItem(item)
                        }
                      }}
                      className="text-xs text-red-400 hover:text-red-300 min-h-[36px] px-2"
                    >
                      Cancel
                    </button>
                  )}
                </div>
              </div>
              {(item.status === 'downloading' || item.status === 'pending') && (
                <div className="w-full bg-gray-800 rounded-full h-1.5">
                  <div
                    className="bg-indigo-400 h-1.5 rounded-full transition-all duration-500"
                    style={{ width: `${Math.min(100, item.progress * 100)}%` }}
                  />
                </div>
              )}
              {item.status === 'downloading' && (
                <p className="text-xs text-gray-500 mt-1">{(item.progress * 100).toFixed(0)}%</p>
              )}
              {item.error_message && (
                <p className="text-xs text-red-400 mt-1">{item.error_message}</p>
              )}
            </div>
          ))}
        </div>
      )}

      {activeTab === 'history' && (
        <div>
          {importHistory.length === 0 ? (
            <div className="text-gray-500 text-center py-20 text-sm">No import history yet</div>
          ) : (
            <>
              <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="text-left px-4 py-3 text-xs font-semibold text-gray-400 uppercase">Release Title</th>
                      <th className="text-left px-4 py-3 text-xs font-semibold text-gray-400 uppercase w-28">Media Type</th>
                      <th className="text-left px-4 py-3 text-xs font-semibold text-gray-400 uppercase w-24">Quality</th>
                      <th className="text-left px-4 py-3 text-xs font-semibold text-gray-400 uppercase w-40">Imported At</th>
                    </tr>
                  </thead>
                  <tbody>
                    {importHistory.map(item => (
                      <tr key={item.id} className="border-b border-gray-800/50 hover:bg-gray-800/30">
                        <td className="px-4 py-3 text-sm text-gray-200 max-w-md truncate">{item.release_title || '—'}</td>
                        <td className="px-4 py-3 text-sm text-gray-400 capitalize">{item.media_type}</td>
                        <td className="px-4 py-3 text-sm text-gray-400">{item.quality || '—'}</td>
                        <td className="px-4 py-3 text-sm text-gray-400">{new Date(item.created_at).toLocaleString()}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
              <Pagination total={historyTotal} page={historyPage} pageSize={historyPageSize} onPageChange={setHistoryPage} />
            </>
          )}
        </div>
      )}

      <ConfirmModal
        open={!!cancelTarget}
        title="Cancel Download"
        message={`Cancel "${cancelTarget?.release_title ?? ''}"? This will remove it from the queue.`}
        onConfirm={() => cancelTarget && cancelItem(cancelTarget)}
        onCancel={() => setCancelTarget(null)}
        destructive
        confirmLabel="Cancel Download"
      />

      <ConfirmModal
        open={clearAllConfirm}
        title="Clear All Completed"
        message="Remove all completed downloads from the queue?"
        onConfirm={() => { clearCompleted(); setClearAllConfirm(false) }}
        onCancel={() => setClearAllConfirm(false)}
        destructive
      />
    </div>
  )
}
