import {platformBrowserDynamic} from "@angular/platform-browser-dynamic";
import {MfeConfigurationProvider} from "./modules/mfe/provider/mfe-configuration.provider";
import {NgModuleRef} from "@angular/core";

let childEventHandlerFromContainer = null;

export type ChildEventType = 'navigate' | 'token-request'
export type ParentEventType = 'navigate';

export function fireMfeEventToContainer(eventType: ChildEventType, eventData: any): Promise<any> {
  if (typeof childEventHandlerFromContainer === 'function') {
    return childEventHandlerFromContainer(eventType, eventData);
  }
  else {
    throw new Error(
        'Event fired from child MFE to container before being bootstrapped as MFE App',
    );
  }
}

export function bootstrapMfeApp(createApp: () => Promise<NgModuleRef<unknown> | void>) {
  function mount(
      element: HTMLElement,
      settings: {
        standalone: boolean,
        useShadowDom?: boolean,
        containerBaseUrl?: string,
        componentBaseUrl?: string,
        startUrl: string,
        childEventHandler?: any,
        params?: any
      } = {
        standalone: false,
        startUrl: '/mfe/business-metrics'
      },
  ) {
    let containerBaseUrl = settings.containerBaseUrl || ''; // префикс ресурса
    let startUrl = settings.startUrl || ''; // ресурс хост-приложения
    MfeConfigurationProvider.setPageBaseUrl(joinPath(containerBaseUrl, startUrl));

    element.appendChild(createContainerForBootstrap())

    childEventHandlerFromContainer = settings.childEventHandler;

    createApp();
    return {
      parentEventHandler(eventType: ParentEventType, url: string) {
      },
      unmount() {
        console.log("Unmounting business-metrics application");
        platformBrowserDynamic().destroy();
      },
    }
  }

  return {
    mount,
  };

}

function createContainerForBootstrap(): HTMLElement {
  let mfeBootstrapContainer = document.createElement('div');
  mfeBootstrapContainer.setAttribute(MfeConfigurationProvider.BASE_COMPONENT_ATTRIBUTE, '');
  return mfeBootstrapContainer;
}

export function joinPath(...paths: string[]): string {
  return '/' + paths
      .filter(path => path)
      .map(path => path.endsWith('/') ? path.substring(0, path.length - 1) : path)
      .map(path => path.startsWith('/') ? path.substring(1, path.length) : path)
      .join('/')
}
