import { type FormEvent, useMemo, useState } from 'react'
import type {
  BossBattle,
  BossResultTeamMemberInput,
  CreateBossResultInput,
  EncounterDetail,
} from '../types/game'
import { ConditionBadge } from './ConditionBadge'

interface BossDefeatModalProps {
  boss: BossBattle
  aliveEncounters: EncounterDetail[]
  onSubmit: (data: CreateBossResultInput) => void
  onClose: () => void
  isPending?: boolean
  starterName?: string | null
}

function matchVariant(labels: string[], starterName?: string | null): string | null {
  if (!starterName || labels.length === 0) return null
  const lower = starterName.toLowerCase()
  const matches = labels.filter((l) => l.toLowerCase().includes(lower))
  return matches.length === 1 ? (matches[0] ?? null) : null
}

type TeamSelection = number

export function BossDefeatModal({
  boss,
  aliveEncounters,
  onSubmit,
  onClose,
  isPending,
  starterName,
}: BossDefeatModalProps) {
  const [selectedTeam, setSelectedTeam] = useState<Set<TeamSelection>>(new Set())

  const toggleTeamMember = (encounterId: number) => {
    setSelectedTeam((prev) => {
      const next = new Set(prev)
      if (next.has(encounterId)) {
        next.delete(encounterId)
      } else {
        next.add(encounterId)
      }
      return next
    })
  }
  const variantLabels = useMemo(() => {
    const labels = new Set<string>()
    for (const bp of boss.pokemon) {
      if (bp.conditionLabel) labels.add(bp.conditionLabel)
    }
    return [...labels].sort()
  }, [boss.pokemon])

  const hasVariants = variantLabels.length > 0
  const autoMatch = useMemo(
    () => matchVariant(variantLabels, starterName),
    [variantLabels, starterName]
  )
  const showPills = hasVariants && autoMatch === null
  const [selectedVariant, setSelectedVariant] = useState<string | null>(
    autoMatch ?? (hasVariants ? (variantLabels[0] ?? null) : null)
  )

  const displayedPokemon = useMemo(() => {
    if (!hasVariants) return boss.pokemon
    return boss.pokemon.filter(
      (bp) => bp.conditionLabel === selectedVariant || bp.conditionLabel === null
    )
  }, [boss.pokemon, hasVariants, selectedVariant])

  const handleSubmit = (e: FormEvent) => {
    e.preventDefault()
    const team: BossResultTeamMemberInput[] = Array.from(selectedTeam).map((encounterId) => ({
      encounterId,
    }))
    onSubmit({
      bossBattleId: boss.id,
      result: 'won',
      attempts: 1,
      team,
    })
  }

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center">
      <div className="fixed inset-0 bg-black/50" onClick={onClose} />
      <div className="relative bg-surface-1 rounded-lg shadow-xl max-w-md w-full mx-4">
        <div className="px-6 py-4 border-b border-border-default">
          <h2 className="text-lg font-semibold">Battle: {boss.name}</h2>
          <p className="text-sm text-text-tertiary">{boss.location}</p>
        </div>

        {/* Boss team preview */}
        {boss.pokemon.length > 0 && (
          <div className="px-6 py-3 border-b border-border-default">
            {showPills && (
              <div className="flex gap-1 mb-2 flex-wrap">
                {variantLabels.map((label) => (
                  <button
                    key={label}
                    type="button"
                    onClick={() => setSelectedVariant(label)}
                    className={`px-2 py-0.5 text-xs font-medium rounded-full transition-colors ${
                      selectedVariant === label
                        ? 'bg-accent-600 text-white'
                        : 'bg-surface-2 text-text-secondary hover:bg-surface-3'
                    }`}
                  >
                    {label}
                  </button>
                ))}
              </div>
            )}
            <div className="flex flex-wrap gap-3">
              {[...displayedPokemon]
                .sort((a, b) => a.order - b.order)
                .map((bp) => {
                  const moves = [bp.move1, bp.move2, bp.move3, bp.move4].filter(Boolean)
                  return (
                    <div key={bp.id} className="flex flex-col items-center">
                      {bp.pokemon.spriteUrl ? (
                        <img
                          src={bp.pokemon.spriteUrl}
                          alt={bp.pokemon.name}
                          className="w-10 h-10"
                        />
                      ) : (
                        <div className="w-10 h-10 bg-surface-3 rounded-full" />
                      )}
                      <span className="text-xs text-text-tertiary capitalize">
                        {bp.pokemon.name}
                      </span>
                      <span className="text-xs font-medium text-text-secondary">Lv.{bp.level}</span>
                      <ConditionBadge condition={bp.conditionLabel} size="xs" />
                      {bp.ability && (
                        <span className="text-[10px] text-text-muted">{bp.ability.name}</span>
                      )}
                      {bp.heldItem && (
                        <span className="text-[10px] text-yellow-500/80">{bp.heldItem}</span>
                      )}
                      {moves.length > 0 && (
                        <div className="text-[9px] text-text-muted text-center leading-tight max-w-[80px]">
                          {moves.map((m) => m!.name).join(', ')}
                        </div>
                      )}
                    </div>
                  )
                })}
            </div>
          </div>
        )}

        {/* Team selection */}
        {aliveEncounters.length > 0 && (
          <div className="px-6 py-3 border-b border-border-default">
            <p className="text-sm font-medium text-text-secondary mb-2">Your team (optional)</p>
            <div className="grid grid-cols-2 sm:grid-cols-3 gap-2 max-h-48 overflow-y-auto">
              {aliveEncounters.map((enc) => {
                const isSelected = selectedTeam.has(enc.id)
                const displayPokemon = enc.currentPokemon ?? enc.pokemon
                return (
                  <div
                    key={enc.id}
                    className={`flex items-center gap-2 p-2 rounded border cursor-pointer transition-colors ${
                      isSelected
                        ? 'border-accent-500 bg-accent-500/10'
                        : 'border-border-default hover:bg-surface-2'
                    }`}
                    onClick={() => toggleTeamMember(enc.id)}
                  >
                    <input
                      type="checkbox"
                      checked={isSelected}
                      onChange={() => toggleTeamMember(enc.id)}
                      className="sr-only"
                    />
                    {displayPokemon.spriteUrl ? (
                      <img
                        src={displayPokemon.spriteUrl}
                        alt={displayPokemon.name}
                        className="w-8 h-8"
                      />
                    ) : (
                      <div className="w-8 h-8 bg-surface-3 rounded-full" />
                    )}
                    <p className="flex-1 min-w-0 text-xs font-medium truncate">
                      {enc.nickname ?? displayPokemon.name}
                    </p>
                  </div>
                )
              })}
            </div>
          </div>
        )}

        <form onSubmit={handleSubmit}>
          <div className="px-6 py-4 border-t border-border-default flex justify-end gap-3">
            <button
              type="button"
              onClick={onClose}
              className="px-4 py-2 text-sm font-medium rounded-md border border-border-default hover:bg-surface-2"
            >
              Cancel
            </button>
            <button
              type="submit"
              disabled={isPending}
              className="px-4 py-2 text-sm font-medium rounded-md bg-accent-600 text-white hover:bg-accent-500 disabled:opacity-50"
            >
              {isPending ? 'Saving...' : 'Save Result'}
            </button>
          </div>
        </form>
      </div>
    </div>
  )
}
