import { useEffect, useRef, useState } from 'react'
import { FolderOpen, Loader2, Check, AlertCircle, X } from 'lucide-react'
import { useQuery, useQueryClient } from '@tanstack/react-query'
import { library } from '../services/api'
import clsx from 'clsx'

interface ScanStatus {
  is_scanning: boolean
  current_folder?: string
  processed_files: number
  total_files: number
  errors: string[]
}

export function ScanProgress() {
  const [isVisible, setIsVisible] = useState(false)
  const [isMinimized, setIsMinimized] = useState(false)
  const queryClient = useQueryClient()
  const wasScanningRef = useRef(false)

  // Poll scan status every 2 seconds when scanning
  const { data: scanStatus } = useQuery<ScanStatus>({
    queryKey: ['scan-status'],
    queryFn: async () => {
      const response = await library.scanStatus()
      return response
    },
    refetchInterval: (query) => {
      // Poll every 2 seconds if scanning, otherwise every 10 seconds
      return query.state.data?.is_scanning ? 2000 : 10000
    },
    enabled: true,
  })

  useEffect(() => {
    const isScanning = scanStatus?.is_scanning ?? false

    if (isScanning) {
      setIsVisible(true)
      setIsMinimized(false)
      wasScanningRef.current = true
    } else if (wasScanningRef.current) {
      // Just transitioned from scanning → done. THIS is the right moment
      // to invalidate caches that might have new data: the photos query
      // (new files indexed), the folder tree (new folders walked), the
      // heap counts (in case a heap photo got reattached).
      wasScanningRef.current = false
      queryClient.invalidateQueries({ queryKey: ['photos'] })
      queryClient.invalidateQueries({ queryKey: ['folders'] })
      queryClient.invalidateQueries({ queryKey: ['folders', 'tree'] })
      queryClient.invalidateQueries({ queryKey: ['heaps'] })
      queryClient.invalidateQueries({ queryKey: ['tags'] })
      queryClient.invalidateQueries({ queryKey: ['library', 'stats'] })

      if (isVisible && (scanStatus?.processed_files ?? 0) > 0) {
        // Keep showing for 3 seconds after scan completes
        setTimeout(() => {
          if (!scanStatus?.is_scanning) {
            setIsVisible(false)
          }
        }, 3000)
      }
    }
  }, [scanStatus?.is_scanning, scanStatus?.processed_files, isVisible, queryClient])

  if (!isVisible || !scanStatus) return null

  const progress = scanStatus.total_files > 0
    ? (scanStatus.processed_files / scanStatus.total_files) * 100
    : 0

  const isComplete = !scanStatus.is_scanning && scanStatus.processed_files > 0
  const hasErrors = scanStatus.errors && scanStatus.errors.length > 0

  return (
    <div
      className={clsx(
        'fixed bottom-4 right-4 z-40 overflow-hidden rounded-lg border border-border bg-surface shadow-xl transition-all duration-300',
        isMinimized ? 'w-12' : 'w-80'
      )}
    >
      {/* Header */}
      <div
        className="flex cursor-pointer items-center justify-between bg-surface-2 px-3 py-2"
        onClick={() => setIsMinimized(!isMinimized)}
      >
        <div className="flex items-center gap-2">
          {scanStatus.is_scanning ? (
            <Loader2 className="h-4 w-4 animate-spin text-primary" />
          ) : isComplete && !hasErrors ? (
            <Check className="h-4 w-4 text-pick" />
          ) : hasErrors ? (
            <AlertCircle className="h-4 w-4 text-reject" />
          ) : (
            <FolderOpen className="h-4 w-4 text-text-muted" />
          )}
          {!isMinimized && (
            <span className="text-sm font-medium text-text">
              {scanStatus.is_scanning
                ? 'Scanning Folders'
                : isComplete
                ? 'Scan Complete'
                : 'Scan Status'}
            </span>
          )}
        </div>
        {!isMinimized && (
          <button
            onClick={(e) => {
              e.stopPropagation()
              setIsVisible(false)
            }}
            className="rounded p-0.5 text-text-muted hover:bg-surface-offset hover:text-text"
          >
            <X className="h-3 w-3" />
          </button>
        )}
      </div>

      {/* Content */}
      {!isMinimized && (
        <div className="p-3">
          {/* Current folder */}
          {scanStatus.current_folder && (
            <div className="mb-2 text-xs text-text-muted">
              <span className="font-mono">{scanStatus.current_folder}</span>
            </div>
          )}

          {/* Progress bar */}
          <div className="mb-2">
            <div className="h-1.5 overflow-hidden rounded-full bg-surface-offset">
              <div
                className={clsx(
                  'h-full transition-all duration-300',
                  scanStatus.is_scanning
                    ? 'bg-primary'
                    : hasErrors
                    ? 'bg-reject'
                    : 'bg-pick'
                )}
                style={{ width: `${progress}%` }}
              />
            </div>
          </div>

          {/* Stats */}
          <div className="flex items-center justify-between text-xs">
            <span className="text-text-muted">
              {scanStatus.processed_files} / {scanStatus.total_files || '?'} files
            </span>
            <span className={clsx(
              'font-medium',
              scanStatus.is_scanning ? 'text-primary' : hasErrors ? 'text-reject' : 'text-pick'
            )}>
              {scanStatus.is_scanning
                ? `${Math.round(progress)}%`
                : isComplete
                ? 'Done'
                : 'Idle'}
            </span>
          </div>

          {/* Errors */}
          {hasErrors && (
            <div className="mt-2 max-h-20 overflow-y-auto rounded bg-reject/10 p-2">
              <div className="text-xs text-reject">
                {scanStatus.errors.slice(0, 3).map((error, i) => (
                  <div key={i} className="truncate">
                    • {error}
                  </div>
                ))}
                {scanStatus.errors.length > 3 && (
                  <div className="mt-1 text-text-muted">
                    +{scanStatus.errors.length - 3} more errors
                  </div>
                )}
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  )
}