import { useState, useEffect } from 'react'
import { useQuery } from '@tanstack/react-query'
import { cardsApi } from '@/api/cards'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table'
import { Badge } from '@/components/ui/badge'
import { Search, Check } from 'lucide-react'

interface PackCardsManagerProps {
  currentCardIds: string[]
  onCardsChange: (addIds: string[], removeIds: string[]) => void
  disabled?: boolean
}

export function PackCardsManager({
  currentCardIds,
  onCardsChange,
  disabled = false,
}: PackCardsManagerProps) {
  const [search, setSearch] = useState('')
  const [selectedCards, setSelectedCards] = useState<Set<string>>(new Set())
  const [removedCards, setRemovedCards] = useState<Set<string>>(new Set())

  // Load all cards with search
  const { data: cardsData, isLoading } = useQuery({
    queryKey: ['cards', 1, 100, search], // Limit to 100 (backend max)
    queryFn: () => cardsApi.getCards({ page: 1, limit: 100, search }),
    enabled: !disabled,
  })

  // Initialize selected cards from currentCardIds when it changes
  useEffect(() => {
    const initialSelected = new Set<string>(
      currentCardIds.filter((id) => !removedCards.has(id.toString()))
    )
    setSelectedCards(initialSelected)
    // Reset removed cards when currentCardIds changes (e.g., when opening dialog)
    setRemovedCards(new Set())
  }, [currentCardIds.join(',')]) // Use join to detect array changes

  // Calculate which cards to add/remove when selection changes
  useEffect(() => {
    const currentlySelected = Array.from(selectedCards)
    const removed = Array.from(removedCards)

    // Cards to add: selected but not in currentCardIds and not removed
    const toAdd = currentlySelected.filter(
      (id) => !currentCardIds.includes(id) && !removed.includes(id)
    )
    // Cards to remove: in removedCards
    const toRemove = removed.filter((id) => currentCardIds.includes(id))

    if (toAdd.length > 0 || toRemove.length > 0) {
      onCardsChange(toAdd, toRemove)
    } else if (selectedCards.size > 0 || removedCards.size > 0) {
      // Also notify if selection was cleared
      onCardsChange([], [])
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [selectedCards.size, removedCards.size, currentCardIds.join(',')])

  const handleToggleCard = (cardId: string | number) => {
    if (disabled) return

    const cardIdStr = String(cardId)
    const isCurrentlySelected = selectedCards.has(cardIdStr) && !removedCards.has(cardIdStr)
    const isInCurrentPack = currentCardIds.includes(cardIdStr)

    if (isCurrentlySelected) {
      // Deselect card
      const newSelected = new Set(selectedCards)
      newSelected.delete(cardIdStr)
      setSelectedCards(newSelected)
      
      // If it was in current pack, mark as removed
      if (isInCurrentPack) {
        setRemovedCards((prev) => new Set([...prev, cardIdStr]))
      }
    } else {
      // Select card
      const newSelected = new Set(selectedCards)
      newSelected.add(cardIdStr)
      setSelectedCards(newSelected)
      
      // If it was marked as removed, unmark it
      if (removedCards.has(cardIdStr)) {
        setRemovedCards((prev) => {
          const newRemoved = new Set(prev)
          newRemoved.delete(cardIdStr)
          return newRemoved
        })
      }
    }
  }

  const isCardSelected = (cardId: string | number) => {
    const cardIdStr = String(cardId)
    return selectedCards.has(cardIdStr) && !removedCards.has(cardIdStr)
  }

  const isCardInCurrentPack = (cardId: string | number) => {
    return currentCardIds.includes(String(cardId))
  }

  const allCards = cardsData?.items || []
  const filteredCards = search
    ? allCards.filter(
        (card) =>
          card.original?.toLowerCase().includes(search.toLowerCase()) ||
          card.translation?.toLowerCase().includes(search.toLowerCase()) ||
          card.mnemo?.toLowerCase().includes(search.toLowerCase())
      )
    : allCards

  return (
    <div className="space-y-4">
      <div className="space-y-2">
        <Label>Manage Cards in Pack</Label>
        <div className="flex items-center space-x-2">
          <Search className="h-4 w-4 text-muted-foreground" />
          <Input
            placeholder="Search cards by original, translation, or mnemo..."
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="max-w-sm"
            disabled={disabled}
          />
        </div>
        <p className="text-sm text-muted-foreground">
          Selected cards: {selectedCards.size - removedCards.size} / {allCards.length}
        </p>
      </div>

      {isLoading ? (
        <div className="text-center py-4">Loading cards...</div>
      ) : (
        <div className="border rounded-lg max-h-[400px] overflow-y-auto">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead className="w-12"></TableHead>
                <TableHead>ID</TableHead>
                <TableHead>Original</TableHead>
                <TableHead>Translation</TableHead>
                <TableHead>Mnemo</TableHead>
                <TableHead>Status</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {filteredCards.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={6} className="text-center text-muted-foreground">
                    No cards found
                  </TableCell>
                </TableRow>
              ) : (
                filteredCards.map((card) => {
                  const cardIdStr = card.id ? String(card.id) : `temp-${card.original}`
                  const selected = isCardSelected(cardIdStr)
                  const inCurrentPack = isCardInCurrentPack(cardIdStr)
                  const newlyRemoved = removedCards.has(cardIdStr)

                  return (
                    <TableRow
                      key={card.id || `temp-${card.original}`}
                      className={selected ? 'bg-muted/50' : ''}
                      onClick={() => handleToggleCard(cardIdStr)}
                    >
                      <TableCell>
                        {selected ? (
                          <Check className="h-4 w-4 text-primary" />
                        ) : (
                          <div className="h-4 w-4 border rounded" />
                        )}
                      </TableCell>
                      <TableCell className="font-mono text-sm">{card.id || '-'}</TableCell>
                      <TableCell className="font-medium">{card.original}</TableCell>
                      <TableCell>{card.translation}</TableCell>
                      <TableCell className="max-w-xs truncate">{card.mnemo}</TableCell>
                      <TableCell>
                        {newlyRemoved ? (
                          <Badge variant="destructive">Removed</Badge>
                        ) : selected && inCurrentPack ? (
                          <Badge variant="default">In Pack</Badge>
                        ) : selected ? (
                          <Badge variant="secondary">Selected</Badge>
                        ) : inCurrentPack ? (
                          <Badge variant="outline">In Pack</Badge>
                        ) : null}
                      </TableCell>
                    </TableRow>
                  )
                })
              )}
            </TableBody>
          </Table>
        </div>
      )}
    </div>
  )
}