import { useState, useCallback, useMemo, useTransition, useDeferredValue } from 'react'

/**
 * Common state and handlers for media filtering across pages.
 * Reduces duplication of filter state management in Media, Review, RecycleBin, etc.
 *
 * Features:
 * - useTransition for non-blocking filter updates
 * - useDeferredValue for smooth search input
 * - Memoized filter state object
 */

export interface FilterState {
  platformFilter: string
  sourceFilter: string
  typeFilter: 'all' | 'image' | 'video'
  searchQuery: string
  dateFrom: string
  dateTo: string
  sizeMin: string
  sizeMax: string
  sortBy: string
  sortOrder: 'asc' | 'desc'
}

export interface UseMediaFilteringOptions {
  initialSortBy?: string
  initialSortOrder?: 'asc' | 'desc'
  initialTypeFilter?: 'all' | 'image' | 'video'
}

export interface UseMediaFilteringResult extends FilterState {
  // Filter state object (for query keys)
  filters: FilterState

  // Deferred filters for expensive operations (use with React Query)
  deferredFilters: FilterState

  // Individual setters for convenience
  setPlatformFilter: (value: string) => void
  setSourceFilter: (value: string) => void
  setTypeFilter: (value: 'all' | 'image' | 'video') => void
  setSearchQuery: (value: string) => void
  setDateFrom: (value: string) => void
  setDateTo: (value: string) => void
  setSizeMin: (value: string) => void
  setSizeMax: (value: string) => void
  setSortBy: (value: string) => void
  setSortOrder: (value: 'asc' | 'desc') => void

  // Generic filter change handler (for FilterBar component)
  handleFilterChange: <K extends keyof FilterState>(key: K, value: FilterState[K]) => void

  // Utility functions
  resetFilters: () => void
  hasActiveFilters: boolean

  // Transition state for loading indicators
  isPending: boolean

  // Advanced filter visibility
  showAdvanced: boolean
  setShowAdvanced: (value: boolean) => void
}

export function useMediaFiltering(options: UseMediaFilteringOptions = {}): UseMediaFilteringResult {
  const {
    initialSortBy = 'post_date',
    initialSortOrder = 'desc',
    initialTypeFilter = 'all'
  } = options

  // useTransition for non-blocking filter updates
  const [isPending, startTransition] = useTransition()

  // Core filter state
  const [platformFilter, setPlatformFilterRaw] = useState<string>('')
  const [sourceFilter, setSourceFilterRaw] = useState<string>('')
  const [typeFilter, setTypeFilterRaw] = useState<'all' | 'image' | 'video'>(initialTypeFilter)
  const [searchQuery, setSearchQueryRaw] = useState<string>('')

  // Advanced filter state
  const [dateFrom, setDateFromRaw] = useState<string>('')
  const [dateTo, setDateToRaw] = useState<string>('')
  const [sizeMin, setSizeMinRaw] = useState<string>('')
  const [sizeMax, setSizeMaxRaw] = useState<string>('')
  const [sortBy, setSortByRaw] = useState<string>(initialSortBy)
  const [sortOrder, setSortOrderRaw] = useState<'asc' | 'desc'>(initialSortOrder)

  // UI state
  const [showAdvanced, setShowAdvanced] = useState(false)

  // Wrap setters with startTransition for non-blocking updates
  const setPlatformFilter = useCallback((value: string) => {
    startTransition(() => setPlatformFilterRaw(value))
  }, [])

  const setSourceFilter = useCallback((value: string) => {
    startTransition(() => setSourceFilterRaw(value))
  }, [])

  const setTypeFilter = useCallback((value: 'all' | 'image' | 'video') => {
    startTransition(() => setTypeFilterRaw(value))
  }, [])

  const setSearchQuery = useCallback((value: string) => {
    // Search is immediate for responsive typing, defer the query
    setSearchQueryRaw(value)
  }, [])

  const setDateFrom = useCallback((value: string) => {
    startTransition(() => setDateFromRaw(value))
  }, [])

  const setDateTo = useCallback((value: string) => {
    startTransition(() => setDateToRaw(value))
  }, [])

  const setSizeMin = useCallback((value: string) => {
    startTransition(() => setSizeMinRaw(value))
  }, [])

  const setSizeMax = useCallback((value: string) => {
    startTransition(() => setSizeMaxRaw(value))
  }, [])

  const setSortBy = useCallback((value: string) => {
    startTransition(() => setSortByRaw(value))
  }, [])

  const setSortOrder = useCallback((value: 'asc' | 'desc') => {
    startTransition(() => setSortOrderRaw(value))
  }, [])

  // Combine all filters into single object for query keys
  const filters = useMemo<FilterState>(() => ({
    platformFilter,
    sourceFilter,
    typeFilter,
    searchQuery,
    dateFrom,
    dateTo,
    sizeMin,
    sizeMax,
    sortBy,
    sortOrder
  }), [
    platformFilter, sourceFilter, typeFilter, searchQuery,
    dateFrom, dateTo, sizeMin, sizeMax, sortBy, sortOrder
  ])

  // Deferred filters for expensive operations (smooth UI during typing)
  const deferredFilters = useDeferredValue(filters)

  // Generic filter change handler (for FilterBar component)
  const handleFilterChange = useCallback(<K extends keyof FilterState>(key: K, value: FilterState[K]) => {
    const setters: Record<keyof FilterState, (v: FilterState[K]) => void> = {
      platformFilter: setPlatformFilter as (v: FilterState[K]) => void,
      sourceFilter: setSourceFilter as (v: FilterState[K]) => void,
      typeFilter: setTypeFilter as (v: FilterState[K]) => void,
      searchQuery: setSearchQuery as (v: FilterState[K]) => void,
      dateFrom: setDateFrom as (v: FilterState[K]) => void,
      dateTo: setDateTo as (v: FilterState[K]) => void,
      sizeMin: setSizeMin as (v: FilterState[K]) => void,
      sizeMax: setSizeMax as (v: FilterState[K]) => void,
      sortBy: setSortBy as (v: FilterState[K]) => void,
      sortOrder: setSortOrder as (v: FilterState[K]) => void,
    }
    setters[key](value)
  }, [setPlatformFilter, setSourceFilter, setTypeFilter, setSearchQuery, setDateFrom, setDateTo, setSizeMin, setSizeMax, setSortBy, setSortOrder])

  // Check if any filters are active
  const hasActiveFilters = useMemo(() => {
    return !!(
      searchQuery ||
      typeFilter !== 'all' ||
      platformFilter ||
      sourceFilter ||
      dateFrom ||
      dateTo ||
      sizeMin ||
      sizeMax
    )
  }, [searchQuery, typeFilter, platformFilter, sourceFilter, dateFrom, dateTo, sizeMin, sizeMax])

  // Reset all filters to default
  const resetFilters = useCallback(() => {
    startTransition(() => {
      setPlatformFilterRaw('')
      setSourceFilterRaw('')
      setTypeFilterRaw('all')
      setSearchQueryRaw('')
      setDateFromRaw('')
      setDateToRaw('')
      setSizeMinRaw('')
      setSizeMaxRaw('')
      setSortByRaw(initialSortBy)
      setSortOrderRaw(initialSortOrder)
      setShowAdvanced(false)
    })
  }, [initialSortBy, initialSortOrder])

  return {
    filters,
    deferredFilters,
    platformFilter, setPlatformFilter,
    sourceFilter, setSourceFilter,
    typeFilter, setTypeFilter,
    searchQuery, setSearchQuery,
    dateFrom, setDateFrom,
    dateTo, setDateTo,
    sizeMin, setSizeMin,
    sizeMax, setSizeMax,
    sortBy, setSortBy,
    sortOrder, setSortOrder,
    handleFilterChange,
    resetFilters,
    hasActiveFilters,
    isPending,
    showAdvanced,
    setShowAdvanced
  }
}

export default useMediaFiltering
