import { useState } from 'react'
import { useParams, Link } from 'react-router-dom'
import {
  DndContext,
  closestCenter,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
  type DragEndEvent,
} from '@dnd-kit/core'
import {
  SortableContext,
  sortableKeyboardCoordinates,
  useSortable,
  verticalListSortingStrategy,
} from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import { RouteFormModal } from '../../components/admin/RouteFormModal'
import { BossBattleFormModal } from '../../components/admin/BossBattleFormModal'
import { BossTeamEditor } from '../../components/admin/BossTeamEditor'
import { useGame } from '../../hooks/useGames'
import { useGameBosses } from '../../hooks/useBosses'
import {
  useCreateRoute,
  useUpdateRoute,
  useDeleteRoute,
  useReorderRoutes,
  useCreateBossBattle,
  useUpdateBossBattle,
  useDeleteBossBattle,
  useSetBossTeam,
} from '../../hooks/useAdmin'
import { exportGameRoutes, exportGameBosses } from '../../api/admin'
import { downloadJson } from '../../utils/download'
import type { Route as GameRoute, CreateRouteInput, UpdateRouteInput, BossBattle } from '../../types'
import type { CreateBossBattleInput, UpdateBossBattleInput } from '../../types/admin'

function SortableRouteRow({
  route,
  onClick,
}: {
  route: GameRoute
  onClick: (r: GameRoute) => void
}) {
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } =
    useSortable({ id: route.id })

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
  }

  return (
    <tr
      ref={setNodeRef}
      style={style}
      className={`${isDragging ? 'opacity-50 bg-blue-50 dark:bg-blue-900/20' : ''} hover:bg-gray-50 dark:hover:bg-gray-800 cursor-pointer`}
      onClick={() => onClick(route)}
    >
      <td className="px-4 py-3 text-sm w-12">
        <button
          {...attributes}
          {...listeners}
          onClick={(e) => e.stopPropagation()}
          className="cursor-grab active:cursor-grabbing text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 touch-none"
          title="Drag to reorder"
        >
          <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
            <circle cx="5" cy="3" r="1.5" />
            <circle cx="11" cy="3" r="1.5" />
            <circle cx="5" cy="8" r="1.5" />
            <circle cx="11" cy="8" r="1.5" />
            <circle cx="5" cy="13" r="1.5" />
            <circle cx="11" cy="13" r="1.5" />
          </svg>
        </button>
      </td>
      <td className="px-4 py-3 text-sm whitespace-nowrap w-16">{route.order}</td>
      <td className="px-4 py-3 text-sm whitespace-nowrap">{route.name}</td>
    </tr>
  )
}

export function AdminGameDetail() {
  const { gameId } = useParams<{ gameId: string }>()
  const id = Number(gameId)
  const { data: game, isLoading } = useGame(id)

  const createRoute = useCreateRoute(id)
  const updateRoute = useUpdateRoute(id)
  const deleteRoute = useDeleteRoute(id)
  const reorderRoutes = useReorderRoutes(id)
  const { data: bosses } = useGameBosses(id)
  const createBoss = useCreateBossBattle(id)
  const updateBoss = useUpdateBossBattle(id)
  const deleteBoss = useDeleteBossBattle(id)

  const [tab, setTab] = useState<'routes' | 'bosses'>('routes')
  const [showCreate, setShowCreate] = useState(false)
  const [editing, setEditing] = useState<GameRoute | null>(null)
  const [showCreateBoss, setShowCreateBoss] = useState(false)
  const [editingBoss, setEditingBoss] = useState<BossBattle | null>(null)
  const [editingTeam, setEditingTeam] = useState<BossBattle | null>(null)

  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
    useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),
  )

  if (isLoading) return <div className="py-8 text-center text-gray-500">Loading...</div>
  if (!game) return <div className="py-8 text-center text-gray-500">Game not found</div>

  const routes = game.routes ?? []

  const handleDragEnd = (event: DragEndEvent) => {
    const { active, over } = event
    if (!over || active.id === over.id) return

    const oldIndex = routes.findIndex((r) => r.id === active.id)
    const newIndex = routes.findIndex((r) => r.id === over.id)
    if (oldIndex === -1 || newIndex === -1) return

    // Build new order assignments based on rearranged positions
    const reordered = [...routes]
    const [moved] = reordered.splice(oldIndex, 1)
    reordered.splice(newIndex, 0, moved)

    const newOrders = reordered.map((r, i) => ({
      id: r.id,
      order: i + 1,
    }))
    reorderRoutes.mutate(newOrders)
  }

  return (
    <div>
      <nav className="text-sm mb-4 text-gray-500 dark:text-gray-400">
        <Link to="/admin/games" className="hover:underline">
          Games
        </Link>
        {' / '}
        <span className="text-gray-900 dark:text-gray-100">{game.name}</span>
      </nav>

      <div className="mb-6">
        <h2 className="text-xl font-semibold">{game.name}</h2>
        <p className="text-sm text-gray-500 dark:text-gray-400">
          {game.region.charAt(0).toUpperCase() + game.region.slice(1)} &middot; Gen {game.generation}
          {game.releaseYear ? ` \u00b7 ${game.releaseYear}` : ''}
        </p>
      </div>

      <div className="flex border-b border-gray-200 dark:border-gray-700 mb-4">
        <button
          onClick={() => setTab('routes')}
          className={`px-4 py-2 text-sm font-medium border-b-2 -mb-px ${
            tab === 'routes'
              ? 'border-blue-600 text-blue-600 dark:border-blue-400 dark:text-blue-400'
              : 'border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300'
          }`}
        >
          Routes ({routes.length})
        </button>
        <button
          onClick={() => setTab('bosses')}
          className={`px-4 py-2 text-sm font-medium border-b-2 -mb-px ${
            tab === 'bosses'
              ? 'border-blue-600 text-blue-600 dark:border-blue-400 dark:text-blue-400'
              : 'border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300'
          }`}
        >
          Boss Battles ({bosses?.length ?? 0})
        </button>
      </div>

      {tab === 'routes' && (
        <>
          <div className="flex justify-end gap-2 mb-4">
            <button
              onClick={async () => {
                const result = await exportGameRoutes(id)
                downloadJson(result.data, result.filename)
              }}
              className="px-4 py-2 text-sm font-medium rounded-md border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-800"
            >
              Export
            </button>
            <button
              onClick={() => setShowCreate(true)}
              className="px-4 py-2 text-sm font-medium rounded-md bg-blue-600 text-white hover:bg-blue-700"
            >
              Add Route
            </button>
          </div>

          {routes.length === 0 ? (
            <div className="text-center py-8 text-gray-500 dark:text-gray-400 border border-gray-200 dark:border-gray-700 rounded-lg">
              No routes yet. Add one to get started.
            </div>
          ) : (
            <div className="border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden">
              <div className="overflow-x-auto">
                <table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
                  <thead className="bg-gray-50 dark:bg-gray-800">
                    <tr>
                      <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider w-12" />
                      <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider w-16">
                        Order
                      </th>
                      <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
                        Name
                      </th>
                    </tr>
                  </thead>
                  <DndContext
                    sensors={sensors}
                    collisionDetection={closestCenter}
                    onDragEnd={handleDragEnd}
                  >
                    <SortableContext
                      items={routes.map((r) => r.id)}
                      strategy={verticalListSortingStrategy}
                    >
                      <tbody className="bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-700">
                        {routes.map((route) => (
                          <SortableRouteRow
                            key={route.id}
                            route={route}
                            onClick={(r) => setEditing(r)}
                          />
                        ))}
                      </tbody>
                    </SortableContext>
                  </DndContext>
                </table>
              </div>
            </div>
          )}

          {showCreate && (
            <RouteFormModal
              nextOrder={routes.length > 0 ? Math.max(...routes.map((r) => r.order)) + 1 : 1}
              onSubmit={(data) =>
                createRoute.mutate(data as CreateRouteInput, {
                  onSuccess: () => setShowCreate(false),
                })
              }
              onClose={() => setShowCreate(false)}
              isSubmitting={createRoute.isPending}
            />
          )}

          {editing && (
            <RouteFormModal
              route={editing}
              onSubmit={(data) =>
                updateRoute.mutate(
                  { routeId: editing.id, data: data as UpdateRouteInput },
                  { onSuccess: () => setEditing(null) },
                )
              }
              onClose={() => setEditing(null)}
              isSubmitting={updateRoute.isPending}
              onDelete={() =>
                deleteRoute.mutate(editing.id, {
                  onSuccess: () => setEditing(null),
                })
              }
              isDeleting={deleteRoute.isPending}
              detailUrl={`/admin/games/${id}/routes/${editing.id}`}
            />
          )}
        </>
      )}

      {tab === 'bosses' && (
        <>
          <div className="flex justify-end gap-2 mb-4">
            <button
              onClick={async () => {
                const result = await exportGameBosses(id)
                downloadJson(result.data, result.filename)
              }}
              className="px-4 py-2 text-sm font-medium rounded-md border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-800"
            >
              Export
            </button>
            <button
              onClick={() => setShowCreateBoss(true)}
              className="px-4 py-2 text-sm font-medium rounded-md bg-blue-600 text-white hover:bg-blue-700"
            >
              Add Boss Battle
            </button>
          </div>

          {!bosses || bosses.length === 0 ? (
            <div className="text-center py-8 text-gray-500 dark:text-gray-400 border border-gray-200 dark:border-gray-700 rounded-lg">
              No boss battles yet. Add one to get started.
            </div>
          ) : (
            <div className="border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden">
              <div className="overflow-x-auto">
                <table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
                  <thead className="bg-gray-50 dark:bg-gray-800">
                    <tr>
                      <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider w-16">
                        Order
                      </th>
                      <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
                        Name
                      </th>
                      <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
                        Type
                      </th>
                      <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
                        Location
                      </th>
                      <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider w-20">
                        Lv Cap
                      </th>
                      <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider w-16">
                        Team
                      </th>
                    </tr>
                  </thead>
                  <tbody className="bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-700">
                    {bosses.map((boss) => (
                      <tr
                        key={boss.id}
                        className="hover:bg-gray-50 dark:hover:bg-gray-800 cursor-pointer"
                        onClick={() => setEditingBoss(boss)}
                      >
                        <td className="px-4 py-3 text-sm whitespace-nowrap">{boss.order}</td>
                        <td className="px-4 py-3 text-sm whitespace-nowrap font-medium">{boss.name}</td>
                        <td className="px-4 py-3 text-sm whitespace-nowrap capitalize">
                          {boss.bossType.replace('_', ' ')}
                        </td>
                        <td className="px-4 py-3 text-sm whitespace-nowrap">{boss.location}</td>
                        <td className="px-4 py-3 text-sm whitespace-nowrap">{boss.levelCap}</td>
                        <td className="px-4 py-3 text-sm whitespace-nowrap">{boss.pokemon.length}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </div>
          )}
        </>
      )}

      {/* Boss Battle Modals */}
      {showCreateBoss && (
        <BossBattleFormModal
          routes={routes}
          nextOrder={bosses ? Math.max(0, ...bosses.map((b) => b.order)) + 1 : 1}
          onSubmit={(data) =>
            createBoss.mutate(data as CreateBossBattleInput, {
              onSuccess: () => setShowCreateBoss(false),
            })
          }
          onClose={() => setShowCreateBoss(false)}
          isSubmitting={createBoss.isPending}
        />
      )}

      {editingBoss && (
        <BossBattleFormModal
          boss={editingBoss}
          routes={routes}
          nextOrder={editingBoss.order}
          onSubmit={(data) =>
            updateBoss.mutate(
              { bossId: editingBoss.id, data: data as UpdateBossBattleInput },
              { onSuccess: () => setEditingBoss(null) },
            )
          }
          onClose={() => setEditingBoss(null)}
          isSubmitting={updateBoss.isPending}
          onDelete={() =>
            deleteBoss.mutate(editingBoss.id, {
              onSuccess: () => setEditingBoss(null),
            })
          }
          isDeleting={deleteBoss.isPending}
          onEditTeam={() => {
            setEditingTeam(editingBoss)
            setEditingBoss(null)
          }}
        />
      )}

      {editingTeam && (
        <BossTeamEditorWrapper
          gameId={id}
          boss={editingTeam}
          onClose={() => setEditingTeam(null)}
        />
      )}
    </div>
  )
}

function BossTeamEditorWrapper({
  gameId,
  boss,
  onClose,
}: {
  gameId: number
  boss: BossBattle
  onClose: () => void
}) {
  const setBossTeam = useSetBossTeam(gameId, boss.id)
  return (
    <BossTeamEditor
      boss={boss}
      onSave={(team) =>
        setBossTeam.mutate(team, { onSuccess: onClose })
      }
      onClose={onClose}
      isSaving={setBossTeam.isPending}
    />
  )
}
