'use client'

import { useCallback, useEffect, useState } from 'react'
import type { ComicIssue, ComicSeries } from '@/types'
import ComicSeriesView from './ComicSeriesView'
import ComicIssueView from './ComicIssueView'
import FilterPanel from '@/components/FilterPanel'
import TagSelector from '@/components/tags/TagSelector'

interface Props {
  libraryId: string
  readOnly?: boolean
}

export default function ComicsView({ libraryId, readOnly }: Props) {
  const [items, setItems] = useState<(ComicIssue | ComicSeries)[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [selectedSeries, setSelectedSeries] = useState<ComicSeries | null>(null)
  const [selectedIssue, setSelectedIssue] = useState<ComicIssue | null>(null)
  const [tagPanel, setTagPanel] = useState<{ itemKey: string; title: string } | null>(null)
  const [search, setSearch] = useState('')
  const [selectedTagIds, setSelectedTagIds] = useState<Set<string>>(new Set())
  const [assignments, setAssignments] = useState<Record<string, string[]>>({})
  const [seriesIssueMeta, setSeriesIssueMeta] = useState<
    Record<string, { tagIds: string[]; issueTitles: string[] }>
  >({})
  const [filterRefreshKey, setFilterRefreshKey] = useState(0)
  const [showFilters, setShowFilters] = useState(
    () => typeof window !== 'undefined' && window.innerWidth >= 768
  )

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

  const fetchItems = useCallback(() => {
    fetch(`/api/comics?libraryId=${encodeURIComponent(libraryId)}`)
      .then((r) => r.json())
      .then((data: (ComicIssue | ComicSeries)[]) => {
        setItems(data)
        setLoading(false)
      })
      .catch(() => {
        setError('Failed to load comics')
        setLoading(false)
      })
  }, [libraryId])

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

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

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

  const fetchSeriesIssueMeta = useCallback(() => {
    fetch(`/api/comics/series-issue-tags?libraryId=${encodeURIComponent(libraryId)}`)
      .then((r) => r.json())
      .then(setSeriesIssueMeta)
      .catch(() => {})
  }, [libraryId])

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

  const onTagsChanged = useCallback(() => {
    setFilterRefreshKey((k) => k + 1)
    fetchAssignments()
    fetchSeriesIssueMeta()
  }, [fetchAssignments, fetchSeriesIssueMeta])

  const filtered = items.filter((item) => {
    const isSeries = 'issueCount' in item

    if (isSeries) {
      const meta = seriesIssueMeta[item.item_key ?? ''] ?? { tagIds: [], issueTitles: [] }

      if (search) {
        const q = search.toLowerCase()
        const titleMatch = item.title.toLowerCase().includes(q)
        const issueMatch = meta.issueTitles.some((t) => t.toLowerCase().includes(q))
        if (!titleMatch && !issueMatch) return false
      }

      if (selectedTagIds.size > 0) {
        const seriesTags = assignments[item.item_key ?? ''] ?? []
        const allTags = [...new Set([...seriesTags, ...meta.tagIds])]
        if (![...selectedTagIds].every((id) => allTags.includes(id))) return false
      }

      return true
    }

    // Standalone issue
    if (search && !item.title.toLowerCase().includes(search.toLowerCase())) return false
    if (selectedTagIds.size > 0) {
      const tags = assignments[item.item_key ?? ''] ?? []
      if (![...selectedTagIds].every((id) => tags.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">
          {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 comics found</p>
              <p className="text-sm">Add .cbz files or folders of .cbz files to this library and scan.</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) =>
                'issueCount' in item ? (
                  <SeriesCard
                    key={item.id}
                    series={item as ComicSeries}
                    readOnly={readOnly}
                    onClick={() => setSelectedSeries(item as ComicSeries)}
                    onTagClick={(item as ComicSeries).item_key && !readOnly
                      ? () => setTagPanel({ itemKey: (item as ComicSeries).item_key!, title: item.title })
                      : undefined}
                  />
                ) : (
                  <IssueCard
                    key={item.id}
                    issue={item as ComicIssue}
                    readOnly={readOnly}
                    onClick={() => setSelectedIssue(item as ComicIssue)}
                    onTagClick={(item as ComicIssue).item_key && !readOnly
                      ? () => setTagPanel({ itemKey: (item as ComicIssue).item_key!, title: item.title })
                      : undefined}
                  />
                )
              )}
            </div>
          )}
        </div>
      </div>

      {/* Tag panel modal */}
      {tagPanel && (
        <div
          className="fixed inset-0 z-50 flex items-end sm:items-center justify-center p-4"
          style={{ backgroundColor: 'rgba(0,0,0,0.6)' }}
          onClick={(e) => { if (e.target === e.currentTarget) setTagPanel(null) }}
        >
          <div
            className="w-full max-w-md rounded-2xl shadow-2xl overflow-hidden"
            style={{ backgroundColor: 'var(--surface)', border: '1px solid var(--border)' }}
          >
            <div
              className="flex items-center justify-between px-5 py-4"
              style={{ borderBottom: '1px solid var(--border)' }}
            >
              <div className="min-w-0">
                <p className="text-xs font-semibold uppercase tracking-wider mb-0.5" style={{ color: 'var(--text-secondary)' }}>
                  Tags
                </p>
                <p className="text-sm font-medium truncate" style={{ color: 'var(--text-primary)' }}>
                  {tagPanel.title}
                </p>
              </div>
              <button
                onClick={() => setTagPanel(null)}
                className="ml-4 w-8 h-8 flex-shrink-0 rounded-full flex items-center justify-center text-sm transition-colors"
                style={{ backgroundColor: 'var(--border)', color: 'var(--text-secondary)' }}
                aria-label="Close"
              >
                ✕
              </button>
            </div>
            <div className="px-5 py-4">
              <TagSelector
                itemKey={tagPanel.itemKey}
                onTagsChanged={onTagsChanged}
                readOnly={readOnly}
              />
            </div>
          </div>
        </div>
      )}

      {selectedSeries && (
        <ComicSeriesView
          libraryId={libraryId}
          series={selectedSeries}
          onClose={() => setSelectedSeries(null)}
          onTagsChanged={onTagsChanged}
          readOnly={readOnly}
        />
      )}

      {selectedIssue && (
        <ComicIssueView
          libraryId={libraryId}
          issue={selectedIssue}
          onClose={() => setSelectedIssue(null)}
          onTagsChanged={onTagsChanged}
          readOnly={readOnly}
        />
      )}
    </>
  )
}

function SeriesCard({
  series,
  onClick,
  onTagClick,
  readOnly,
}: {
  series: ComicSeries
  onClick: () => void
  onTagClick?: () => void
  readOnly?: boolean
}) {
  return (
    <div
      className="relative rounded-xl overflow-hidden group"
      style={{ border: '1px solid var(--border)', background: 'var(--surface)' }}
    >
      <button className="text-left w-full focus:outline-none focus:ring-2" onClick={onClick}>
        <div
          className="relative w-full overflow-hidden"
          style={{ aspectRatio: '2/3', background: 'var(--border)' }}
        >
          {series.coverUrl ? (
            // eslint-disable-next-line @next/next/no-img-element
            <img
              src={series.coverUrl}
              alt={series.title}
              className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-200"
            />
          ) : (
            <div className="w-full h-full flex items-center justify-center text-4xl">📚</div>
          )}
          <div
            className="absolute top-1 right-1 px-1.5 py-0.5 rounded text-xs font-bold leading-none"
            style={{ backgroundColor: 'rgba(0,0,0,0.7)', color: '#fff' }}
          >
            {series.issueCount}
          </div>
        </div>
        <div className="px-2 pt-1.5 pb-1">
          <p className="text-xs font-medium leading-tight truncate" style={{ color: 'var(--text-primary)' }}>
            {series.title}
          </p>
          <p className="text-xs mt-0.5" style={{ color: 'var(--text-secondary)' }}>
            {series.issueCount} {series.issueCount === 1 ? 'issue' : 'issues'}
          </p>
        </div>
      </button>
      {onTagClick && !readOnly && (
        <button
          onClick={(e) => { e.stopPropagation(); onTagClick() }}
          className="absolute top-1 left-1 w-6 h-6 rounded-full flex items-center justify-center text-xs opacity-0 group-hover:opacity-100 transition-opacity"
          style={{ backgroundColor: 'rgba(0,0,0,0.6)', color: '#fff' }}
          title="Tag series"
          aria-label="Tag series"
        >
          🏷
        </button>
      )}
    </div>
  )
}

function IssueCard({
  issue,
  onClick,
  onTagClick,
  readOnly,
}: {
  issue: ComicIssue
  onClick: () => void
  onTagClick?: () => void
  readOnly?: boolean
}) {
  return (
    <div
      className="relative rounded-xl overflow-hidden group"
      style={{ border: '1px solid var(--border)', background: 'var(--surface)' }}
    >
      <button className="text-left w-full focus:outline-none focus:ring-2" onClick={onClick}>
        <div
          className="relative w-full overflow-hidden"
          style={{ aspectRatio: '2/3', background: 'var(--border)' }}
        >
          {issue.coverUrl ? (
            // eslint-disable-next-line @next/next/no-img-element
            <img
              src={issue.coverUrl}
              alt={issue.title}
              className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-200"
            />
          ) : (
            <div className="w-full h-full flex items-center justify-center text-4xl">📖</div>
          )}
        </div>
        <div className="px-2 pt-1.5 pb-1">
          <p className="text-xs font-medium leading-tight truncate" style={{ color: 'var(--text-primary)' }}>
            {issue.title}
          </p>
          <p className="text-xs mt-0.5" style={{ color: 'var(--text-secondary)' }}>
            {issue.pageCount} {issue.pageCount === 1 ? 'pg' : 'pgs'}
          </p>
        </div>
      </button>
      {onTagClick && !readOnly && (
        <button
          onClick={(e) => { e.stopPropagation(); onTagClick() }}
          className="absolute top-1 left-1 w-6 h-6 rounded-full flex items-center justify-center text-xs opacity-0 group-hover:opacity-100 transition-opacity"
          style={{ backgroundColor: 'rgba(0,0,0,0.6)', color: '#fff' }}
          title="Tag issue"
          aria-label="Tag issue"
        >
          🏷
        </button>
      )}
    </div>
  )
}

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 }, (_, i) => (
        <div key={i} className="rounded-xl overflow-hidden animate-pulse" style={{ border: '1px solid var(--border)' }}>
          <div style={{ aspectRatio: '2/3', background: 'var(--border)' }} />
          <div className="p-2 space-y-1">
            <div className="h-3 rounded" style={{ background: 'var(--border)', width: '75%' }} />
            <div className="h-2 rounded" style={{ background: 'var(--border)', width: '40%' }} />
          </div>
        </div>
      ))}
    </div>
  )
}
