import {
    BlazeCTAActionType,
    BlazePlayerType,
} from '../interfaces';
import { BlazePlayerEvent, BlazePlayerEventType } from '../interfaces/blaze-player-event';
import { RegisterGlobalEvents } from './RegisterGlobalEvents';
import { CommonParser } from './common-parser';

export interface BlazePlayerEntryPointDelegate {
    onDataLoadStarted?: (params: BlazeOnDataLoadStartedParams) => void;
    onDataLoadComplete?: (params: BlazeOnDataLoadCompleteParams) => void;
    onPlayerDidAppear?: (params: BlazeOnPlayerDidAppearParams) => void;
    onPlayerDidDismiss?: (params: BlazeOnPlayerDidDismissParams) => void;
    onTriggerCTA?: (params: BlazeOnTriggerCTAParams) => void;
    onTriggerPlayerBodyTextLink?: (params: BlazeOnTriggerPlayerBodyTextLinkParams) => void;
    onPlayerEventTriggered?: (params: OnPlayerEventTriggeredParams) => void;
}

export interface BlazeOnDataLoadStartedParams {
    playerType: BlazePlayerType;
    sourceId: string | undefined;
}

export interface BlazeOnDataLoadCompleteParams {
    playerType: BlazePlayerType;
    sourceId: string | undefined;
    itemsCount: number;
    error: string | undefined;
}

export interface BlazeOnPlayerDidAppearParams {
    playerType: BlazePlayerType;
    sourceId: string | undefined;
}

export interface BlazeOnPlayerDidDismissParams {
    playerType: BlazePlayerType;
    sourceId: string | undefined;
}

export interface BlazeOnTriggerCTAParams {
    playerType: BlazePlayerType;
    sourceId: string | undefined;
    actionType: BlazeCTAActionType;
    actionParam: string;
}

export interface BlazeOnTriggerPlayerBodyTextLinkParams {
    playerType: BlazePlayerType;
    sourceId: string | undefined;
    actionParam: string;
}

export interface OnPlayerEventTriggeredParams {
    playerType: BlazePlayerType;
    sourceId: string | undefined;
    event: BlazePlayerEvent;
}

export class BlazeEntryPointDelegateHelper {

    static registerEntryPointDelegate(entryPointDelegate?: BlazePlayerEntryPointDelegate | null) {
        BlazeEntryPointDelegateHelper.onDataLoadStarted(entryPointDelegate?.onDataLoadStarted)
        BlazeEntryPointDelegateHelper.onDataLoadComplete(entryPointDelegate?.onDataLoadComplete)
        BlazeEntryPointDelegateHelper.onPlayerDidAppear(entryPointDelegate?.onPlayerDidAppear)
        BlazeEntryPointDelegateHelper.onPlayerDidDismiss(entryPointDelegate?.onPlayerDidDismiss)
        BlazeEntryPointDelegateHelper.onTriggerCTA(entryPointDelegate?.onTriggerCTA)
        BlazeEntryPointDelegateHelper.onTriggerPlayerBodyTextLink(entryPointDelegate?.onTriggerPlayerBodyTextLink)
        BlazeEntryPointDelegateHelper.onPlayerEventTriggered(entryPointDelegate?.onPlayerEventTriggered)
    }

    private static onDataLoadStarted(
        callback?: (params: BlazeOnDataLoadStartedParams) => void,
    ) {
        const eventName = 'Blaze.onDataLoadStarted'
        if (callback) {
            RegisterGlobalEvents.createEventSubscription(
                eventName,
                data => {
                    try {
                        const playerType = BlazeEntryPointDelegateHelper.extractPlayerType(data);
                        const sourceId = data['sourceId'];
                        callback({
                            playerType,
                            sourceId
                        });
                    } catch (e) {
                        console.error('onDataLoadStarted', e);
                    }
                },
            );
        } else {
            RegisterGlobalEvents.cancelEventSubscription(eventName)
        }
    };

    private static onDataLoadComplete(
        callback?: (params: BlazeOnDataLoadCompleteParams) => void,
    ) {
        const eventName = 'Blaze.onDataLoadComplete'
        if (callback) {
            RegisterGlobalEvents.createEventSubscription(
                eventName,
                data => {
                    try {
                        const playerType = BlazeEntryPointDelegateHelper.extractPlayerType(data);
                        const sourceId = data['sourceId'];
                        const itemsCount = data['itemsCount'];
                        const error = data['error'];

                        callback({
                            playerType,
                            sourceId,
                            itemsCount,
                            error
                        });
                    } catch (e) {
                        console.error('onDataLoadComplete', e);
                    }
                },
            );
        } else {
            RegisterGlobalEvents.cancelEventSubscription(eventName)
        }
    }

    private static onPlayerDidAppear(
        callback?: (params: BlazeOnPlayerDidAppearParams) => void,
    ) {
        const eventName = 'Blaze.onPlayerDidAppear'
        if (callback) {
            RegisterGlobalEvents.createEventSubscription(
                eventName,
                data => {
                    try {
                        const playerType = BlazeEntryPointDelegateHelper.extractPlayerType(data);
                        const sourceId = data['sourceId'];
                        callback({
                            playerType,
                            sourceId
                        });
                    } catch (e) {
                        console.error('onPlayerDidAppear', e);
                    }
                },
            );
        } else {
            RegisterGlobalEvents.cancelEventSubscription(eventName)
        }
    };

    private static onPlayerDidDismiss(
        callback?: (params: BlazeOnPlayerDidDismissParams) => void,
    ) {
        const eventName = 'Blaze.onPlayerDidDismiss'
        if (callback) {
            RegisterGlobalEvents.createEventSubscription(
                eventName,
                data => {
                    try {
                        const playerType = BlazeEntryPointDelegateHelper.extractPlayerType(data);
                        const sourceId = data['sourceId'];
                        callback({
                            playerType,
                            sourceId
                        });
                    } catch (e) {
                        console.error('onPlayerDidDismiss', e);
                    }
                },
            );
        } else {
            RegisterGlobalEvents.cancelEventSubscription(eventName)
        }
    };

    private static onTriggerCTA(
        callback?: (params: BlazeOnTriggerCTAParams) => void,
    ) {
        const eventName = 'Blaze.onTriggerCTA'
        if (callback) {
            RegisterGlobalEvents.createEventSubscription(
                eventName,
                data => {
                    try {
                        const playerType = BlazeEntryPointDelegateHelper.extractPlayerType(data);
                        const sourceId = data['sourceId'];
                        const actionType = BlazeEntryPointDelegateHelper.extractCTAActionType(data);
                        const actionParam = data['actionParam'];
                        callback({
                            playerType,
                            sourceId,
                            actionType,
                            actionParam
                        });
                    } catch (e) {
                        console.error('onTriggerCTA', e);
                    }
                },
            );
        } else {
            RegisterGlobalEvents.cancelEventSubscription(eventName)
        }
    };

    private static onTriggerPlayerBodyTextLink(
        callback?: (params: BlazeOnTriggerPlayerBodyTextLinkParams) => void,
    ) {
        const eventName = 'Blaze.onTriggerPlayerBodyTextLink'
        if (callback) {
            RegisterGlobalEvents.createEventSubscription(
                eventName,
                data => {
                    try {
                        const playerType = BlazeEntryPointDelegateHelper.extractPlayerType(data);
                        const sourceId = data['sourceId'];
                        const actionParam = data['actionParam'];
                        callback({
                            playerType,
                            sourceId,
                            actionParam
                        });
                    } catch (e) {
                        console.error('onTriggerPlayerBodyTextLink', e);
                    }
                },
            );
        } else {
            RegisterGlobalEvents.cancelEventSubscription(eventName)
        }
    };

    private static onPlayerEventTriggered(
        callback?: (params: OnPlayerEventTriggeredParams) => void,
    ) {
        const eventName = 'Blaze.onPlayerEventTriggered'
        if (callback) {
            RegisterGlobalEvents.createEventSubscription(
                eventName,
                data => {
                    try {
                        const playerType = BlazeEntryPointDelegateHelper.extractPlayerType(data);
                        const sourceId = data['sourceId'];
                        const playerEventType = data['playerEventType'] as BlazePlayerEventType
                        const playerEventParams = data['playerEventParams'];

                        const result = CommonParser.extractPlayerEvent(playerEventType, playerEventParams)

                        if (result != null) {
                            callback({
                                playerType: playerType,
                                sourceId: sourceId,
                                event: result
                            });
                        }
                    } catch (e) {
                        console.error('onPlayerEventTriggered', e);
                    }
                },
            );
        } else {
            RegisterGlobalEvents.cancelEventSubscription(eventName)
        }
    };

    private static extractPlayerType(data: any): BlazePlayerType {
        return data['playerType'] as BlazePlayerType
    }


    private static extractCTAActionType(data: any): BlazeCTAActionType {
        return data['actionType'] as BlazeCTAActionType
    }

}

