
import React, { useContext, useEffect } from 'react';
import { Navigate, Route, Routes } from 'react-router';
import { useApi } from './Api';

const AuthContext = React.createContext(null as any);
const LoginContext = React.createContext(null as any);

export function useAuth() {
  return useContext(AuthContext);
}

export function withAuth(Component) {
  return function(props) {
    const [ api ] = useAuth();
    return <Component api={api} {...props} />;
  };
}

export function useLogin() {
  return useContext(LoginContext);
}

export default function AuthProvider({ tokenEndpoint, client_id, client_secret, allowAnonymous = false, children }) {
  const api = useApi(tokenEndpoint, client_id, client_secret, allowAnonymous);

  return <AuthContext.Provider value={api}>
    {children}
  </AuthContext.Provider>;
}

export function Authorized({ children }) {
  const [ _, isLoggedIn ] = useAuth();

  return isLoggedIn ? <Routes>
    <Route path="/logout" element={<Logout />} />
    <Route path="*" element={children} />
  </Routes> : null;
}

export function Logout() {
  const [ api ] = useAuth();
  useEffect(function() {
    api.logout();
  }, [api]);
  return null;
}

export function NotAuthorized({ children }) {
  const [ _, isLoggedIn ] = useAuth();

  if (isLoggedIn)
    return null;

  var a = React.Children.toArray(children);
  var login = a.find(a => (a as any).type === LoginRoute);
  var reset = a.find(a => (a as any).type === ForgotPasswordRoute);
  var registerRoute = a.find(a => (a as any).type === RegisterRoute);

  return <LoginContext.Provider value={{
    login: login && '/login',
    reset: reset && '/reset',
    register: registerRoute && '/register'
  }}>
    <Routes>
      { a.filter(a => a !== login && a !== reset && a !== registerRoute) }
      { login && <Route path="/login" element={(login as any).props.children} /> }
      { reset && <Route path="/reset" element={(reset as any).props.children} /> }
      { registerRoute && <Route path="/register" element={(registerRoute as any).props.children} /> }
      <Route path="*" element={<Navigate to="/login" />} />
    </Routes>
  </LoginContext.Provider>;
}

export function LoginRoute(props) {
  return null;
}

export function ForgotPasswordRoute(props) {
  return null;
}

export function RegisterRoute(props) {
  return null;
}
