import React, { useState, useRef } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { Upload, Package, Search, Trash2, RefreshCw, X, ChevronLeft, ChevronRight } from 'lucide-react'
import { collectionApi } from '@/api'
import { Button, Input, Panel, Badge, Spinner, EmptyState, Skeleton, ErrorMessage } from '@/components/ui'
import type { CollectionCard, CollectionStats } from '@/types'
import { AxiosError } from 'axios'

// ─── Import panel ─────────────────────────────────────────────────────────────

function ImportPanel({ onSuccess }: { onSuccess: () => void }) {
  const [source, setSource] = useState<'archidekt' | 'manabox'>('archidekt')
  const [replace, setReplace] = useState(false)
  const [file, setFile] = useState<File | null>(null)
  const [error, setError] = useState('')
  const [success, setSuccess] = useState('')
  const fileRef = useRef<HTMLInputElement>(null)

  const importMutation = useMutation({
    mutationFn: () => collectionApi.import(source, file!, replace),
    onSuccess: (res) => {
      setSuccess(`Imported ${res.data.imported ?? 'cards'} successfully.`)
      setFile(null)
      setError('')
      onSuccess()
    },
    onError: (err) => {
      if (err instanceof AxiosError) {
        setError(err.response?.data?.detail ?? 'Import failed.')
      } else {
        setError('Import failed.')
      }
    },
  })

  return (
    <Panel className="p-5 flex flex-col gap-4">
      <h2 className="font-display text-base text-text-primary">Import collection</h2>

      {/* Source selector */}
      <div className="flex gap-2">
        {(['archidekt', 'manabox'] as const).map((s) => (
          <button
            key={s}
            onClick={() => setSource(s)}
            className={`flex-1 py-2 rounded text-sm font-medium transition-all capitalize ${
              source === s
                ? 'bg-accent-violet text-white'
                : 'bg-bg-elevated text-text-muted hover:text-text-primary border border-bg-border'
            }`}
          >
            {s}
          </button>
        ))}
      </div>

      {/* File drop zone */}
      <div
        onClick={() => fileRef.current?.click()}
        className={`
          border-2 border-dashed rounded-lg p-6 text-center cursor-pointer transition-all
          ${file ? 'border-accent-violet/50 bg-accent-violet/5' : 'border-bg-border hover:border-accent-violet/40 hover:bg-bg-elevated'}
        `}
      >
        <input
          ref={fileRef}
          type="file"
          accept=".csv,.json"
          className="hidden"
          onChange={(e) => setFile(e.target.files?.[0] ?? null)}
        />
        {file ? (
          <div className="flex items-center justify-center gap-2">
            <span className="text-sm text-accent-violet-light">{file.name}</span>
            <button
              onClick={(e) => { e.stopPropagation(); setFile(null) }}
              className="text-text-muted hover:text-danger"
            >
              <X className="w-4 h-4" />
            </button>
          </div>
        ) : (
          <div className="flex flex-col items-center gap-2 text-text-muted">
            <Upload className="w-6 h-6" />
            <p className="text-sm">Click to choose {source === 'archidekt' ? 'CSV or JSON' : 'CSV'} file</p>
          </div>
        )}
      </div>

      <label className="flex items-center gap-2 cursor-pointer">
        <input
          type="checkbox"
          checked={replace}
          onChange={(e) => setReplace(e.target.checked)}
          className="rounded border-bg-border"
        />
        <span className="text-sm text-text-secondary">Replace existing collection</span>
      </label>

      {error && <ErrorMessage message={error} />}
      {success && (
        <div className="bg-owned/10 border border-owned/30 rounded-md p-3 text-sm text-owned">
          {success}
        </div>
      )}

      <Button
        loading={importMutation.isPending}
        disabled={!file}
        icon={<Upload className="w-4 h-4" />}
        onClick={() => importMutation.mutate()}
      >
        Import
      </Button>
    </Panel>
  )
}

// ─── Stats panel ──────────────────────────────────────────────────────────────

function StatsPanel() {
  const { data } = useQuery<CollectionStats>({
    queryKey: ['collection-stats'],
    queryFn: async () => (await collectionApi.stats()).data,
  })

  if (!data) return null

  return (
    <div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
      {[
        { label: 'Total cards', value: data.total_cards.toLocaleString() },
        { label: 'Unique cards', value: data.unique_cards.toLocaleString() },
        { label: 'Foil', value: data.foil_cards.toLocaleString() },
        {
          label: 'Est. value',
          value: data.estimated_value != null ? `$${data.estimated_value.toFixed(2)}` : '—',
        },
      ].map((s) => (
        <Panel key={s.label} className="p-3 text-center">
          <p className="text-xl font-semibold text-text-primary">{s.value}</p>
          <p className="text-xs text-text-muted mt-0.5">{s.label}</p>
        </Panel>
      ))}
    </div>
  )
}

// ─── Card row ─────────────────────────────────────────────────────────────────

function CollectionCardRow({
  card,
  onDelete,
}: {
  card: CollectionCard
  onDelete: (id: number) => void
}) {
  const img = card.scryfall_data?.image_uris?.small
  const price = card.scryfall_data?.prices?.usd

  return (
    <div className="flex items-center gap-3 py-2.5 px-3 hover:bg-bg-elevated rounded-md transition-colors group">
      {img ? (
        <img src={img} alt={card.card_name} className="w-7 h-9 rounded object-cover flex-shrink-0" />
      ) : (
        <div className="w-7 h-9 bg-bg-border rounded flex-shrink-0" />
      )}
      <div className="flex-1 min-w-0">
        <p className="text-sm text-text-primary truncate">{card.card_name}</p>
        <div className="flex gap-2 items-center mt-0.5">
          {card.set_code && (
            <span className="text-xs text-text-muted uppercase">{card.set_code}</span>
          )}
          {card.collector_number && (
            <span className="text-xs text-text-muted">#{card.collector_number}</span>
          )}
        </div>
      </div>
      <div className="flex items-center gap-3 flex-shrink-0">
        <div className="text-right">
          {card.quantity > 0 && (
            <span className="text-xs text-text-secondary">{card.quantity}×</span>
          )}
          {card.foil_quantity > 0 && (
            <span className="text-xs text-unowned ml-1.5">{card.foil_quantity}✦</span>
          )}
        </div>
        {price && <span className="text-xs text-text-muted">${price}</span>}
        <button
          onClick={() => onDelete(card.id)}
          className="text-text-muted hover:text-danger opacity-0 group-hover:opacity-100 transition-all"
        >
          <X className="w-4 h-4" />
        </button>
      </div>
    </div>
  )
}

// ─── Main page ────────────────────────────────────────────────────────────────

export function CollectionPage() {
  const [search, setSearch] = useState('')
  const [page, setPage] = useState(1)
  const queryClient = useQueryClient()

  const { data, isLoading } = useQuery({
    queryKey: ['collection', search, page],
    queryFn: async () => (await collectionApi.list(search, page)).data,
  })

  const deleteMutation = useMutation({
    mutationFn: (id: number) => collectionApi.deleteCard(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['collection'] })
      queryClient.invalidateQueries({ queryKey: ['collection-stats'] })
    },
  })

  const clearMutation = useMutation({
    mutationFn: () => collectionApi.clear(),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['collection'] })
      queryClient.invalidateQueries({ queryKey: ['collection-stats'] })
    },
  })

  const invalidate = () => {
    queryClient.invalidateQueries({ queryKey: ['collection'] })
    queryClient.invalidateQueries({ queryKey: ['collection-stats'] })
  }

  const cards: CollectionCard[] = data?.items ?? []
  const total: number = data?.total ?? 0
  const pages: number = data?.pages ?? 1

  return (
    <div className="max-w-3xl mx-auto px-4 py-8">
      <div className="flex items-center justify-between mb-6">
        <h1 className="font-display text-2xl text-text-primary">Collection</h1>
        {total > 0 && (
          <Button
            variant="danger"
            size="sm"
            icon={<Trash2 className="w-4 h-4" />}
            loading={clearMutation.isPending}
            onClick={() => {
              if (confirm('Clear your entire collection? This cannot be undone.')) {
                clearMutation.mutate()
              }
            }}
          >
            Clear all
          </Button>
        )}
      </div>

      <div className="flex flex-col gap-6">
        <ImportPanel onSuccess={invalidate} />
        <StatsPanel />

        {/* Search */}
        <div className="relative">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-text-muted" />
          <input
            type="text"
            value={search}
            onChange={(e) => { setSearch(e.target.value); setPage(1) }}
            placeholder="Search collection…"
            className="w-full bg-bg-elevated border border-bg-border rounded-md pl-9 pr-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-accent-violet focus:border-transparent"
          />
        </div>

        {/* Card list */}
        <Panel className="overflow-hidden">
          {isLoading ? (
            <div className="p-4 flex flex-col gap-2">
              {[1, 2, 3, 4, 5].map((n) => (
                <div key={n} className="flex gap-3 items-center">
                  <Skeleton className="w-7 h-9 rounded" />
                  <div className="flex-1">
                    <Skeleton className="h-4 w-40 mb-1.5" />
                    <Skeleton className="h-3 w-20" />
                  </div>
                </div>
              ))}
            </div>
          ) : cards.length === 0 ? (
            <EmptyState
              icon={<Package className="w-full h-full" />}
              title={search ? 'No matching cards' : 'Collection is empty'}
              description={search ? 'Try a different search.' : 'Import your collection above.'}
            />
          ) : (
            <div className="divide-y divide-bg-border px-1">
              {cards.map((card) => (
                <CollectionCardRow
                  key={card.id}
                  card={card}
                  onDelete={(id) => deleteMutation.mutate(id)}
                />
              ))}
            </div>
          )}
        </Panel>

        {/* Pagination */}
        {pages > 1 && (
          <div className="flex items-center justify-between text-sm text-text-muted">
            <span>{total} cards</span>
            <div className="flex items-center gap-2">
              <button
                onClick={() => setPage((p) => Math.max(1, p - 1))}
                disabled={page === 1}
                className="p-1 hover:text-text-primary disabled:opacity-30"
              >
                <ChevronLeft className="w-4 h-4" />
              </button>
              <span>Page {page} of {pages}</span>
              <button
                onClick={() => setPage((p) => Math.min(pages, p + 1))}
                disabled={page === pages}
                className="p-1 hover:text-text-primary disabled:opacity-30"
              >
                <ChevronRight className="w-4 h-4" />
              </button>
            </div>
          </div>
        )}
      </div>
    </div>
  )
}
