import * as React from 'react';
import { Widget, AppService, WidgetMode, WidgetSize } from '@talentsoft-opensource/integration-widget-component';
import { getWidgetDefinition } from './widget-definition-helper';
import { WidgetDefinitionState } from './widget-definition';
import { HostMock } from './mock-definitions';
import { Proxy } from './proxy';
import { HttpResponse, RequestOptions } from '@talentsoft-opensource/integration-widget-contract';

export interface WidgetToTestProps {
    mode: WidgetMode;
    language: string;
    size: WidgetSize;
}

const defaultMocks = {
    loadData() {
        return Promise.resolve([]);
    },
    requestExternalResource(): Promise<HttpResponse> {
        return Promise.resolve({
            status: 200,
            headers: {},
            body: ""
        });
    },
    getAutoConnectUrl(url: string) {
        return url;
    }
}

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 class WidgetToTest extends React.Component<WidgetToTestProps, WidgetDefinitionState> {
    constructor(props: WidgetToTestProps) {
        super(props);

        this.state = {
            widgetDefinition: getWidgetDefinition(window)
        }
    }

    getContext: AppService["getContext"] = (appid: string) => {
        const {mode, language, size} = this.props;
        const {widgetDefinition} = this.state;

        const title = widgetDefinition ? widgetDefinition.name : 'no name';
        const enlargeable = false;

        return Promise.resolve({size, mode, title, language, enlargeable});
    }

    render() {
        const {widgetDefinition} = this.state;

        if (!widgetDefinition) {
            return null;
        }
        
        const appname = widgetDefinition.name;
        const widget = widgetDefinition.component;
        const appid = "test-demo";


        var hostMock: HostMock = (window as any).exports.default;
        const getAutoConnectUrl = hostMock.getAutoConnectUrl || defaultMocks.getAutoConnectUrl;

        const requestExternalResource = getRequestMethod(hostMock);

        const appService: AppService = {
            getContext: this.getContext,
            on: () => {},
            restoreSize: () => Promise.resolve(),
            expand: () => Promise.resolve(),
            reduce: () => Promise.resolve(),
            openUrlInNewTab: (url: { url: string }) => openUrlInNewTab(getAutoConnectUrl(url.url)),
            openUrlInCurrentTab: (url: { url: string }) => openUrlInCurrentTab(getAutoConnectUrl(url.url)),
            loadData: hostMock.loadData || defaultMocks.loadData,
            getUrlForCurrentContext: () => Promise.resolve(""),
            requestExternalResource: (opts: { requestOptions: RequestOptions }) => requestExternalResource(opts.requestOptions)
        };

        return (
            <Widget
                appid={appid}
                appService={appService}
                bodyComponent={widget}
                name={appname}
                params={hostMock.configuration || {}}
                />
        );
    }
}

function getRequestMethod(hostMock: HostMock) {
    if (hostMock.proxyMode && (!hostMock.secretKey || !hostMock.login)) {
        throw new Error('proxy mode is enabled but secretkey or login is undefined');
    }
    const requestExternalResource = hostMock.proxyMode
        ? new Proxy(hostMock.secretKey!, hostMock.login!).requestExternalResource
        : hostMock.requestExternalResource || defaultMocks.requestExternalResource;
    return requestExternalResource;
}

