"use client";

import { useMemo, useEffect, useReducer, useCallback, useState } from 'react';
import { useRouter } from '@/hooks';
import { AuthContext } from './auth-context';
import { paths } from '@/routes/paths';
import { ActionsType, AuthStateType, Types } from './types';
import { users } from '@/shared/_mock';

// ----------------------------------------------------------------------


const STORAGE_KEY = 'accessToken';
// ----------------------------------------------------------------------

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [authenticated, setAuthenticated] = useState(false);
  const initialState: AuthStateType = {
    user: null,
    loading: true,
  };

  const router = useRouter();

  const reducer = (state: AuthStateType, action: ActionsType): AuthStateType => {
    switch (action.type) {
      case Types.INITIAL:
        return { ...state, user: action.payload?.user, loading: false };
      case Types.LOGIN:
        return { ...state, user: action.payload?.user };
      case Types.LOGOUT:
        return { ...state, user: null };
      default:
        return state;
    }
  };

  const [state, dispatch] = useReducer(reducer, initialState);

  const initialize = useCallback(() => {
    const accessToken = localStorage.getItem(STORAGE_KEY);
    if (accessToken) {
      const user = { email: accessToken };
      setAuthenticated(true);
      dispatch({ type: Types.INITIAL, payload: { user } });
    } else {
      setAuthenticated(false);
      dispatch({ type: Types.INITIAL, payload: { user: null } });
    }
  }, []);

  useEffect(() => {
    initialize();
  }, [initialize]);

  const login = useCallback(
    (email: string, password: string) => {
      const user = users.find(u => u.email === email && u.password === password);
      if (user) {
        localStorage.setItem(STORAGE_KEY, email);
        setAuthenticated(true);
        dispatch({ type: Types.LOGIN, payload: { user: { email } } });
        return Promise.resolve();
      } else {
        alert('Invalid email or password');
        throw new Error('Invalid email or password');
      }
    },
    []
  );

  const logout = useCallback(() => {
    localStorage.removeItem(STORAGE_KEY);
    setAuthenticated(false);
    dispatch({ type: Types.LOGOUT });
    router.push(paths.auth.jwt.login);
  }, [router]);

  const memoizedValue = useMemo(
    () => ({
      user: state.user,
      authenticated,
      setAuthenticated,
      login,
      logout,
      loading: state.loading,
    }),
    [state.user, authenticated, login, logout, state.loading]
  );

  return (
    <AuthContext.Provider value={memoizedValue}>
      {children}
    </AuthContext.Provider>
  );
}
