import React, { useContext, useEffect, useState } from 'react';

const AUTH_URL = 'https://dev-auth.fiskerdps.com';
const UserContext = React.createContext();

export const UserProvider = ({ children }) => {
  const [fetching, setFetching] = useState(false);
  const [token, setToken] = useState(null);
  const [error, setError] = useState(null);

  useEffect(async () => {
    if (!sessionStorage) return;
    const token = JSON.parse(sessionStorage.getItem("token"));
    if (!token) return;
    const { accessToken: { jwtToken }} = token;
    const resp = await fetch(`${AUTH_URL}/auth/verify`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify({ token: jwtToken })
    });
    const result = await resp.json();
    if (result.authenticated) {
      setToken(token);
    } else {
      console.log(result);
      await signOut();
    }
  }, []);

  const requestSignIn = (username, password) => fetch(`${AUTH_URL}/auth/login`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      username,
      password,
    })
  })
    .then((response) => response.json());
  
  const requestSignUp = (username, password) => fetch(`${AUTH_URL}/auth/register`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      username,
      password,
    })
  })
    .then((response) => response.json());
  
  const signIn = (username, password) => {
    if (!username) throw new Error('Email is required');
    if (!password) throw new Error('Password is required');
    setFetching(true);
    setError(null);
    return requestSignIn(username, password)
      .then((result) => {
        setFetching(false);
        if (result.message) throw new Error(result.message);
        signedIn(result);
        return result;
      })
      .catch((error) => {
        setError(error.message);
        setFetching(false);
        return null;
      });
  };

  const signUp = (username, password, confirmPassword) => {
    if (!username) throw new Error('Email is required');
    if (!password) throw new Error('Password is required');
    if (password !== confirmPassword) throw new Error('Passwords do not match');
    setFetching(true);
    setError(null);
    return requestSignUp(username, password)
      .then((result) => {
        if (result.message) throw new Error(result.message);
      })
      .catch((error) => {
        setError(error.message);
        setFetching(false);
        return null;
      });
  };

  const signOut = async () => {
    setToken(null);
    if (!sessionStorage) return;
    sessionStorage.removeItem("token");
  };

  const signedIn = (token) => {
    setToken(token);
    if (!sessionStorage) return;
    sessionStorage.setItem("token", JSON.stringify(token));
  }

  return (
    <UserContext.Provider value={{
      fetching,
      token,
      error,
      setError,
      signIn,
      signUp,
      signOut,
    }}>
      {children}
    </UserContext.Provider>
  );
};

export const useUserContext = () => useContext(UserContext);
