import { useAuth, useAuthLogin, useAuthLogout } from "@/hooks/useAuth"
import * as SecureStore from "@/utils/SecureStore"
import { useRouter } from "expo-router"
import { useRef, useState } from "react"
import { Platform } from "react-native"
import { Appbar, Button, Dialog, Portal, Surface, Text, TextInput } from "react-native-paper"

export default function Login() {
  const router = useRouter()

  const auth = useAuth()
  const authLogin = useAuthLogin()
  const authLogout = useAuthLogout()

  const isLoggedIn = auth.loggedIn
  const [loggingIn, setLoggingIn] = useState(false)
  const [name, setName] = useState(auth.name ?? "")
  const [password, setPassword] = useState("")
  const [errorDialogVisible, setErrorDialogVisible] = useState(false)
  const [errorTitle, setErrorTitle] = useState("")
  const [errorText, setErrorText] = useState("")

  const loginRef = useRef<any | null>()
  const passwordRef = useRef<any | null>()

  const hideErrorDialog = () => setErrorDialogVisible(false)

  async function login() {
    if (loggingIn)
      return
    setLoggingIn(true)
    const resp = await fetch(`${process.env.EXPO_PUBLIC_TRAINTRAPE_MOI_SERVER}/auth/login/`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ name: name, password: password })
    })
    .then(resp => resp.json())
    .catch(err => {
      setErrorDialogVisible(true)
      setErrorTitle("Erreur")
      setErrorText("Une erreur inconnue est survenue lors de la connexion. Veuillez réessayer plus tard. " + err)
      setLoggingIn(false)
    })
    if (!resp)
      return
    else if (resp.error) {
      setErrorDialogVisible(true)
      setErrorTitle(resp.error)
      setErrorText(resp.message)
      setLoggingIn(false)
      return
    }
    setLoggingIn(false)
    authLogin({ name: name, token: resp.accessToken })
    SecureStore.setItem("apiName", name)
    if (Platform.OS !== "web") {
      // Le stockage navigateur n'est pas sûr, on évite de stocker un mot de passe à l'intérieur
      SecureStore.setItem("apiPassword", password)
    }
    SecureStore.setItem("apiToken", resp.accessToken)
    if (router.canGoBack())
      router.back()
    else
      router.navigate('/')
  }

  async function logout() {
    authLogout()
    await SecureStore.deleteItemAsync("apiName")
    await SecureStore.deleteItemAsync("apiPassword")
    await SecureStore.deleteItemAsync("apiToken")
  }

  return (
    <Surface style={{ flex: 1 }}>
      <Appbar.Header>
        {isLoggedIn && router.canGoBack() ? <Appbar.BackAction onPress={() => router.back()} /> : undefined}
        <Appbar.Content title={"Connexion"} />
        {isLoggedIn ? <Appbar.Action icon={"logout"} onPress={logout} /> : undefined}
      </Appbar.Header>
      <TextInput
          ref={loginRef}
          label="Nom"
          value={name}
          onChangeText={(text) => setName(text)}
          onSubmitEditing={() => passwordRef?.current.focus()}
          style={{ margin: 8 }} />
      <TextInput
          ref={passwordRef}
          label="Mot de passe"
          value={password}
          onChangeText={(text) => setPassword(text)}
          onSubmitEditing={login}
          secureTextEntry={true}
          style={{ margin: 8 }} />
      <Button
          key={loggingIn ? "disabledLoginButton" : "loginButton"}
          onPress={login}
          mode={"contained"}
          icon="login"
          disabled={loggingIn}
          style={{ margin: 8 }}>
        Se connecter
      </Button>
      <Portal>
        <Dialog visible={errorDialogVisible} onDismiss={hideErrorDialog}>
          <Dialog.Title>{errorTitle}</Dialog.Title>
          <Dialog.Content>
            <Text variant="bodyMedium">{errorText}</Text>
          </Dialog.Content>
          <Dialog.Actions>
            <Button onPress={hideErrorDialog}>Ok</Button>
          </Dialog.Actions>
        </Dialog>
      </Portal>
    </Surface>
  )
}
