import AsyncStorage from '@react-native-async-storage/async-storage';
import {router} from "expo-router";
import {createContext, MutableRefObject, ReactNode, useCallback, useContext, useEffect, useRef, useState} from 'react';
import CryptoES from "crypto-es";

const AuthContext = createContext<{
  signIn: (arg0: string) => void;
  signOut: () => void
  decryptToken: (arg0: string) => Promise<string>
  encryptToken: (arg0: string) => Promise<string>
  token: MutableRefObject<string | null> | null;
  isLoading: boolean
}>({
  signIn: () => null,
  signOut: () => null,
  decryptToken: () => Promise.resolve(''),
  encryptToken: () => Promise.resolve(''),
  token: null,
  isLoading: true
});

// This hook can be used to access the user info.
export function useAuthSession() {
  return useContext(AuthContext);
}

export default function AuthProvider  ({children}:{children: ReactNode}): ReactNode {
  const tokenRef = useRef<string|null>(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    (async ():Promise<void> => {
      const token = await AsyncStorage.getItem('@token');
      tokenRef.current = token || '';
      setIsLoading(false);
    })()
  }, []);

  const decryptToken = (async (token: string) => {
    var C = require("crypto-js");
    var Decrypted = C.AES.decrypt(token, "your password");
    var result = Decrypted.toString(C.enc.Utf8);
    return result
  })

  const encryptToken = (async (token: string) => {
    var result = CryptoES.AES.encrypt(token, "your password").toString();
    return result
  })

  const signIn = useCallback(async (token: string) => {
    await AsyncStorage.setItem('@token', token);
    tokenRef.current = token;
    router.replace('/home')
  }, []);

  const signOut = useCallback(async () => {
    await AsyncStorage.setItem('@token', '');
    tokenRef.current = null;
    router.replace('/');
  }, []);

  return (
    <AuthContext.Provider
      value={{
        signIn,
        signOut,
        token: tokenRef,
        decryptToken,
        encryptToken,
        isLoading
      }}
    >
      {children}
    </AuthContext.Provider>
  );
};