'use client'

import { useEffect, useState, useCallback, useRef } from 'react'
import type { Game, GameSeries } from '@/types'
import GameDetailModal from './GameDetailModal'
import FilterPanel from '@/components/FilterPanel'

interface Props {
  libraryId: string
}

export default function GamesView({ libraryId }: Props) {
  const [items, setItems] = useState<(Game | GameSeries)[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [selectedSeries, setSelectedSeries] = useState<GameSeries | null>(null)
  const [selected, setSelected] = useState<Game | null>(null)
  const selectedRef = useRef(selected)
  selectedRef.current = selected
  const [search, setSearch] = useState('')
  const [selectedTagIds, setSelectedTagIds] = useState<Set<string>>(new Set())
  const [assignments, setAssignments] = useState<Record<string, string[]>>({})
  const [filterRefreshKey, setFilterRefreshKey] = useState(0)
  const [showFilters, setShowFilters] = useState(true)

  const toggleTag = (tagId: string) =>
    setSelectedTagIds((prev) => {
      const next = new Set(prev)
      next.has(tagId) ? next.delete(tagId) : next.add(tagId)
      return next
    })

  const fetchGames = useCallback((syncSelected = false) => {
    fetch(`/api/games?libraryId=${encodeURIComponent(libraryId)}`)
      .then((r) => r.json())
      .then((data: (Game | GameSeries)[]) => {
        setItems(data)
        setLoading(false)
        if (syncSelected && selectedRef.current) {
          const id = selectedRef.current.id
          // Search top-level games and inside series
          let updated: Game | undefined
          for (const item of data) {
            if ('games' in item) {
              updated = item.games.find((g) => g.id === id)
            } else if (item.id === id) {
              updated = item
            }
            if (updated) break
          }
          if (updated) setSelected(updated)
        }
      })
      .catch(() => {
        setError('Failed to load games')
        setLoading(false)
      })
  }, [libraryId])

  useEffect(() => { fetchGames() }, [fetchGames])

  const fetchAssignments = useCallback(() => {
    fetch(`/api/tags/library-assignments?libraryId=${encodeURIComponent(libraryId)}`)
      .then((r) => r.json())
      .then(setAssignments)
      .catch(() => {})
  }, [libraryId])

  useEffect(() => { fetchAssignments() }, [fetchAssignments])

  // Items shown in the current view level
  const visibleItems: (Game | GameSeries)[] = selectedSeries
    ? selectedSeries.games
    : items

  const filtered = visibleItems.filter((item) => {
    if ('games' in item) {
      const searchMatch = !search ||
        item.title.toLowerCase().includes(search.toLowerCase()) ||
        item.games.some((g) => g.title.toLowerCase().includes(search.toLowerCase()))
      if (!searchMatch) return false
      if (selectedTagIds.size > 0) {
        return item.games.some((g) => {
          const gameTags = assignments[`${libraryId}:${g.id}`] ?? []
          return [...selectedTagIds].every((id) => gameTags.includes(id))
        })
      }
      return true
    }
    if (search && !item.title.toLowerCase().includes(search.toLowerCase())) return false
    if (selectedTagIds.size > 0) {
      const gameTags = assignments[`${libraryId}:${item.id}`] ?? []
      if (![...selectedTagIds].every((id) => gameTags.includes(id))) return false
    }
    return true
  })

  const filtersActive = search !== '' || selectedTagIds.size > 0

  return (
    <>
      <div className="flex items-center gap-2 mb-4">
        <button
          onClick={() => setShowFilters((v) => !v)}
          className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-medium transition-colors"
          style={{
            backgroundColor: (showFilters || filtersActive) ? 'var(--accent)' : 'var(--surface)',
            color: (showFilters || filtersActive) ? '#fff' : 'var(--text-secondary)',
            border: '1px solid var(--border)',
          }}
          aria-label={showFilters ? 'Hide filters' : 'Show filters'}
        >
          Filters{filtersActive ? ' ●' : ''}
        </button>
      </div>
      <div className="flex flex-col md:flex-row gap-6 md:items-start">
        {showFilters && (
          <div className="w-full md:w-52 md:flex-shrink-0">
            <FilterPanel
              libraryId={libraryId}
              assignments={assignments}
              search={search}
              onSearchChange={setSearch}
              selectedTagIds={selectedTagIds}
              onTagToggle={toggleTag}
              refreshKey={filterRefreshKey}
            />
          </div>
        )}
        <div className="flex-1 min-w-0">
        {/* Breadcrumb when inside a series */}
        {selectedSeries && (
          <div className="flex items-center gap-2 mb-4 text-sm">
            <button
              onClick={() => { setSelectedSeries(null); setSearch('') }}
              className="transition-colors"
              style={{ color: 'var(--accent)' }}
            >
              All Games
            </button>
            <span style={{ color: 'var(--text-secondary)' }}>/</span>
            <span className="font-medium" style={{ color: 'var(--text-primary)' }}>
              {selectedSeries.title}
            </span>
          </div>
        )}

        {loading ? (
          <LoadingGrid />
        ) : error ? (
          <div className="rounded-lg border p-8 text-center" style={{ borderColor: 'var(--border)', color: 'var(--text-secondary)' }}>
            {error}
          </div>
        ) : items.length === 0 ? (
          <div className="rounded-lg border p-12 text-center" style={{ borderColor: 'var(--border)', color: 'var(--text-secondary)' }}>
            <p className="text-lg mb-1">No games found</p>
            <p className="text-sm">Each game should be a folder containing a .zip file.</p>
          </div>
        ) : (
          <div className="grid gap-4 grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6">
            {filtered.map((item) =>
              'games' in item ? (
                <SeriesCard
                  key={item.id}
                  series={item}
                  onClick={() => { setSelectedSeries(item); setSearch('') }}
                />
              ) : (
                <GameCard
                  key={item.id}
                  game={item}
                  onClick={() => setSelected(item)}
                />
              )
            )}
          </div>
        )}

        {selected && (
          <GameDetailModal
            game={selected}
            libraryId={libraryId}
            onClose={() => setSelected(null)}
            onTagsChanged={() => { setFilterRefreshKey((k) => k + 1); fetchAssignments() }}
            onCoverUploaded={() => fetchGames(true)}
          />
        )}
        </div>
      </div>
    </>
  )
}

function GameCard({ game, onClick }: { game: Game; onClick: () => void }) {
  return (
    <button
      onClick={onClick}
      className="group text-left rounded-xl overflow-hidden border transition-all focus:outline-none focus-visible:ring-2"
      style={{ borderColor: 'var(--border)', backgroundColor: 'var(--surface)' }}
      onMouseEnter={(e) => {
        ;(e.currentTarget as HTMLElement).style.borderColor = 'var(--accent)'
        ;(e.currentTarget as HTMLElement).style.transform = 'translateY(-2px)'
      }}
      onMouseLeave={(e) => {
        ;(e.currentTarget as HTMLElement).style.borderColor = 'var(--border)'
        ;(e.currentTarget as HTMLElement).style.transform = 'translateY(0)'
      }}
    >
      <div className="aspect-[3/4] w-full relative overflow-hidden" style={{ backgroundColor: 'var(--border)' }}>
        {game.coverUrl ? (
          // eslint-disable-next-line @next/next/no-img-element
          <img src={game.coverUrl} alt={game.title} className="absolute inset-0 w-full h-full object-cover" />
        ) : (
          <div className="absolute inset-0 flex items-center justify-center text-4xl">🎮</div>
        )}
      </div>
      <div className="p-2">
        <p className="text-xs font-medium truncate leading-tight" style={{ color: 'var(--text-primary)' }} title={game.title}>
          {game.title}
        </p>
      </div>
    </button>
  )
}

function SeriesCard({ series, onClick }: { series: GameSeries; onClick: () => void }) {
  return (
    <button
      onClick={onClick}
      className="group text-left rounded-xl overflow-hidden border transition-all focus:outline-none focus-visible:ring-2"
      style={{ borderColor: 'var(--border)', backgroundColor: 'var(--surface)' }}
      onMouseEnter={(e) => {
        ;(e.currentTarget as HTMLElement).style.borderColor = 'var(--accent)'
        ;(e.currentTarget as HTMLElement).style.transform = 'translateY(-2px)'
      }}
      onMouseLeave={(e) => {
        ;(e.currentTarget as HTMLElement).style.borderColor = 'var(--border)'
        ;(e.currentTarget as HTMLElement).style.transform = 'translateY(0)'
      }}
    >
      <div className="aspect-[3/4] w-full relative overflow-hidden" style={{ backgroundColor: 'var(--border)' }}>
        {series.coverUrl ? (
          // eslint-disable-next-line @next/next/no-img-element
          <img src={series.coverUrl} alt={series.title} className="absolute inset-0 w-full h-full object-cover" />
        ) : (
          <div className="absolute inset-0 flex items-center justify-center text-4xl">🎮</div>
        )}
        {/* Game count badge */}
        <div
          className="absolute bottom-1.5 right-1.5 px-1.5 py-0.5 rounded text-xs font-semibold"
          style={{ backgroundColor: 'rgba(0,0,0,0.7)', color: '#fff' }}
        >
          {series.games.length}
        </div>
      </div>
      <div className="p-2">
        <p className="text-xs font-medium truncate leading-tight" style={{ color: 'var(--text-primary)' }} title={series.title}>
          {series.title}
        </p>
        <p className="text-xs mt-0.5" style={{ color: 'var(--text-secondary)' }}>
          Series
        </p>
      </div>
    </button>
  )
}

function LoadingGrid() {
  return (
    <div className="grid gap-4 grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6">
      {Array.from({ length: 12 }).map((_, i) => (
        <div key={i} className="rounded-xl overflow-hidden" style={{ backgroundColor: 'var(--surface)' }}>
          <div className="aspect-[3/4] w-full animate-pulse" style={{ backgroundColor: 'var(--border)' }} />
          <div className="p-2">
            <div className="h-3 rounded animate-pulse" style={{ backgroundColor: 'var(--border)', width: '70%' }} />
          </div>
        </div>
      ))}
    </div>
  )
}
