import { AppLayout } from '@/components/AppLayout'
import { AppPagination } from '@/components/AppPagination'
import { CreateExtractionDialog } from '@/components/extractions/CreateExtractionDialog'
import { ExtractionsHeader } from '@/components/extractions/ExtractionsHeader'
import {
  ExtractionsEmpty,
  ExtractionsError,
  ExtractionsLoading,
} from '@/components/extractions/ExtractionsLoadingStates'
import { ExtractionsTable } from '@/components/extractions/ExtractionsTable'
import {
  type ExtractionInfo,
  type ExtractionSortField,
  type ExtractionSortOrder,
  type ExtractionStatus,
  extractionsService,
} from '@/lib/api/services/extractions'
import { EXTRACTION_EVENTS, extractionEvents } from '@/lib/events'
import { useCallback, useEffect, useState } from 'react'
import { toast } from 'sonner'

export function ExtractionsPage() {
  const [extractions, setExtractions] = useState<ExtractionInfo[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)

  // Search, sorting, and filtering state
  const [searchQuery, setSearchQuery] = useState('')
  const [sortBy, setSortBy] = useState<ExtractionSortField>('created_at')
  const [sortOrder, setSortOrder] = useState<ExtractionSortOrder>('desc')
  const [statusFilter, setStatusFilter] = useState<ExtractionStatus | 'all'>('all')

  // Pagination state
  const [currentPage, setCurrentPage] = useState(1)
  const [totalPages, setTotalPages] = useState(1)
  const [totalCount, setTotalCount] = useState(0)
  const [pageSize, setPageSize] = useState(10)

  // Create extraction dialog state
  const [showCreateDialog, setShowCreateDialog] = useState(false)
  const [createLoading, setCreateLoading] = useState(false)
  const [url, setUrl] = useState('')

  // Debounce search query
  const [debouncedSearchQuery, setDebouncedSearchQuery] = useState(searchQuery)

  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedSearchQuery(searchQuery)
    }, 300)

    return () => clearTimeout(handler)
  }, [searchQuery])

  const fetchExtractions = useCallback(async () => {
    try {
      setLoading(true)
      setError(null)
      const response = await extractionsService.getAllExtractions({
        search: debouncedSearchQuery.trim() || undefined,
        sort_by: sortBy,
        sort_order: sortOrder,
        status_filter: statusFilter !== 'all' ? statusFilter : undefined,
        page: currentPage,
        limit: pageSize,
      })
      setExtractions(response.extractions)
      setTotalPages(response.total_pages)
      setTotalCount(response.total)
    } catch (err) {
      const errorMessage =
        err instanceof Error ? err.message : 'Failed to fetch extractions'
      setError(errorMessage)
      toast.error(errorMessage)
    } finally {
      setLoading(false)
    }
  }, [debouncedSearchQuery, sortBy, sortOrder, statusFilter, currentPage, pageSize])

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

  // Reset to page 1 when filters change
  useEffect(() => {
    if (currentPage !== 1) {
      setCurrentPage(1)
    }
  }, [debouncedSearchQuery, sortBy, sortOrder, statusFilter, pageSize])

  // Listen for extraction events to refresh the list
  useEffect(() => {
    const handleExtractionStatusUpdate = () => {
      fetchExtractions()
    }

    const handleExtractionCompleted = () => {
      fetchExtractions()
    }

    const handleExtractionFailed = () => {
      fetchExtractions()
    }

    // Subscribe to extraction events
    extractionEvents.on(EXTRACTION_EVENTS.EXTRACTION_STATUS_UPDATED, handleExtractionStatusUpdate)
    extractionEvents.on(EXTRACTION_EVENTS.EXTRACTION_COMPLETED, handleExtractionCompleted)
    extractionEvents.on(EXTRACTION_EVENTS.EXTRACTION_FAILED, handleExtractionFailed)

    return () => {
      // Cleanup event listeners
      extractionEvents.off(EXTRACTION_EVENTS.EXTRACTION_STATUS_UPDATED, handleExtractionStatusUpdate)
      extractionEvents.off(EXTRACTION_EVENTS.EXTRACTION_COMPLETED, handleExtractionCompleted)
      extractionEvents.off(EXTRACTION_EVENTS.EXTRACTION_FAILED, handleExtractionFailed)
    }
  }, [fetchExtractions])

  const handlePageChange = (page: number) => {
    setCurrentPage(page)
  }

  const handlePageSizeChange = (size: number) => {
    setPageSize(size)
    setCurrentPage(1) // Reset to first page when changing page size
  }


  const handleCreateExtraction = async () => {
    if (!url.trim()) {
      toast.error('Please enter a URL')
      return
    }

    try {
      setCreateLoading(true)
      const response = await extractionsService.createExtraction(url.trim())
      toast.success(response.message)

      // Reset form and close dialog
      setUrl('')
      setShowCreateDialog(false)

      // Emit event for new extraction created
      extractionEvents.emit(EXTRACTION_EVENTS.EXTRACTION_CREATED, response.extraction)

      // Refresh the extractions list
      fetchExtractions()
    } catch (err) {
      const errorMessage =
        err instanceof Error ? err.message : 'Failed to create extraction'
      toast.error(errorMessage)
    } finally {
      setCreateLoading(false)
    }
  }

  const handleCancelCreate = () => {
    setUrl('')
    setShowCreateDialog(false)
  }

  const handleExtractionDeleted = (extractionId: number) => {
    // Remove the deleted extraction from the current list
    setExtractions(prev => prev.filter(extraction => extraction.id !== extractionId))
    
    // Update total count
    setTotalCount(prev => prev - 1)
    
    // If current page is now empty and not the first page, go to previous page
    const remainingOnCurrentPage = extractions.length - 1
    if (remainingOnCurrentPage === 0 && currentPage > 1) {
      setCurrentPage(currentPage - 1)
    }
    
    // Refresh the full list to ensure accuracy
    fetchExtractions()
  }

  const renderContent = () => {
    if (loading) {
      return <ExtractionsLoading />
    }

    if (error) {
      return <ExtractionsError error={error} onRetry={fetchExtractions} />
    }

    if (extractions.length === 0) {
      return <ExtractionsEmpty searchQuery={searchQuery} statusFilter={statusFilter} />
    }

    return (
      <div className="space-y-4">
        <ExtractionsTable 
          extractions={extractions} 
          onExtractionDeleted={handleExtractionDeleted}
        />
        <AppPagination
          currentPage={currentPage}
          totalPages={totalPages}
          totalCount={totalCount}
          pageSize={pageSize}
          onPageChange={handlePageChange}
          onPageSizeChange={handlePageSizeChange}
          itemName="extractions"
        />
      </div>
    )
  }

  return (
    <AppLayout
      breadcrumb={{
        items: [{ label: 'Dashboard', href: '/' }, { label: 'Extractions' }],
      }}
    >
      <div className="flex-1 rounded-xl bg-muted/50 p-4">
        <ExtractionsHeader
          searchQuery={searchQuery}
          onSearchChange={setSearchQuery}
          sortBy={sortBy}
          onSortByChange={setSortBy}
          sortOrder={sortOrder}
          onSortOrderChange={setSortOrder}
          statusFilter={statusFilter}
          onStatusFilterChange={setStatusFilter}
          onRefresh={fetchExtractions}
          onCreateClick={() => setShowCreateDialog(true)}
          loading={loading}
          error={error}
          extractionCount={totalCount}
        />

        <CreateExtractionDialog
          open={showCreateDialog}
          onOpenChange={setShowCreateDialog}
          loading={createLoading}
          url={url}
          onUrlChange={setUrl}
          onSubmit={handleCreateExtraction}
          onCancel={handleCancelCreate}
        />

        {renderContent()}
      </div>
    </AppLayout>
  )
}
