import { useRef, useEffect, useMemo, useState } from 'react'
import { useVirtualizer } from '@tanstack/react-virtual'
import { usePhotoStore } from '../../store/photoStore'
import { PhotoThumbnail } from './PhotoThumbnail'
import { useQuery } from '@tanstack/react-query'
import axios from 'axios'
import type { Photo } from '../../types/photo'

export function Timeline() {
  const parentRef = useRef<HTMLDivElement>(null)
  const [containerWidth, setContainerWidth] = useState(0)
  
  const {
    selectedPhotos,
    lastSelectedIndex,
    rangeStartIndex,
    selectPhoto,
    togglePhotoSelection,
    clearSelection,
    openLoupe,
  } = usePhotoStore()
  
  // Helper function for range selection
  const selectRange = (endIndex: number) => {
    const startIndex = rangeStartIndex ?? lastSelectedIndex ?? 0
    const minIndex = Math.min(startIndex, endIndex)
    const maxIndex = Math.max(startIndex, endIndex)
    
    // Select all photos in the range
    for (let i = minIndex; i <= maxIndex; i++) {
      if (i < photos.length && !selectedPhotos.includes(photos[i].id)) {
        togglePhotoSelection(photos[i].id, i)
      }
    }
  }

  // Thumbnail size configuration
  const thumbnailSize = 200 // Base size for thumbnails
  const gap = 4
  const padding = 16

  // Calculate number of columns based on container width
  const columns = useMemo(() => {
    if (containerWidth === 0) return 4
    return Math.floor((containerWidth - padding * 2) / (thumbnailSize + gap))
  }, [containerWidth, thumbnailSize, gap, padding])

  // Fetch photos from backend
  const { data: photos = [], isLoading } = useQuery({
    queryKey: ['photos'],
    queryFn: async () => {
      const response = await axios.get<{photos: Photo[], total: number}>('http://localhost:8001/api/v1/photos', {
        params: {
          limit: 1000,
          offset: 0,
        },
      })
      return response.data.photos || []
    },
    staleTime: 30000,
  })

  // Group photos into rows for grid layout
  const rows = useMemo(() => {
    const result: Photo[][] = []
    for (let i = 0; i < photos.length; i += columns) {
      result.push(photos.slice(i, i + columns))
    }
    return result
  }, [photos, columns])

  // Virtual scrolling setup
  const virtualizer = useVirtualizer({
    count: rows.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => thumbnailSize + gap,
    overscan: 5,
  })

  // Measure container width on mount and resize
  useEffect(() => {
    const measureWidth = () => {
      if (parentRef.current) {
        setContainerWidth(parentRef.current.clientWidth)
      }
    }

    measureWidth()
    window.addEventListener('resize', measureWidth)
    return () => window.removeEventListener('resize', measureWidth)
  }, [])

  // Handle keyboard shortcuts for photo navigation
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (photos.length === 0) return

      const currentIndex = lastSelectedIndex ?? -1

      switch (e.key) {
        case 'ArrowUp':
          e.preventDefault()
          if (currentIndex > columns - 1) {
            const newIndex = currentIndex - columns
            if (e.shiftKey) {
              selectRange(newIndex)
            } else {
              selectPhoto(photos[newIndex].id, newIndex)
            }
          }
          break

        case 'ArrowDown':
          e.preventDefault()
          if (currentIndex < photos.length - columns) {
            const newIndex = Math.min(currentIndex + columns, photos.length - 1)
            if (e.shiftKey) {
              selectRange(newIndex)
            } else {
              selectPhoto(photos[newIndex].id, newIndex)
            }
          }
          break

        case 'ArrowLeft':
          e.preventDefault()
          if (currentIndex > 0) {
            const newIndex = currentIndex - 1
            if (e.shiftKey) {
              selectRange(newIndex)
            } else {
              selectPhoto(photos[newIndex].id, newIndex)
            }
          }
          break

        case 'ArrowRight':
          e.preventDefault()
          if (currentIndex < photos.length - 1) {
            const newIndex = currentIndex + 1
            if (e.shiftKey) {
              selectRange(newIndex)
            } else {
              selectPhoto(photos[newIndex].id, newIndex)
            }
          }
          break

        case 'a':
          if (e.ctrlKey || e.metaKey) {
            e.preventDefault()
            // Select all
            photos.forEach((photo, index) => {
              if (!selectedPhotos.includes(photo.id)) {
                togglePhotoSelection(photo.id, index)
              }
            })
          }
          break

        case 'Escape':
          e.preventDefault()
          clearSelection()
          break
      }
    }

    window.addEventListener('keydown', handleKeyDown)
    return () => window.removeEventListener('keydown', handleKeyDown)
  }, [photos, selectedPhotos, lastSelectedIndex, columns, selectPhoto, togglePhotoSelection, selectRange, clearSelection])

  if (isLoading) {
    return (
      <div className="flex items-center justify-center h-full">
        <div className="text-text-muted">Loading photos...</div>
      </div>
    )
  }

  if (photos.length === 0) {
    return (
      <div className="flex items-center justify-center h-full">
        <div className="text-text-muted">No photos found. Add a source folder to get started.</div>
      </div>
    )
  }

  return (
    <div
      ref={parentRef}
      className="h-full overflow-auto bg-bg"
      style={{ padding: `${padding}px` }}
    >
      <div
        style={{
          height: `${virtualizer.getTotalSize()}px`,
          width: '100%',
          position: 'relative',
        }}
      >
        {virtualizer.getVirtualItems().map((virtualRow) => {
          const row = rows[virtualRow.index]
          return (
            <div
              key={virtualRow.key}
              style={{
                position: 'absolute',
                top: 0,
                left: 0,
                width: '100%',
                height: `${virtualRow.size}px`,
                transform: `translateY(${virtualRow.start}px)`,
              }}
            >
              <div
                className="flex"
                style={{ gap: `${gap}px` }}
              >
                {row.map((photo, colIndex) => {
                  const globalIndex = virtualRow.index * columns + colIndex
                  return (
                    <PhotoThumbnail
                      key={photo.id}
                      photo={photo}
                      size={thumbnailSize}
                      isSelected={selectedPhotos.includes(photo.id)}
                      onClick={(e) => {
                        if (e.shiftKey && lastSelectedIndex !== null) {
                          selectRange(globalIndex)
                        } else if (e.ctrlKey || e.metaKey) {
                          togglePhotoSelection(photo.id, globalIndex)
                        } else {
                          selectPhoto(photo.id, globalIndex)
                        }
                      }}
                      onDoubleClick={() => openLoupe(photo.id)}
                    />
                  )
                })}
              </div>
            </div>
          )
        })}
      </div>
    </div>
  )
}