import { ThemeProvider } from '@mui/material';
import { Attributes, FC, ReactNode, createContext, useContext, useMemo, useRef, useState } from 'react';
import { useTheme } from '../contexts/ThemeContext';
import ListPage from '../pages/ListPage/ListPage';
import PDFPage from '../pages/PDFPage/PDFPage';

interface IRouterContext {
  navigate?: (route: string, props: (Partial<Record<string, unknown>> & Attributes) | undefined) => void;
  goBack?: () => void;
  getProps?: () => (Partial<Record<string, unknown>> & Attributes) | undefined;
}

export const RouterContext = createContext<IRouterContext>({});

export const useRouter = () => {
  const { navigate, goBack, getProps } = useContext(RouterContext);

  if (navigate && goBack && getProps) {
    return { navigate, goBack, getProps };
  } else {
    throw new Error("Couldn't find context. Is your component inside a Router?");
  }
};

interface IRouterProps {
  globals: (Partial<Record<string, unknown>> & Attributes) | undefined;
}

const Router: FC<IRouterProps> = ({ globals }) => {
  const { theme } = useTheme();

  const routes = useMemo<
    {
      path: string;
      element: ReactNode;
    }[]
  >(
    () => [
      {
        path: '/',
        element: <ListPage />,
      },
      {
        path: '/file',
        element: <PDFPage />,
      },
    ],
    []
  );

  const history = useRef([{ page: routes[0].element, props: globals }]).current;

  const [currentPage, setCurrentPage] = useState<{
    page: ReactNode;
    props: (Partial<Record<string, unknown>> & Attributes) | undefined;
  }>({ page: routes[0].element, props: globals });

  const navigate = (route: string, _props: (Partial<Record<string, unknown>> & Attributes) | undefined) => {
    const page = routes.find((_page) => _page.path === route);
    if (page) {
      history.push({ page: page.element, props: { ..._props, ...globals } });
      setCurrentPage({ page: page.element, props: { ..._props, ...globals } });
      window.dispatchEvent(new Event('resize'));
    } else {
      console.warn('No route registered for', route);
    }
  };
  const goBack = () => {
    if (history.length > 1) {
      history.pop();
      setCurrentPage(history[history.length - 1]);
      window.dispatchEvent(new Event('resize'));
    } else console.warn('Already on root page');
  };

  const getProps = () => currentPage.props;

  return (
    <ThemeProvider theme={theme}>
      <RouterContext.Provider value={{ navigate, goBack, getProps }}>{currentPage.page}</RouterContext.Provider>
    </ThemeProvider>
  );
};

export default Router;
