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

interface RequestItem {
  id: number
  media_id: number
  title: string
  media_type: string
  year: number | null
  quality_profile_id: number | null
  quality_profile_name: string | null
  root_folder_id: number | null
  root_folder_path: string | null
  status: string
  requested_by: string
  notes: string | null
  created_at: string
  updated_at: string
}

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

interface QualityProfile {
  id: number
  name: string
}

interface RootFolder {
  id: number
  path: string
  media_type: string
}

const PAGE_SIZE = 20

const FILTER_TABS = [
  { value: '', label: 'All' },
  { value: 'pending', label: 'Pending' },
  { value: 'approved', label: 'Approved' },
  { value: 'fulfilled', label: 'Fulfilled' },
  { value: 'rejected', label: 'Rejected' },
]

const MEDIA_TYPES = ['movie', 'series', 'music', 'book', 'audiobook', 'podcast', 'other']

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

export default function Requests() {
  const { showToast } = useToast()
  const [requests, setRequests] = useState<RequestItem[]>([])
  const [total, setTotal] = useState(0)
  const [page, setPage] = useState(1)
  const [statusFilter, setStatusFilter] = useState('')
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)

  // New request modal
  const [showNewModal, setShowNewModal] = useState(false)
  const [newTitle, setNewTitle] = useState('')
  const [newType, setNewType] = useState('movie')
  const [newYear, setNewYear] = useState('')
  const [newQualityId, setNewQualityId] = useState<number | ''>('')
  const [newRootFolderId, setNewRootFolderId] = useState<number | ''>('')
  const [submitting, setSubmitting] = useState(false)
  const [formError, setFormError] = useState<string | null>(null)

  // Reject confirmation
  const [rejectTarget, setRejectTarget] = useState<RequestItem | null>(null)

  // Dropdown data
  const [qualityProfiles, setQualityProfiles] = useState<QualityProfile[]>([])
  const [rootFolders, setRootFolders] = useState<RootFolder[]>([])

  const fetchRequests = useCallback(() => {
    setLoading(true)
    setError(null)
    const params = new URLSearchParams({ page: String(page), page_size: String(PAGE_SIZE) })
    if (statusFilter) params.set('status', statusFilter)
    fetchAPI<PaginatedResponse>(`/api/requests?${params}`)
      .then(res => {
        setRequests(res.data ?? [])
        setTotal(res.total)
      })
      .catch(err => setError(err.message || 'Something went wrong. Please try again.'))
      .finally(() => setLoading(false))
  }, [page, statusFilter])

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

  // Fetch dropdown data on mount
  useEffect(() => {
    fetchAPI<{ data: QualityProfile[] }>('/api/quality-profiles?page=1&page_size=100')
      .then(res => setQualityProfiles(res.data ?? []))
      .catch(() => {})

    fetchAPI<{ data: RootFolder[] }>('/api/root-folders?page=1&page_size=100')
      .then(res => setRootFolders(res.data ?? []))
      .catch(() => {})
  }, [])

  const handleFilterChange = (value: string) => {
    setStatusFilter(value)
    setPage(1)
  }

  const openNewModal = () => {
    setNewTitle('')
    setNewType('movie')
    setNewYear('')
    setNewQualityId('')
    setNewRootFolderId('')
    setFormError(null)
    setShowNewModal(true)
  }

  const submitNewRequest = async () => {
    if (!newTitle.trim()) {
      setFormError('Title is required')
      return
    }
    setSubmitting(true)
    setFormError(null)
    try {
      const body: Record<string, unknown> = {
        title: newTitle.trim(),
        media_type: newType,
      }
      if (newYear) body.year = parseInt(newYear, 10)
      if (newQualityId !== '') body.quality_profile_id = newQualityId
      if (newRootFolderId !== '') body.root_folder_id = newRootFolderId

      await postAPI('/api/requests', body)
      showToast('Request submitted')
      setShowNewModal(false)
      fetchRequests()
    } catch (err: unknown) {
      const msg = err instanceof Error ? err.message : 'Failed to submit request'
      setFormError(msg)
    } finally {
      setSubmitting(false)
    }
  }

  const approveRequest = async (req: RequestItem) => {
    try {
      await putAPI(`/api/requests/${req.id}/approve`, {})
      showToast('Request approved — searching for release')
      fetchRequests()
    } catch {
      showToast('Failed to approve request')
    }
  }

  const rejectRequest = async () => {
    if (!rejectTarget) return
    try {
      await putAPI(`/api/requests/${rejectTarget.id}/reject`, {})
      showToast('Request rejected')
      fetchRequests()
    } catch {
      showToast('Failed to reject request')
    }
    setRejectTarget(null)
  }

  const withdrawRequest = async (req: RequestItem) => {
    try {
      await deleteAPI(`/api/requests/${req.id}`)
      showToast('Request withdrawn')
      fetchRequests()
    } catch {
      showToast('Failed to withdraw request')
    }
  }

  // Filter root folders by selected media type
  const filteredFolders = rootFolders.filter(f => f.media_type === newType)

  return (
    <div>
      {/* Header */}
      <div className="flex justify-between items-center mb-6">
        <h2 className="text-2xl font-semibold text-gray-100">Requests</h2>
        <button
          onClick={openNewModal}
          className="bg-indigo-400 hover:bg-indigo-500 px-4 py-2 rounded text-sm font-semibold text-gray-950 min-h-[36px]"
        >
          + New Request
        </button>
      </div>

      {/* Filter tabs */}
      <div className="flex gap-2 mb-6">
        {FILTER_TABS.map(tab => (
          <button
            key={tab.value}
            onClick={() => handleFilterChange(tab.value)}
            className={`px-4 py-2 rounded text-sm font-medium min-h-[36px] ${
              statusFilter === tab.value
                ? 'bg-indigo-400 text-gray-950'
                : 'bg-gray-800 text-gray-400 hover:bg-gray-700'
            }`}
          >
            {tab.label}
          </button>
        ))}
      </div>

      {/* Error */}
      {error && <ErrorBanner error={error} onRetry={fetchRequests} />}

      {/* Loading */}
      {loading ? (
        <Loading />
      ) : requests.length === 0 ? (
        /* Empty */
        <div className="text-gray-500 text-center py-20 text-sm">
          {statusFilter
            ? `No ${statusFilter} requests`
            : 'No requests yet. Click + New Request to get started.'}
        </div>
      ) : (
        <>
          {/* Request cards */}
          <div className="space-y-3">
            {requests.map(req => (
              <div
                key={req.id}
                className="bg-gray-900 border border-gray-800 rounded-lg p-4"
              >
                {/* Header row */}
                <div className="flex items-start justify-between mb-2">
                  <h3 className="text-xl font-semibold text-gray-100">
                    {req.title}
                    {req.year ? (
                      <span className="text-gray-400 font-normal"> ({req.year})</span>
                    ) : null}
                  </h3>
                  <StatusBadge status={req.status} />
                </div>

                {/* Meta row */}
                <div className="text-sm text-gray-400 mb-3">
                  <span>Requested by: {req.requested_by}</span>
                  <span className="mx-2">&bull;</span>
                  <span>{formatTimeAgo(req.created_at)}</span>
                  {req.quality_profile_name && (
                    <>
                      <span className="mx-2">&bull;</span>
                      <span>Quality: {req.quality_profile_name}</span>
                    </>
                  )}
                  {req.root_folder_path && (
                    <>
                      <span className="mx-2">&bull;</span>
                      <span>Root: {req.root_folder_path}</span>
                    </>
                  )}
                </div>

                {/* Actions row */}
                {req.status === 'pending' && (
                  <div className="flex items-center gap-3">
                    <button
                      onClick={() => approveRequest(req)}
                      className="bg-green-600 hover:bg-green-700 text-sm font-medium px-4 py-2 rounded min-h-[36px]"
                      aria-label="Approve request"
                    >
                      Approve
                    </button>
                    <button
                      onClick={() => setRejectTarget(req)}
                      className="bg-red-600 hover:bg-red-700 text-sm font-medium px-4 py-2 rounded min-h-[36px]"
                      aria-label="Reject request"
                    >
                      Reject
                    </button>
                  </div>
                )}

                {/* Withdraw link for own pending/approved requests */}
                {(req.status === 'pending' || req.status === 'approved') && (
                  <button
                    onClick={() => withdrawRequest(req)}
                    className="text-xs text-gray-500 hover:text-gray-300 mt-2"
                  >
                    Withdraw
                  </button>
                )}
              </div>
            ))}
          </div>

          {/* Pagination */}
          <Pagination
            total={total}
            page={page}
            pageSize={PAGE_SIZE}
            onPageChange={setPage}
          />
        </>
      )}

      {/* New Request Modal */}
      {showNewModal && (
        <div className="fixed inset-0 bg-black/60 flex items-center justify-center z-50" onClick={() => setShowNewModal(false)}>
          <div className="bg-gray-900 border border-gray-800 rounded-lg p-6 max-w-md w-full mx-4" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <h3 className="text-xl font-semibold text-gray-100">New Request</h3>
              <button onClick={() => setShowNewModal(false)} className="text-gray-500 hover:text-gray-300 text-lg">
                &times;
              </button>
            </div>

            {formError && (
              <div className="bg-red-900/30 border border-red-800 rounded-lg p-3 mb-4">
                <p className="text-red-400 text-sm">{formError}</p>
              </div>
            )}

            <div className="space-y-4">
              {/* Title */}
              <div>
                <label className="block text-sm text-gray-400 mb-1">Title</label>
                <input
                  type="text"
                  value={newTitle}
                  onChange={e => setNewTitle(e.target.value)}
                  placeholder="Movie or show title"
                  className="w-full bg-gray-800 border border-gray-700 rounded px-3 py-2 text-sm text-gray-100 focus:border-indigo-500 focus:outline-none"
                  autoFocus
                />
              </div>

              {/* Type */}
              <div>
                <label className="block text-sm text-gray-400 mb-1">Type</label>
                <select
                  value={newType}
                  onChange={e => {
                    setNewType(e.target.value)
                    setNewRootFolderId('')
                  }}
                  className="w-full bg-gray-800 border border-gray-700 rounded px-3 py-2 text-sm text-gray-100 focus:border-indigo-500 focus:outline-none"
                >
                  {MEDIA_TYPES.map(t => (
                    <option key={t} value={t}>{t.charAt(0).toUpperCase() + t.slice(1)}</option>
                  ))}
                </select>
              </div>

              {/* Year */}
              <div>
                <label className="block text-sm text-gray-400 mb-1">Year</label>
                <input
                  type="number"
                  value={newYear}
                  onChange={e => setNewYear(e.target.value)}
                  placeholder="2024"
                  min="1900"
                  max="2099"
                  className="w-full bg-gray-800 border border-gray-700 rounded px-3 py-2 text-sm text-gray-100 focus:border-indigo-500 focus:outline-none"
                />
              </div>

              {/* Quality Profile */}
              <div>
                <label className="block text-sm text-gray-400 mb-1">Quality Profile</label>
                <select
                  value={newQualityId}
                  onChange={e => setNewQualityId(e.target.value ? parseInt(e.target.value, 10) : '')}
                  className="w-full bg-gray-800 border border-gray-700 rounded px-3 py-2 text-sm text-gray-100 focus:border-indigo-500 focus:outline-none"
                >
                  <option value="">Any</option>
                  {qualityProfiles.map(p => (
                    <option key={p.id} value={p.id}>{p.name}</option>
                  ))}
                </select>
              </div>

              {/* Root Folder */}
              <div>
                <label className="block text-sm text-gray-400 mb-1">Root Folder</label>
                <select
                  value={newRootFolderId}
                  onChange={e => setNewRootFolderId(e.target.value ? parseInt(e.target.value, 10) : '')}
                  className="w-full bg-gray-800 border border-gray-700 rounded px-3 py-2 text-sm text-gray-100 focus:border-indigo-500 focus:outline-none"
                >
                  <option value="">Default</option>
                  {filteredFolders.map(f => (
                    <option key={f.id} value={f.id}>{f.path}</option>
                  ))}
                </select>
              </div>
            </div>

            {/* Modal actions */}
            <div className="flex gap-3 justify-end mt-6">
              <button
                onClick={() => setShowNewModal(false)}
                className="px-4 py-2 text-sm bg-gray-700 hover:bg-gray-600 rounded text-gray-200 min-h-[36px]"
              >
                Cancel
              </button>
              <button
                onClick={submitNewRequest}
                disabled={submitting}
                className="px-4 py-2 text-sm bg-indigo-500 hover:bg-indigo-400 rounded font-semibold text-white min-h-[36px] disabled:opacity-50"
              >
                {submitting ? 'Submitting...' : 'Submit'}
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Reject Confirmation Modal */}
      <ConfirmModal
        open={!!rejectTarget}
        title="Reject Request"
        message={`Reject "${rejectTarget?.title}"? The requester will be notified.`}
        onConfirm={rejectRequest}
        onCancel={() => setRejectTarget(null)}
        destructive
        confirmLabel="Reject"
      />
    </div>
  )
}
