import React, { useState } from 'react'
import { useParams, useNavigate, Link } from 'react-router-dom'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import {
  ArrowLeft, Trash2, ChevronDown, ChevronUp, ExternalLink,
  Swords, Zap, Sparkles, Shield, Cog, Star, Mountain, X
} from 'lucide-react'
import { decksApi } from '@/api'
import { Button, Badge, Spinner, Panel, EmptyState } from '@/components/ui'
import type { Deck, DeckCard, CardSlot } from '@/types'

// ─── Slot metadata ────────────────────────────────────────────────────────────

const SLOT_META: Record<CardSlot, { label: string; icon: React.ReactNode; color: string }> = {
  creature:     { label: 'Creatures',     icon: <Swords className="w-4 h-4" />,    color: 'text-green-400' },
  instant:      { label: 'Instants',      icon: <Zap className="w-4 h-4" />,       color: 'text-blue-400' },
  sorcery:      { label: 'Sorceries',     icon: <Sparkles className="w-4 h-4" />,  color: 'text-purple-400' },
  enchantment:  { label: 'Enchantments',  icon: <Star className="w-4 h-4" />,      color: 'text-yellow-400' },
  artifact:     { label: 'Artifacts',     icon: <Cog className="w-4 h-4" />,       color: 'text-slate-400' },
  planeswalker: { label: 'Planeswalkers', icon: <Shield className="w-4 h-4" />,    color: 'text-pink-400' },
  land:         { label: 'Lands',         icon: <Mountain className="w-4 h-4" />,  color: 'text-amber-600' },
  battle:       { label: 'Battles',       icon: <Swords className="w-4 h-4" />,    color: 'text-red-400' },
}

const SLOT_ORDER: CardSlot[] = [
  'creature', 'instant', 'sorcery', 'enchantment', 'artifact', 'planeswalker', 'land', 'battle',
]

// ─── Card image helper ────────────────────────────────────────────────────────

function cardImageUrl(card: DeckCard, size: 'small' | 'normal' = 'small'): string | null {
  const sf = card.scryfall_data
  if (!sf) return null
  const uris = sf.image_uris
  if (uris) return uris[size] ?? null
  const faces = sf.card_faces
  if (faces?.length) return faces[0].image_uris?.[size] ?? null
  return null
}

// ─── Reasoning drawer ─────────────────────────────────────────────────────────

function ReasoningDrawer({
  card,
  onClose,
}: {
  card: DeckCard
  onClose: () => void
}) {
  const img = cardImageUrl(card, 'normal')

  return (
    <div className="fixed inset-0 z-50 flex items-end md:items-center justify-center p-4">
      <div
        className="absolute inset-0 bg-black/70 backdrop-blur-sm"
        onClick={onClose}
      />
      <div className="relative bg-bg-surface border border-bg-border rounded-xl shadow-card w-full max-w-lg animate-slide-up">
        <div className="flex items-start gap-4 p-5">
          {img && (
            <img
              src={img}
              alt={card.card_name}
              className="w-24 rounded-lg shadow-card flex-shrink-0 hidden sm:block"
            />
          )}
          <div className="flex-1 min-w-0">
            <div className="flex items-start justify-between gap-2 mb-3">
              <div>
                <h3 className="font-display text-base text-text-primary">{card.card_name}</h3>
                {card.scryfall_data?.type_line && (
                  <p className="text-xs text-text-muted mt-0.5">{card.scryfall_data.type_line}</p>
                )}
              </div>
              <button onClick={onClose} className="text-text-muted hover:text-text-primary flex-shrink-0">
                <X className="w-5 h-5" />
              </button>
            </div>
            <div className="flex flex-wrap gap-2 mb-3">
              <Badge variant={card.is_owned ? 'owned' : 'unowned'}>
                {card.is_owned ? 'Owned' : 'Unowned'}
              </Badge>
              <Badge variant="slot">{SLOT_META[card.slot]?.label ?? card.slot}</Badge>
              {card.scryfall_data?.prices?.usd && (
                <Badge variant="default">${card.scryfall_data.prices.usd}</Badge>
              )}
            </div>
            {card.ai_reasoning && (
              <div className="bg-bg-elevated rounded-md p-3 text-sm text-text-secondary leading-relaxed">
                {card.ai_reasoning}
              </div>
            )}
          </div>
        </div>
        {card.scryfall_id && (
          <div className="px-5 pb-4">
            <a
              href={`https://scryfall.com/card/${card.scryfall_id}`}
              target="_blank"
              rel="noopener noreferrer"
              className="text-xs text-text-muted hover:text-accent-violet-light flex items-center gap-1"
            >
              View on Scryfall <ExternalLink className="w-3 h-3" />
            </a>
          </div>
        )}
      </div>
    </div>
  )
}

// ─── Card tile ────────────────────────────────────────────────────────────────

function CardTile({ card, onClick }: { card: DeckCard; onClick: () => void }) {
  const img = cardImageUrl(card, 'small')
  const price = card.scryfall_data?.prices?.usd

  return (
    <button
      onClick={onClick}
      className="group flex items-center gap-3 bg-bg-elevated hover:bg-bg-border/50 border border-bg-border hover:border-accent-violet/40 rounded-md px-3 py-2 text-left transition-all w-full"
    >
      {img ? (
        <img
          src={img}
          alt={card.card_name}
          className="w-8 h-10 rounded object-cover flex-shrink-0 opacity-90 group-hover:opacity-100"
        />
      ) : (
        <div className="w-8 h-10 rounded bg-bg-border flex-shrink-0" />
      )}
      <div className="flex-1 min-w-0">
        <p className="text-sm text-text-primary truncate group-hover:text-accent-violet-light transition-colors">
          {card.quantity > 1 && <span className="text-text-muted mr-1.5">{card.quantity}×</span>}
          {card.card_name}
        </p>
        {card.scryfall_data?.mana_cost && (
          <p className="text-xs text-text-muted truncate">{card.scryfall_data.mana_cost}</p>
        )}
      </div>
      <div className="flex flex-col items-end gap-1 flex-shrink-0">
        {!card.is_owned && (
          <span className="w-1.5 h-1.5 rounded-full bg-unowned" title="Unowned" />
        )}
        {price && <span className="text-xs text-text-muted">${price}</span>}
      </div>
    </button>
  )
}

// ─── Slot group ───────────────────────────────────────────────────────────────

function SlotGroup({ slot, cards }: { slot: CardSlot; cards: DeckCard[] }) {
  const [open, setOpen] = useState(true)
  const [selectedCard, setSelectedCard] = useState<DeckCard | null>(null)
  const meta = SLOT_META[slot]
  const totalCount = cards.reduce((s, c) => s + (c.quantity || 1), 0)

  return (
    <div className="mb-4">
      <button
        onClick={() => setOpen((o) => !o)}
        className="flex items-center gap-2 w-full mb-2 group"
      >
        <span className={`${meta.color}`}>{meta.icon}</span>
        <span className="text-sm font-semibold text-text-primary">{meta.label}</span>
        <span className="text-xs text-text-muted">({totalCount})</span>
        <div className="flex-1 h-px bg-bg-border ml-2" />
        {open ? (
          <ChevronUp className="w-3.5 h-3.5 text-text-muted" />
        ) : (
          <ChevronDown className="w-3.5 h-3.5 text-text-muted" />
        )}
      </button>

      {open && (
        <div className="flex flex-col gap-1 animate-fade-in">
          {cards.map((card) => (
            <CardTile key={card.id} card={card} onClick={() => setSelectedCard(card)} />
          ))}
        </div>
      )}

      {selectedCard && (
        <ReasoningDrawer card={selectedCard} onClose={() => setSelectedCard(null)} />
      )}
    </div>
  )
}

// ─── Cuts section ─────────────────────────────────────────────────────────────

function CutsSection({ cuts }: { cuts: { name: string; reasoning: string }[] }) {
  const [open, setOpen] = useState(false)

  if (!cuts.length) return null

  return (
    <Panel className="p-5">
      <button onClick={() => setOpen((o) => !o)} className="flex items-center justify-between w-full mb-1">
        <div className="flex items-center gap-2">
          <X className="w-4 h-4 text-danger" />
          <span className="font-display text-sm text-text-primary">Suggested cuts ({cuts.length})</span>
        </div>
        {open ? <ChevronUp className="w-4 h-4 text-text-muted" /> : <ChevronDown className="w-4 h-4 text-text-muted" />}
      </button>
      {open && (
        <div className="flex flex-col gap-2 mt-3 animate-fade-in">
          {cuts.map((cut, i) => (
            <div key={i} className="flex gap-3 bg-danger/5 border border-danger/20 rounded-md p-3">
              <span className="text-xs text-danger font-medium mt-0.5 flex-shrink-0">#{i + 1}</span>
              <div>
                <p className="text-sm font-medium text-text-primary">{cut.name}</p>
                <p className="text-xs text-text-secondary mt-0.5 leading-relaxed">{cut.reasoning}</p>
              </div>
            </div>
          ))}
        </div>
      )}
    </Panel>
  )
}

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

export function DeckViewPage() {
  const { id } = useParams<{ id: string }>()
  const navigate = useNavigate()
  const queryClient = useQueryClient()

  const { data: deck, isLoading, error } = useQuery<Deck>({
    queryKey: ['deck', id],
    queryFn: async () => (await decksApi.get(Number(id))).data,
    enabled: !!id,
  })

  const deleteMutation = useMutation({
    mutationFn: () => decksApi.delete(Number(id)),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['decks'] })
      navigate('/decks')
    },
  })

  if (isLoading) {
    return (
      <div className="flex items-center justify-center h-64">
        <Spinner size="lg" />
      </div>
    )
  }

  if (error || !deck) {
    return (
      <div className="max-w-2xl mx-auto px-4 py-8">
        <EmptyState title="Deck not found" description="This deck may have been deleted." />
      </div>
    )
  }

  // Group cards by slot (excluding commander)
  const nonCommanderCards = deck.cards.filter((c) => !c.is_commander)
  const commander = deck.cards.find((c) => c.is_commander)
  const bySlot = SLOT_ORDER.reduce<Record<CardSlot, DeckCard[]>>(
    (acc, slot) => {
      acc[slot] = nonCommanderCards.filter((c) => c.slot === slot)
      return acc
    },
    {} as Record<CardSlot, DeckCard[]>
  )

  const ownedCount = nonCommanderCards.filter((c) => c.is_owned).length
  const totalNonBasics = nonCommanderCards.filter((c) => c.slot !== 'land').length
  const totalCards = nonCommanderCards.reduce((s, c) => s + (c.quantity || 1), 0)

  const cuts = deck.ai_reasoning?.cuts ?? []
  const unresolved = deck.ai_reasoning?.unresolved_cards ?? []

  return (
    <div className="max-w-3xl mx-auto px-4 py-8">
      {/* Header */}
      <div className="flex items-start justify-between gap-4 mb-6">
        <div className="flex items-start gap-3">
          <Link to="/decks" className="text-text-muted hover:text-text-primary mt-1">
            <ArrowLeft className="w-5 h-5" />
          </Link>
          <div>
            <h1 className="font-display text-2xl text-text-primary">{deck.name}</h1>
            <div className="flex flex-wrap items-center gap-2 mt-1">
              <Badge variant="mode">{deck.mode}</Badge>
              <span className="text-text-muted text-sm">•</span>
              <span className="text-text-secondary text-sm">{deck.commander}</span>
              {deck.playstyle && (
                <>
                  <span className="text-text-muted text-sm">•</span>
                  <span className="text-text-muted text-sm">{deck.playstyle}</span>
                </>
              )}
            </div>
          </div>
        </div>

        <Button
          variant="danger"
          size="sm"
          icon={<Trash2 className="w-4 h-4" />}
          loading={deleteMutation.isPending}
          onClick={() => {
            if (confirm('Delete this deck?')) deleteMutation.mutate()
          }}
        >
          Delete
        </Button>
      </div>

      {/* Stats bar */}
      <div className="grid grid-cols-3 gap-3 mb-6">
        {[
          { label: 'Total cards', value: totalCards + 1 },
          { label: 'Owned', value: `${ownedCount}/${totalCards}` },
          { label: 'Non-lands', value: totalNonBasics },
        ].map((stat) => (
          <Panel key={stat.label} className="p-3 text-center">
            <p className="text-xl font-semibold text-text-primary">{stat.value}</p>
            <p className="text-xs text-text-muted mt-0.5">{stat.label}</p>
          </Panel>
        ))}
      </div>

      {/* Strategy summary */}
      {deck.ai_reasoning?.strategy_summary && (
        <Panel className="p-5 mb-6">
          <p className="text-xs font-medium text-text-secondary uppercase tracking-wider mb-2">Strategy</p>
          <p className="text-sm text-text-secondary leading-relaxed">{deck.ai_reasoning.strategy_summary}</p>
        </Panel>
      )}

      {/* Commander */}
      {commander && (
        <div className="mb-6">
          <p className="text-xs font-medium text-text-secondary uppercase tracking-wider mb-2">Commander</p>
          <div className="bg-accent-violet/10 border border-accent-violet/30 rounded-lg px-4 py-3 flex items-center gap-3">
            <span className="font-display text-base text-accent-violet-light">{commander.card_name}</span>
            <Badge variant={commander.is_owned ? 'owned' : 'unowned'}>
              {commander.is_owned ? 'Owned' : 'Unowned'}
            </Badge>
          </div>
        </div>
      )}

      {/* Unresolved cards warning */}
      {unresolved.length > 0 && (
        <div className="bg-unowned/10 border border-unowned/30 rounded-lg p-4 mb-6 flex gap-3">
          <span className="text-unowned flex-shrink-0">⚠</span>
          <div>
            <p className="text-sm font-medium text-unowned">Unresolved cards ({unresolved.length})</p>
            <p className="text-xs text-text-secondary mt-1">
              These card names could not be verified on Scryfall:{' '}
              {unresolved.join(', ')}
            </p>
          </div>
        </div>
      )}

      {/* Card grid by slot */}
      <div>
        {SLOT_ORDER.map((slot) => {
          const cards = bySlot[slot]
          if (!cards.length) return null
          return <SlotGroup key={slot} slot={slot} cards={cards} />
        })}
      </div>

      {/* Cuts */}
      {cuts.length > 0 && <CutsSection cuts={cuts} />}
    </div>
  )
}
