"use client"

import { useEffect, useRef, useState, useMemo, useCallback } from "react"
import type { AssetResponse } from "@/lib/types"
import type { DateGroup } from "@/lib/timeline"
import { PhotoCard } from "./photo-card"
import { ImageViewer } from "./image-viewer"
import { AddToAlbumDialog } from "./add-to-album-dialog"
import { Button } from "@/components/ui/button"
import { Spinner } from "@/components/ui/spinner"
import { ImagePlusIcon, XIcon, CheckSquareIcon, Trash2Icon } from "lucide-react"

interface PhotoGridProps {
  groups: DateGroup[]
  isLoading: boolean
  hasMore: boolean
  onLoadMore: () => void
  onRemoveAsset?: (assetId: string) => void
  onDeleteAssets?: (assetIds: string[]) => void
}

export function PhotoGrid({
  groups,
  isLoading,
  hasMore,
  onLoadMore,
  onRemoveAsset,
  onDeleteAssets,
}: PhotoGridProps) {
  const sentinelRef = useRef<HTMLDivElement>(null)
  const [selectedIndex, setSelectedIndex] = useState<number | null>(null)
  const [selecting, setSelecting] = useState(false)
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set())
  const [albumDialogOpen, setAlbumDialogOpen] = useState(false)

  const allAssets = useMemo(
    () => groups.flatMap((g) => g.assets),
    [groups],
  )

  const toggleSelect = useCallback((id: string, selected: boolean) => {
    setSelectedIds((prev) => {
      const next = new Set(prev)
      if (selected) next.add(id)
      else next.delete(id)
      return next
    })
  }, [])

  const exitSelection = useCallback(() => {
    setSelecting(false)
    setSelectedIds(new Set())
  }, [])

  useEffect(() => {
    const el = sentinelRef.current
    if (!el) return
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) onLoadMore()
      },
      { rootMargin: "200px" },
    )
    observer.observe(el)
    return () => observer.disconnect()
  }, [onLoadMore])

  if (allAssets.length === 0 && !isLoading) {
    return (
      <div className="flex flex-1 items-center justify-center text-muted-foreground">
        No photos yet. Upload some to get started.
      </div>
    )
  }

  let flatIndex = 0

  return (
    <div className="flex flex-1 flex-col">
      {/* Selection toolbar */}
      {selecting && (
        <div className="sticky top-0 z-20 flex items-center gap-2 rounded-md border bg-background px-3 py-2 shadow-sm">
          <span className="text-sm font-medium">
            {selectedIds.size} selected
          </span>
          <div className="flex-1" />
          <Button
            size="sm"
            variant="outline"
            disabled={selectedIds.size === 0}
            onClick={() => setAlbumDialogOpen(true)}
          >
            <ImagePlusIcon className="mr-1.5 h-3.5 w-3.5" />
            Add to Album
          </Button>
          {onRemoveAsset && selectedIds.size > 0 && (
            <Button
              size="sm"
              variant="secondary"
              onClick={() => {
                selectedIds.forEach((id) => onRemoveAsset(id))
                exitSelection()
              }}
            >
              Remove from Album
            </Button>
          )}
          {onDeleteAssets && selectedIds.size > 0 && (
            <Button
              size="sm"
              variant="destructive"
              onClick={() => {
                onDeleteAssets(Array.from(selectedIds))
                exitSelection()
              }}
            >
              <Trash2Icon className="mr-1.5 h-3.5 w-3.5" />
              Delete
            </Button>
          )}
          <Button size="sm" variant="ghost" onClick={exitSelection}>
            <XIcon className="h-3.5 w-3.5" />
          </Button>
        </div>
      )}

      {!selecting && allAssets.length > 0 && (
        <div className="flex justify-end">
          <Button
            size="sm"
            variant="ghost"
            className="text-xs text-muted-foreground"
            onClick={() => setSelecting(true)}
          >
            <CheckSquareIcon className="mr-1 h-3.5 w-3.5" />
            Select
          </Button>
        </div>
      )}

      <div className="flex flex-col gap-4">
        {groups.map((group) => {
          const startIndex = flatIndex
          flatIndex += group.assets.length
          return (
            <div key={group.date}>
              <h2
                id={`date-${group.date}`}
                data-date={group.date}
                className="sticky top-0 z-10 bg-background/80 py-1.5 text-sm font-medium backdrop-blur"
              >
                {group.label}
              </h2>
              <div className="grid grid-cols-2 gap-1 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6">
                {group.assets.map((asset, j) => (
                  <PhotoCard
                    key={asset.id}
                    asset={asset}
                    selectable={selecting}
                    selected={selectedIds.has(asset.id)}
                    onSelect={(sel) => toggleSelect(asset.id, sel)}
                    onClick={() => setSelectedIndex(startIndex + j)}
                  />
                ))}
              </div>
            </div>
          )
        })}
        {hasMore && <div ref={sentinelRef} className="h-1" />}
        {isLoading && (
          <div className="flex justify-center py-4">
            <Spinner />
          </div>
        )}
      </div>

      {selectedIndex !== null && (
        <ImageViewer
          assets={allAssets}
          initialIndex={selectedIndex}
          onClose={() => setSelectedIndex(null)}
        />
      )}

      <AddToAlbumDialog
        assetIds={Array.from(selectedIds)}
        open={albumDialogOpen}
        onOpenChange={(open) => {
          setAlbumDialogOpen(open)
          if (!open) exitSelection()
        }}
      />
    </div>
  )
}
