/**
 * @ignore
 * @packageDocumentation
 */

import { Page } from './entities/Page';
import { RouteList, Router } from './entities/Router';
import { RouterConfig } from './entities/RouterConfig';
import { PageParams, RouterGenericBase } from './entities/Types';
import { useRouter as useHSRouter } from './hooks/useRouter';
import { useLocation as useHSLocation } from './hooks/useLocation';
import { useParams as useHSParams } from './hooks/useParams';
import { useFirstPageCheck as useHSFirstPageCheck } from './hooks/useFirstPageCheck';
import { useThrottlingLocation as useHSThrottlingLocation } from './hooks/useThrottlingLocation';
import { Location } from './entities/Location';

/**
 * @ignore
 */
export function preventBlinkingBySettingScrollRestoration() {
  if ('scrollRestoration' in window.history && window.history.scrollRestoration === 'auto') {
    window.history.scrollRestoration = 'manual';
  }
}

/**
 * @ignore
 * @param WrappedComponent
 */
export function getDisplayName(WrappedComponent: { displayName?: string; name?: string }) {
  return WrappedComponent.displayName || WrappedComponent.name || 'Component';
}

export function isDesktopSafari(): boolean {
  const ua = window.navigator.userAgent;
  return (
    ua.indexOf('AppleWebKit/') > 0 &&
    ua.indexOf('Safari/') > 0 &&
    !ua.includes('Chrome/') &&
    !ua.includes('Mobile/') &&
    !ua.includes('Android') &&
    !ua.includes('iPhone')
  );
}

export function getTypedRouterElements<T extends RouterGenericBase = RouterGenericBase>(): {
  createRouter: (routes: RouteList<T>, routerConfig?: RouterConfig<T> | null) => Router<T>;
  createPage: (panelId?: T['panelId'], viewId?: T['viewId'], rootId?: T['rootId']) => Page<T>;
  useRouter: (withUpdate?: boolean) => Router<T>;
  useLocation: (withUpdate?: boolean, panelId?: T['panelId']) => Location<T>;
  useFirstPageCheck: (withUpdate?: boolean, panelId?: T['panelId']) => boolean;
  useParams: (panelId?: T['panelId']) => PageParams;
  useThrottlingLocation: () => [Location<T>, () => void];
} {
  const createRouter = (routes: RouteList<T>, routerConfig: RouterConfig<T> | null = null) =>
    new Router<T>(routes, routerConfig);
  const createPage = (panelId?: T['panelId'], viewId?: T['viewId'], rootId?: T['rootId']) =>
    new Page(panelId, viewId, rootId);

  const useRouter = (withUpdate?: boolean) => useHSRouter<T>(withUpdate);
  const useLocation = (withUpdate?: boolean, panelId?: T['panelId']) => useHSLocation<T>(withUpdate, panelId);
  const useParams = (panelId?: T['panelId']) => useHSParams<T>(panelId);
  const useFirstPageCheck = (withUpdate?: boolean, panelId?: T['panelId']) =>
    useHSFirstPageCheck<T>(withUpdate, panelId);
  const useThrottlingLocation = () => useHSThrottlingLocation<T>();

  return {
    createRouter,
    createPage,

    useRouter,
    useLocation,
    useParams,
    useFirstPageCheck,
    useThrottlingLocation,
  };
}
