import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'
import * as adminApi from '../api/admin'
import type {
  CreateGameInput,
  UpdateGameInput,
  CreateRouteInput,
  UpdateRouteInput,
  RouteReorderItem,
  CreatePokemonInput,
  UpdatePokemonInput,
  CreateRouteEncounterInput,
  UpdateRouteEncounterInput,
  CreateEvolutionInput,
  UpdateEvolutionInput,
  CreateBossBattleInput,
  UpdateBossBattleInput,
  BossPokemonInput,
  BossReorderItem,
  UpdateGenlockeInput,
  AddGenlockeLegInput,
} from '../types'

// --- Queries ---

export function usePokemonList(search?: string, limit = 50, offset = 0, type?: string) {
  return useQuery({
    queryKey: ['pokemon', { search, limit, offset, type }],
    queryFn: () => adminApi.listPokemon(search, limit, offset, type),
  })
}

// --- Game Mutations ---

export function useCreateGame() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (data: CreateGameInput) => adminApi.createGame(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['games'] })
      toast.success('Game created')
    },
    onError: (err) => toast.error(`Failed to create game: ${err.message}`),
  })
}

export function useUpdateGame() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: ({ id, data }: { id: number; data: UpdateGameInput }) =>
      adminApi.updateGame(id, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['games'] })
      toast.success('Game updated')
    },
    onError: (err) => toast.error(`Failed to update game: ${err.message}`),
  })
}

export function useDeleteGame() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (id: number) => adminApi.deleteGame(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['games'] })
      toast.success('Game deleted')
    },
    onError: (err) => toast.error(`Failed to delete game: ${err.message}`),
  })
}

// --- Route Mutations ---

export function useCreateRoute(gameId: number) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (data: CreateRouteInput) => adminApi.createRoute(gameId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['games', gameId] })
      qc.invalidateQueries({ queryKey: ['games', gameId, 'routes'] })
      toast.success('Route created')
    },
    onError: (err) => toast.error(`Failed to create route: ${err.message}`),
  })
}

export function useUpdateRoute(gameId: number) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: ({ routeId, data }: { routeId: number; data: UpdateRouteInput }) =>
      adminApi.updateRoute(gameId, routeId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['games', gameId] })
      qc.invalidateQueries({ queryKey: ['games', gameId, 'routes'] })
      toast.success('Route updated')
    },
    onError: (err) => toast.error(`Failed to update route: ${err.message}`),
  })
}

export function useDeleteRoute(gameId: number) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (routeId: number) => adminApi.deleteRoute(gameId, routeId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['games', gameId] })
      qc.invalidateQueries({ queryKey: ['games', gameId, 'routes'] })
      toast.success('Route deleted')
    },
    onError: (err) => toast.error(`Failed to delete route: ${err.message}`),
  })
}

export function useReorderRoutes(gameId: number) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (routes: RouteReorderItem[]) => adminApi.reorderRoutes(gameId, routes),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['games', gameId] })
      qc.invalidateQueries({ queryKey: ['games', gameId, 'routes'] })
      toast.success('Routes reordered')
    },
    onError: (err) => toast.error(`Failed to reorder routes: ${err.message}`),
  })
}

// --- Pokemon Mutations ---

export function useCreatePokemon() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (data: CreatePokemonInput) => adminApi.createPokemon(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['pokemon'] })
      toast.success('Pokemon created')
    },
    onError: (err) => toast.error(`Failed to create pokemon: ${err.message}`),
  })
}

export function useUpdatePokemon() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: ({ id, data }: { id: number; data: UpdatePokemonInput }) =>
      adminApi.updatePokemon(id, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['pokemon'] })
      toast.success('Pokemon updated')
    },
    onError: (err) => toast.error(`Failed to update pokemon: ${err.message}`),
  })
}

export function useDeletePokemon() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (id: number) => adminApi.deletePokemon(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['pokemon'] })
      toast.success('Pokemon deleted')
    },
    onError: (err) => toast.error(`Failed to delete pokemon: ${err.message}`),
  })
}

export function useBulkImportPokemon() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (items: Array<{ pokeapiId: number; nationalDex: number; name: string; types: string[]; spriteUrl?: string | null }>) =>
      adminApi.bulkImportPokemon(items),
    onSuccess: (result) => {
      qc.invalidateQueries({ queryKey: ['pokemon'] })
      toast.success(`Import complete: ${result.created} created, ${result.updated} updated`)
    },
    onError: (err) => toast.error(`Import failed: ${err.message}`),
  })
}

export function useBulkImportEvolutions() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (items: unknown[]) => adminApi.bulkImportEvolutions(items),
    onSuccess: (result) => {
      qc.invalidateQueries({ queryKey: ['evolutions'] })
      toast.success(`Import complete: ${result.created} created, ${result.updated} updated`)
    },
    onError: (err) => toast.error(`Import failed: ${err.message}`),
  })
}

export function useBulkImportRoutes(gameId: number) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (items: unknown[]) => adminApi.bulkImportRoutes(gameId, items),
    onSuccess: (result) => {
      qc.invalidateQueries({ queryKey: ['games', gameId] })
      qc.invalidateQueries({ queryKey: ['games', gameId, 'routes'] })
      toast.success(`Import complete: ${result.created} routes, ${result.updated} encounters`)
    },
    onError: (err) => toast.error(`Import failed: ${err.message}`),
  })
}

export function useBulkImportBosses(gameId: number) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (items: unknown[]) => adminApi.bulkImportBosses(gameId, items),
    onSuccess: (result) => {
      qc.invalidateQueries({ queryKey: ['games', gameId, 'bosses'] })
      toast.success(`Import complete: ${result.created} bosses imported`)
    },
    onError: (err) => toast.error(`Import failed: ${err.message}`),
  })
}

// --- Evolution Queries & Mutations ---

export function useEvolutionList(search?: string, limit = 50, offset = 0, trigger?: string) {
  return useQuery({
    queryKey: ['evolutions', { search, limit, offset, trigger }],
    queryFn: () => adminApi.listEvolutions(search, limit, offset, trigger),
  })
}

export function useCreateEvolution() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (data: CreateEvolutionInput) => adminApi.createEvolution(data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['evolutions'] })
      toast.success('Evolution created')
    },
    onError: (err) => toast.error(`Failed to create evolution: ${err.message}`),
  })
}

export function useUpdateEvolution() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: ({ id, data }: { id: number; data: UpdateEvolutionInput }) =>
      adminApi.updateEvolution(id, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['evolutions'] })
      toast.success('Evolution updated')
    },
    onError: (err) => toast.error(`Failed to update evolution: ${err.message}`),
  })
}

export function useDeleteEvolution() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (id: number) => adminApi.deleteEvolution(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['evolutions'] })
      toast.success('Evolution deleted')
    },
    onError: (err) => toast.error(`Failed to delete evolution: ${err.message}`),
  })
}

// --- Route Encounter Mutations ---

export function useAddRouteEncounter(routeId: number) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (data: CreateRouteEncounterInput) =>
      adminApi.addRouteEncounter(routeId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['routes', routeId, 'pokemon'] })
      toast.success('Encounter added')
    },
    onError: (err) => toast.error(`Failed to add encounter: ${err.message}`),
  })
}

export function useUpdateRouteEncounter(routeId: number) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: ({ encounterId, data }: { encounterId: number; data: UpdateRouteEncounterInput }) =>
      adminApi.updateRouteEncounter(routeId, encounterId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['routes', routeId, 'pokemon'] })
      toast.success('Encounter updated')
    },
    onError: (err) => toast.error(`Failed to update encounter: ${err.message}`),
  })
}

export function useRemoveRouteEncounter(routeId: number) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (encounterId: number) =>
      adminApi.removeRouteEncounter(routeId, encounterId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['routes', routeId, 'pokemon'] })
      toast.success('Encounter removed')
    },
    onError: (err) => toast.error(`Failed to remove encounter: ${err.message}`),
  })
}

// --- Boss Battle Mutations ---

export function useCreateBossBattle(gameId: number) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (data: CreateBossBattleInput) => adminApi.createBossBattle(gameId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['games', gameId, 'bosses'] })
      toast.success('Boss battle created')
    },
    onError: (err) => toast.error(`Failed to create boss battle: ${err.message}`),
  })
}

export function useUpdateBossBattle(gameId: number) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: ({ bossId, data }: { bossId: number; data: UpdateBossBattleInput }) =>
      adminApi.updateBossBattle(gameId, bossId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['games', gameId, 'bosses'] })
      toast.success('Boss battle updated')
    },
    onError: (err) => toast.error(`Failed to update boss battle: ${err.message}`),
  })
}

export function useReorderBosses(gameId: number) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (bosses: BossReorderItem[]) => adminApi.reorderBosses(gameId, bosses),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['games', gameId, 'bosses'] })
      toast.success('Bosses reordered')
    },
    onError: (err) => toast.error(`Failed to reorder bosses: ${err.message}`),
  })
}

export function useDeleteBossBattle(gameId: number) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (bossId: number) => adminApi.deleteBossBattle(gameId, bossId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['games', gameId, 'bosses'] })
      toast.success('Boss battle deleted')
    },
    onError: (err) => toast.error(`Failed to delete boss battle: ${err.message}`),
  })
}

export function useSetBossTeam(gameId: number, bossId: number) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (team: BossPokemonInput[]) => adminApi.setBossTeam(gameId, bossId, team),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['games', gameId, 'bosses'] })
      toast.success('Boss team updated')
    },
    onError: (err) => toast.error(`Failed to update boss team: ${err.message}`),
  })
}

// --- Genlocke Mutations ---

export function useUpdateGenlocke() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: ({ id, data }: { id: number; data: UpdateGenlockeInput }) =>
      adminApi.updateGenlocke(id, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['genlockes'] })
      toast.success('Genlocke updated')
    },
    onError: (err) => toast.error(`Failed to update genlocke: ${err.message}`),
  })
}

export function useDeleteGenlocke() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (id: number) => adminApi.deleteGenlocke(id),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['genlockes'] })
      toast.success('Genlocke deleted')
    },
    onError: (err) => toast.error(`Failed to delete genlocke: ${err.message}`),
  })
}

export function useAddGenlockeLeg(genlockeId: number) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (data: AddGenlockeLegInput) => adminApi.addGenlockeLeg(genlockeId, data),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['genlockes'] })
      qc.invalidateQueries({ queryKey: ['genlockes', genlockeId] })
      toast.success('Leg added')
    },
    onError: (err) => toast.error(`Failed to add leg: ${err.message}`),
  })
}

export function useDeleteGenlockeLeg(genlockeId: number) {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (legId: number) => adminApi.deleteGenlockeLeg(genlockeId, legId),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['genlockes'] })
      qc.invalidateQueries({ queryKey: ['genlockes', genlockeId] })
      toast.success('Leg removed')
    },
    onError: (err) => toast.error(`Failed to remove leg: ${err.message}`),
  })
}
