import {
    RequestOptionsWithPartner,
    PartnerUrl,
    AppHeaderActionConfiguration,
    WidgetMode,
    WidgetContext
} from "@talentsoft-opensource/integration-widget-component";
import {
    HttpResponse,
    DashboardScope,
    RequestOptions,
    GenericHttpResponse
} from "@talentsoft-opensource/integration-widget-contract";
import { errorResources } from "./error-resources";
import { HostMock } from "../../contracts/host-mock-contract";
import { ProxyClient } from "./proxy-client";
import {
    IWidgetCollectionController,
    getTransportConfig,
    WidgetCollectionController
} from "./widget-collection-controller";
import {
    HostPeer,
    PostMessageBusTransport,
    setLogLevel
} from "@talentsoft-opensource/integration-com-layer";
import { TopicMap } from "@talentsoft-opensource/integration-com-layer/dist/src/peers/contracts";

setLogLevel("trace");

export interface HostSettings {
    language: string;
    mode: WidgetMode;
}

export function getHostMock(): HostMock {
    return (window as any)["integration/hostmock"].hostmock;
}

export function makeHostEvents() {
    return {
        onEditModeChanged() {},
        onLanguageChanged() {},
        onSizeChangedToMinimized() {},
        onSizeChangedToNormal() {},
        onSizeChangedToEnlarged() {},
        onSetWidgetAsEnlargeable() {}
    };
}

export type HostEventApi = ReturnType<typeof makeHostEvents>;

function openUrlInNewTab(url: string) {
    const win = window.open(url, "_blank");
    if (win) {
        win.focus();
    }
    return Promise.resolve();
}

function openUrlInCurrentTab(url: string) {
    top.location.href = url;
    return Promise.resolve();
}

export function makeHostAPI(
    settings: HostSettings,
    widgetsController: IWidgetCollectionController,
    hostPeer: () => HostPeer<HostEventApi>
) {
    const hostMock = getHostMock();
    const proxyClient = new ProxyClient(
        hostMock.secretKey!,
        hostMock.login!,
        hostMock.securityMode || "directconnect"
    );

    return {
        getContext(widgetId: string): WidgetContext {
            const widget = widgetsController.getWidget(widgetId);
            return {
                currentUser: {
                    employeeNumber: hostMock.employeeNumber || "",
                    login: hostMock.login || ""
                },
                language: settings.language,
                errorMessages: errorResources[settings.language],
                size: widget.size,
                mode: settings.mode,
                enlargeable: widget.enlargeable,
                title: widget.title,
                scope: DashboardScope.Me
            };
        },

        expand(widgetId: string) {
            widgetsController.expand(widgetId);
        },

        reduce(widgetId: string) {
            widgetsController.reduce(widgetId);
        },

        restoreSize(widgetId: string) {
            widgetsController.restoreSize(widgetId);
        },

        async requestExternalResource(
            options: RequestOptionsWithPartner
        ): Promise<HttpResponse> {
            return hostMock.proxyMode
                ? proxyClient.requestExternalResource(options.requestOptions)
                : hostMock.requestExternalResource!(options.requestOptions);
        },

        async requestInternalResource(
            options: RequestOptions
        ): Promise<HttpResponse> {
            return hostMock.requestInternalResource!(options);
        },

        async requestInternalResourceAsArrayBuffer(
            options: RequestOptions
        ): Promise<GenericHttpResponse<ArrayBuffer>> {
            return hostMock.requestInternalResourceAsArrayBuffer!(options);
        },

        async downloadExternalResource(options: RequestOptionsWithPartner) {
            proxyClient.downloadExternalResource(options.requestOptions);
        },

        call() {},

        getPreloadedResources(language: string) {
            const getPreloadedResources = hostMock.getPreloadedResources;
            return getPreloadedResources ? getPreloadedResources(language) : {};
        },

        async openUrlInNewTab(url: PartnerUrl) {
            const urlWithAuth = proxyClient.getAutoConnectUrl(url.url);
            openUrlInNewTab(urlWithAuth);
        },

        openUrlInCurrentTab(url: PartnerUrl) {
            const urlWithAuth = proxyClient.getAutoConnectUrl(url.url);
            openUrlInCurrentTab(urlWithAuth);
        },

        setHeaderActionConfiguration(appConfig: AppHeaderActionConfiguration) {
            widgetsController.setEnlargeable(
                appConfig.appid,
                appConfig.configuration.enlargeable || false
            );
            if (appConfig.configuration.enlargeable) {
                hostPeer().events.onSetWidgetAsEnlargeable.notify(
                    appConfig.appid
                );
            }
        }
    };
}

export function initHost(initialLanguage: string, initialMode: WidgetMode) {
    const widgetController = new WidgetCollectionController();
    const events = makeHostEvents();
    const hostApi = makeHostAPI(
        { language: initialLanguage, mode: initialMode },
        widgetController,
        () => hostPeer
    );

    const hostConfig = getTransportConfig("host");
    const transport = new PostMessageBusTransport(hostConfig);
    transport.init();
    const hostPeer = HostPeer.new(
        transport,
        events,
        (hostApi as any) as TopicMap
    );
    widgetController.hostPeer = hostPeer;

    console.log("com server initialized");
    return { widgetController, hostPeer };
}
