import { useGameRepairMutation, useGameResetMutation, useGameStartMutation, useGameStopMutation, useGameSwitchPlayerMutation } from '@/hooks/mutations/useGameMutation'
import { useAuth } from '@/hooks/useAuth'
import { useGame, useSetLocationAccuracy, useUpdateGameState } from '@/hooks/useGame'
import { useQueryClient } from '@tanstack/react-query'
import { useRouter } from 'expo-router'
import { useState } from 'react'
import { Button, Dialog, List, MD3Colors, Portal, Snackbar, Surface, Text } from 'react-native-paper'
import { Dropdown } from 'react-native-paper-dropdown'
import { Accuracy } from 'expo-location'

export default function HistoryScreen() {
  const [successVisible, setSuccessVisible] = useState(false)
  const [successMessage, setSuccessMessage] = useState("")
  const [errorVisible, setErrorVisible] = useState(false)
  const [error, setError] = useState([200, ""])

  const router = useRouter()
  const queryClient = useQueryClient()
  const auth = useAuth()
  const game = useGame()
  const updateGameState = useUpdateGameState()
  const setLocationAccuracy = useSetLocationAccuracy()

  const accuracyArrayList = [
    { value: Accuracy.BestForNavigation.toString(), label: "Navigation" },
    { value: Accuracy.Highest.toString(), label: "Plus haute" },
    { value: Accuracy.High.toString(), label: "Haute" },
    { value: Accuracy.Balanced.toString(), label: "Équilibrée" },
    { value: Accuracy.Low.toString(), label: "Basse" },
    { value: Accuracy.Lowest.toString(), label: "Plus basse" },
    { value: 'null', label: "Désactivée" },
  ]

  const gameStartMutation = useGameStartMutation({
    auth,
    updateGameState,
    onPostSuccess: () => {
      setSuccessVisible(true)
      setSuccessMessage("Jeu démarré avec succès")
      queryClient.invalidateQueries({ predicate: (query) => query.queryKey[0] === 'get-game' })
    },
    onError: ({ response, error }) => {
      setErrorVisible(true)
      if (response)
        setError([response.statusCode, response.message])
      else if (error)
        setError([400, error.message])
    },
  })
  const gameStopMutation = useGameStopMutation({
    auth,
    updateGameState,
    onPostSuccess: () => {
      setSuccessVisible(true)
      setSuccessMessage("Jeu arrêté avec succès")
      queryClient.invalidateQueries({ predicate: (query) => query.queryKey[0] === 'get-game' })
    },
    onError: ({ response, error }) => {
      setErrorVisible(true)
      if (response)
        setError([response.statusCode, response.message])
      else if (error)
        setError([400, error.message])
    },
  })
  const gameSwitchMutation = useGameSwitchPlayerMutation({
    auth,
    updateGameState,
    onPostSuccess: () => {
      setSuccessVisible(true)
      setSuccessMessage("Échange de joueuse en course réalisé avec succès")
      queryClient.invalidateQueries({ predicate: (query) => query.queryKey[0] === 'get-game' })
    },
    onError: ({ response, error }) => {
      setErrorVisible(true)
      if (response)
        setError([response.statusCode, response.message])
      else if (error)
        setError([400, error.message])
    },
  })
  const gameRepairMutation = useGameRepairMutation({
    auth,
    onPostSuccess: () => {
      setSuccessVisible(true)
      setSuccessMessage("Réparation du jeu effectuée avec succès")
      queryClient.invalidateQueries({ predicate: (query) => query.queryKey[0] === 'get-game' })
      queryClient.invalidateQueries({ predicate: (query) => query.queryKey[0] === 'get-player' })
      queryClient.invalidateQueries({ predicate: (query) => query.queryKey[0] === 'money-updates' })
    },
    onError: ({ response, error }) => {
      setErrorVisible(true)
      if (response)
        setError([response.statusCode, response.message])
      else if (error)
        setError([400, error.message])
    },
  })
  const gameResetMutation = useGameResetMutation({
    auth,
    updateGameState,
    onPostSuccess: () => {
      setSuccessVisible(true)
      setSuccessMessage("Jeu réinitialisé avec succès")
      queryClient.invalidateQueries()
    },
    onError: ({ response, error }) => {
      setErrorVisible(true)
      if (response)
        setError([response.statusCode, response.message])
      else if (error)
        setError([400, error.message])
    },
  })

  const [resetConfirmVisible, setResetConfirmVisible] = useState(false)

  return (
    <Surface
      style={{ flex: 1 }}>
      <List.Section title={"Paramètres"}>
        <List.Item
            key={"login"}
            title="Connexion au serveur"
            description={auth.loggedIn ? "Vous êtes déjà connecté⋅e" : "Vous n'êtes pas connecté⋅e"}
            right={() => <List.Icon icon="login" />}
            onPress={() => router.navigate('/login')} />
        <List.Item
            key={"location-accuracy"}
            title="Précision de la géolocalisation"
            description="Réglez le niveau de précision de la géolocalisation. Une valeur élevée indique une consommation de batterie accrue."
            right={() => <Dropdown label={"Géolocalisation"} hideMenuHeader={true} options={accuracyArrayList} value={game.settings.locationAccuracy?.toString() ?? 'null'} onSelect={(value) => setLocationAccuracy(!value || value == 'null' ? null : +value)} />} />
      </List.Section>
      <List.Section title={"Gestion du jeu"}>
        <List.Item
            key={"start"}
            title="Démarrer le jeu"
            disabled={game.gameStarted}
            right={() => <List.Icon icon="play" color={!game.gameStarted ? undefined : MD3Colors.secondary30} />}
            onPress={() => gameStartMutation.mutate()} />
        <List.Item
            key={"stop"}
            title="Arrêter le jeu"
            disabled={!game.gameStarted}
            right={() => <List.Icon icon="stop" color={game.gameStarted ? undefined : MD3Colors.secondary30} />}
            onPress={() => gameStopMutation.mutate()} />
        <List.Item
            key={"switch"}
            title="Changer de joueur⋅se en course"
            description="À utiliser après une capture"
            disabled={!game.gameStarted}
            right={() => <List.Icon icon="exit-run" color={game.gameStarted ? undefined : MD3Colors.secondary30} />}
            onPress={() => gameSwitchMutation.mutate()} />
      </List.Section>
      <List.Section title={"Avancé"}>
        <List.Item
            key={"repair"}
            title="Réparer"
            description="Permet de réparer les soldes des joueur⋅ses à partir des défis réalisés et des trains emprunter. À manipuler avec précaution."
            right={() => <List.Icon icon='tools' color={MD3Colors.error60} />}
            onPress={() => gameRepairMutation.mutate()} />
        <List.Item
            key={"reset"}
            title="Réinitialiser les données de jeu"
            description="Permet de détruire toutes les données. À manipuler avec précaution."
            right={() => <List.Icon icon="reload-alert" color={MD3Colors.error60} />}
            onPress={() => setResetConfirmVisible(true)} />
      </List.Section>
      <Snackbar
          key='success-snackbar'
          visible={successVisible}
          icon={'close'}
          onDismiss={() => setSuccessVisible(false)}
          onIconPress={() => setSuccessVisible(false)}>
        <Text variant='bodyMedium' style={{ color: MD3Colors.secondary0 }}>
          {successMessage}
        </Text>
      </Snackbar>
      <Snackbar
          key='error-snackbar'
          visible={errorVisible}
          icon={'close'}
          onDismiss={() => setErrorVisible(false)}
          onIconPress={() => setErrorVisible(false)}>
        <Text variant='bodyMedium' style={{ color: MD3Colors.secondary0 }}>
          Erreur {error[0]} : {error[1]}
        </Text>
      </Snackbar>
      <Portal>
        <Dialog key="confirmReset" visible={resetConfirmVisible} onDismiss={() => setResetConfirmVisible(false)}>
          <Dialog.Title>Confirmer</Dialog.Title>
          <Dialog.Content>
            <Text variant="bodyMedium">
              Cette action va réinitialiser TOUTES les données de jeu : l'historique des positions, les défis réalisés et les trains empruntés.
              Êtes-vous réellement sûr⋅e de vouloir tout supprimer ?
            </Text>
          </Dialog.Content>
          <Dialog.Actions>
            <Button onPress={() => setResetConfirmVisible(false)}>Annuler</Button>
            <Button onPress={() => { setResetConfirmVisible(false); gameResetMutation.mutate() }}>Confirmer</Button>
          </Dialog.Actions>
        </Dialog>
      </Portal>
    </Surface>
  )
}
