import * as routerRedux from "connected-react-router";
import { RouteProps, Route, Router } from "react-router-dom";
import queryString from "querystring";
import React, { lazy, Suspense, PropsWithChildren } from "react";

import { History, createBrowserHistory } from "history";

export { routerRedux };
export * from "react-router-dom";
export * from "history";

export const globalRouteConfig = new Map();

export interface LoadableProps {
  loader: () => Promise<any>;
  loadding?: any;
  routeProps?: any;
  location?: object;
  routerParams?: object;
}

const defaultLoading = "loading...";

export const LoadableComponent = ({
  loader,
  loadding,
  ...props
}: LoadableProps) => {
  const LazyComponent = lazy(loader);

  /**
   * loading 组件的优先级为 自定义 > 全局 > 默认
   */
  const fallback =
    loadding || globalRouteConfig.get("loading") || defaultLoading;

  return (
    <Suspense fallback={fallback}>
      <LazyComponent {...props} />
    </Suspense>
  );
};

export type LazyRouteProps = RouteProps & {
  loader: () => Promise<any>;
  loading?: any;
};

export const LazyRoute = (props: LazyRouteProps) => {
  const { loader, loading } = props;
  const C = (componentProps: any) => {
    const parsed = queryString.parse(window.location.search);
    return (
      <LoadableComponent
        routeProps={componentProps}
        loadding={loading}
        loader={loader}
        location={{
          ...componentProps.location,
          query: parsed
        }}
        routerParams={componentProps.match.params}
      />
    );
  };

  return <Route {...props} component={C} />;
};

export interface RouterProviderProps {
  history?: History;
  loading?: any;
}
export const RouterProvider = (
  props: PropsWithChildren<RouterProviderProps>
) => {
  const { history = createBrowserHistory(), children, loading } = props;
  globalRouteConfig.set("loading", loading);
  return <Router history={history}>{children}</Router>;
};
