/**
 * Эти функции будут работать после вызова {@link setGlobalRouter}
 * @packageDocumentation
 */

import { RouteList, Router } from './entities/Router';
import { Route } from './entities/Route';
import { RouterConfig } from './entities/RouterConfig';
import { __testResetHistoryUniqueId } from './entities/State';
import { InfinityPanelIdTitle, PageParams, RouterGenericBase } from './entities/Types';

let globalRouter: any;

/**
 * @ignore
 * @param routes
 * @param config
 */
export function startGlobalRouter<T extends RouterGenericBase = RouterGenericBase>(
  routes: RouteList<T>,
  config: RouterConfig<T> | null = null
): Router<T> {
  if (globalRouter) {
    throw new Error('startGlobalRouter called twice is not allowed');
  }
  globalRouter = new Router<T>(routes, config);
  globalRouter.start();

  return globalRouter;
}

export function getGlobalRouter<T extends RouterGenericBase = RouterGenericBase>(): Router<T> {
  if (!globalRouter) {
    throw new Error('getGlobalRouter called before startGlobalRouter');
  }
  return globalRouter;
}

export function setGlobalRouter<T extends RouterGenericBase = RouterGenericBase>(router: Router<T>) {
  globalRouter = router;
}

/**
 * @ignore
 */
export function dangerousResetGlobalRouterUseForTestOnly() {
  if (globalRouter) {
    globalRouter.stop();
    window.history.pushState(null, '', '');
  }
  if (window.history.state) {
    window.history.pushState(null, '', '');
  }
  __testResetHistoryUniqueId();
  globalRouter = null;
}

export function pushPage<T extends RouterGenericBase = RouterGenericBase>(
  pageId: T['pageId'],
  params: PageParams = {}
) {
  return getGlobalRouter<T>().pushPage(pageId, params);
}

export function replacePage<T extends RouterGenericBase = RouterGenericBase>(
  pageId: T['pageId'],
  params: PageParams = {}
) {
  return getGlobalRouter<T>().replacePage(pageId, params);
}

export function popPage<T extends RouterGenericBase = RouterGenericBase>() {
  return getGlobalRouter<T>().popPage();
}

export function pushModal<T extends RouterGenericBase = RouterGenericBase>(
  modalId: T['modalId'],
  params: PageParams = {}
) {
  return getGlobalRouter<T>().pushModal(modalId, params);
}

export function pushPopup<T extends RouterGenericBase = RouterGenericBase>(
  popupId: T['popupId'],
  params: PageParams = {}
) {
  return getGlobalRouter<T>().pushPopup(popupId, params);
}

export function replaceModal<T extends RouterGenericBase = RouterGenericBase>(
  modalId: T['modalId'],
  params: PageParams = {}
) {
  return getGlobalRouter<T>().replaceModal(modalId, params);
}

export function replacePopout<T extends RouterGenericBase = RouterGenericBase>(
  popupId: string,
  params: PageParams = {}
) {
  return getGlobalRouter<T>().replacePopup(popupId, params);
}

export function popPageTo<T extends RouterGenericBase = RouterGenericBase>(x: number | T['pageId']) {
  return getGlobalRouter<T>().popPageTo(x);
}

/**
 * @deprecated use popPageIfHasOverlay
 */
export function popPageIfModalOrPopup<T extends RouterGenericBase = RouterGenericBase>() {
  return getGlobalRouter<T>().popPageIfModalOrPopup();
}

export function popPageIfHasOverlay<T extends RouterGenericBase = RouterGenericBase>() {
  return getGlobalRouter<T>().popPageIfHasOverlay();
}

export function pushPageAfterPreviews<T extends RouterGenericBase = RouterGenericBase>(
  prevPageId: T['pageId'],
  pageId: T['pageId'],
  params: PageParams = {}
) {
  return getGlobalRouter<T>().pushPageAfterPreviews(prevPageId, pageId, params);
}

/**
 * @deprecated getCurrentStateOrDef
 * @ignore
 */
export function getCurrentRouterState<T extends RouterGenericBase = RouterGenericBase>() {
  return getCurrentStateOrDef<T>();
}

export function getCurrentStateOrDef<T extends RouterGenericBase = RouterGenericBase>() {
  return getGlobalRouter<T>().getCurrentStateOrDef();
}

/**
 * @deprecated getCurrentRouteOrDef
 * @ignore
 */
export function getCurrentRoute<T extends RouterGenericBase = RouterGenericBase>(): Route {
  return getCurrentRouteOrDef<T>();
}

export function getCurrentRouteOrDef<T extends RouterGenericBase = RouterGenericBase>() {
  return getGlobalRouter<T>().getCurrentRouteOrDef();
}

export function isInfinityPanel<PanelIdType extends string = string>(panelId: PanelIdType): boolean {
  // see Route.getPanelId
  return !!panelId && panelId.startsWith('_');
}

export function getInfinityPanelId<PanelIdType extends string = string>(panelId: InfinityPanelIdTitle<PanelIdType>) {
  // see Route.getPanelId
  return (panelId.split('..').shift() || '').replace('_', '');
}
