import * as I from "../types/types";
import axios, { AxiosResponse } from 'axios';
const xml2jsParser = require('xml2js').parseString;
import * as UI from "./ui";
import { config } from "./config";
import * as Cart from "./cart";
import Utils from './utils'

// rework try/catch ?
export function sendMessage(inData: I.Message, inTo: string): void {
    if (inTo === "parent")
        window.parent.postMessage(JSON.stringify(inData), '*');
    else {
        const child: any = document.getElementById(inTo);

        if (child !== null && child.contentWindow !== null)
            child.contentWindow.postMessage(JSON.stringify(inData), "*");
    }
}

export function listenToMessages(inHandler: CallableFunction): void {
    window.addEventListener('message', (e: any): void => {
        inHandler(e);
    });
}

export function sendXML(inUrl: string, inTo: string, inEvent: string, inFrom: string, inDate: number = Date.now()): void {
    getXMLPromise(inUrl).then((result: unknown): void => {
        const message: I.Message = {
            date: inDate,
            from: inFrom,
            message: result,
            event: inEvent
        }
        sendMessage(message, inTo);
    })
        .catch(function (err) {
            console.error(err);
        });
}

export function sendEventToChild(inEvent: string): void {
    const message: I.Message = {
        message: null,
        from: "parent",
        event: inEvent,
        date: Date.now()
    };
    sendMessage(message, "iframeSeatmap");
}

export function sendEventToParent(inEvent: string): void {
    const message: I.Message = {
        message: null,
        from: "child",
        event: inEvent,
        date: Date.now()
    };
    sendMessage(message, "parent");
}

export function needSeatmapXML(inID: string): void {
    const message: I.Message = {
        message: inID,
        from: "child",
        event: "child_needSeatmapXML",
        date: Date.now()
    };
    sendMessage(message, "parent");
}

export function cancelCheckout(inUrl: string): void {
    // use fetch instead of axios because of 302 redirect
    // see https://github.com/axios/axios/issues/932
    fetch(inUrl, {
        redirect: "manual"
    })
        .then(() => Utils.consoleLog(`${inUrl} canceled`))
        .catch((error) => Utils.consoleLog(error));
}

export function isValidSeatSelection(): void {
    jQuery("#modalCart-overlay").hide();

    if (!config.state.selectedSeatsArr.length)
        return;

    UI.adjustUIToLoading();
    const url: string | undefined = Cart.generateCheckoutUrl();

    const message: I.Message = {
        message: {
            url: url,
        },
        from: "child",
        event: "child_needCheckoutResponse",
        date: Date.now()
    };

    sendMessage(message, "parent");
}

function getXMLPromise(inUrl: string): Promise<unknown> {
    return axios.get(inUrl)
        .then((response: void | AxiosResponse<any>) => {
            return new Promise((resolve: any, reject: any) => {
                const AxiosResponse = <AxiosResponse>response;
                if (AxiosResponse.status === 200 && AxiosResponse.headers["content-type"] === "text/xml;charset=utf-8") {
                    xml2jsParser(AxiosResponse.data,
                        { normalizeTags: true, normalize: true, mergeAttrs: true },
                        (err: any, result: any) => {
                            if (err)
                                reject(err);
                            else
                                resolve(result);
                        });
                }
            });
        })
        .catch((error) => Utils.consoleLog(error));
}