import { 
  createContext, 
  useContext, 
  useState, 
  ReactNode, 
  Dispatch, 
  SetStateAction, 
  useEffect 
} from 'react'
import { trpc } from '@/utils/trpc';
import { User } from '@prisma/client';

interface UserContextProps {
  session_valid: boolean;
  userData: User;
  userSessionDataLoading: boolean;
  setUserData: (userData: User) => void;
  setSessionValid: (session_valid: boolean) => void;
  handleLogout: () => void;
}

const UserContext = createContext<UserContextProps>({
  session_valid: false,
  userData: {} as User,
  userSessionDataLoading: true,
  setUserData: () => {},
  setSessionValid: () => {},
  handleLogout: () => {},
});

export function useUserContext() {
  const context = useContext(UserContext);
  if (!context) {
    throw new Error('useUserContext must be used within a UserContextProvider');
  }
  return context;
}

export function UserContextProvider({ children }: { children: ReactNode }) {
  const [userState, setUserState] = useState({
    session_valid: false,
    userData: {} as User,
    userSessionDataLoading: true,
    setUserData: (data: User) => setUserState(prevState => ({ ...prevState, userData: data })),
    setSessionValid: (isValid: boolean) => setUserState(prevState => ({ ...prevState, session_valid: isValid })),
  })

  const { data, error } = trpc.auth.getSession.useQuery()

  useEffect(() => {
    if (error) {
      setUserState(prevState => ({
        ...prevState,
        session_valid: false,
        userData: {} as User,
        userSessionDataLoading: false,
      }));
    }

    if (data) {
      setUserState(prevState => ({
        ...prevState,
        session_valid: data.session_valid,
        userData: data.user,
        userSessionDataLoading: false,
      }));
    }
  }, [data]);

  const handleLogout = async () => {
    setUserState(prevState => ({
      ...prevState,
      session_valid: false,
      userData: {} as User,
      userSessionDataLoading: false,
    }));
  }

  return (
    <UserContext.Provider value={{ ...userState, handleLogout }}>
      {children}
    </UserContext.Provider>
  )
}