import { BlazePlayerType } from '../interfaces';
import { BlazeGlobalEvents } from '../shared/BlazeGlobalEvents';
import {
    BlazeBasePlayerDelegate,
    BlazeBasePlayerDelegateHandler,
    BlazeOnDataLoadStartedParams,
    BlazeOnDataLoadCompleteParams,
    BlazeOnPlayerDidAppearParams,
    BlazeOnPlayerDidDismissParams,
    BlazeOnTriggerCTAParams,
    BlazeOnTriggerPlayerBodyTextLinkParams,
    OnPlayerEventTriggeredParams,
    BlazeOnTriggerCustomActionButtonParams
} from './base-player-delegate';

export interface BlazeOnReadStatusChangedParams {
    playerType: BlazePlayerType;
    sourceId?: string;
    dataSourceStringRepresentation: string;
    isEntireContentRead: boolean;
    itemReadStatus: Record<string, boolean>;
}

export interface BlazePlayerEntryPointDelegate extends BlazeBasePlayerDelegate {
    onReadStatusChanged?: (params: BlazeOnReadStatusChangedParams) => void;
}

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)
        BlazeEntryPointDelegateHelper.onTriggerCustomActionButton(entryPointDelegate?.onTriggerCustomActionButton)
        BlazeEntryPointDelegateHelper.onReadStatusChanged(entryPointDelegate?.onReadStatusChanged)
    }

    private static onDataLoadStarted(
        callback?: (params: BlazeOnDataLoadStartedParams) => void,
    ) {
        const eventName = 'Blaze.onDataLoadStarted'
        if (callback) {
            BlazeGlobalEvents.createEventSubscription(
                eventName,
                (data: any) => {
                    BlazeBasePlayerDelegateHandler.handleDataLoadStarted(data, callback);
                },
            );
        } else {
            BlazeGlobalEvents.cancelEventSubscription(eventName)
        }
    };

    private static onDataLoadComplete(
        callback?: (params: BlazeOnDataLoadCompleteParams) => void,
    ) {
        const eventName = 'Blaze.onDataLoadComplete'
        if (callback) {
            BlazeGlobalEvents.createEventSubscription(
                eventName,
                (data: any) => {
                    BlazeBasePlayerDelegateHandler.handleDataLoadComplete(data, callback);
                },
            );
        } else {
            BlazeGlobalEvents.cancelEventSubscription(eventName)
        }
    }

    private static onPlayerDidAppear(
        callback?: (params: BlazeOnPlayerDidAppearParams) => void,
    ) {
        const eventName = 'Blaze.onPlayerDidAppear'
        if (callback) {
            BlazeGlobalEvents.createEventSubscription(
                eventName,
                (data: any) => {
                    BlazeBasePlayerDelegateHandler.handlePlayerDidAppear(data, callback);
                },
            );
        } else {
            BlazeGlobalEvents.cancelEventSubscription(eventName)
        }
    };

    private static onPlayerDidDismiss(
        callback?: (params: BlazeOnPlayerDidDismissParams) => void,
    ) {
        const eventName = 'Blaze.onPlayerDidDismiss'
        if (callback) {
            BlazeGlobalEvents.createEventSubscription(
                eventName,
                (data: any) => {
                    BlazeBasePlayerDelegateHandler.handlePlayerDidDismiss(data, callback);
                },
            );
        } else {
            BlazeGlobalEvents.cancelEventSubscription(eventName)
        }
    };

    private static onTriggerCTA(
        callback?: (params: BlazeOnTriggerCTAParams) => void,
    ) {
        const eventName = 'Blaze.onTriggerCTA'
        if (callback) {
            BlazeGlobalEvents.createEventSubscription(
                eventName,
                (data: any) => {
                    BlazeBasePlayerDelegateHandler.handleTriggerCTA(data, callback);
                },
            );
        } else {
            BlazeGlobalEvents.cancelEventSubscription(eventName)
        }
    };

    private static onTriggerPlayerBodyTextLink(
        callback?: (params: BlazeOnTriggerPlayerBodyTextLinkParams) => void,
    ) {
        const eventName = 'Blaze.onTriggerPlayerBodyTextLink'
        if (callback) {
            BlazeGlobalEvents.createEventSubscription(
                eventName,
                (data: any) => {
                    BlazeBasePlayerDelegateHandler.handleTriggerPlayerBodyTextLink(data, callback);
                },
            );
        } else {
            BlazeGlobalEvents.cancelEventSubscription(eventName)
        }
    };

    private static onPlayerEventTriggered(
        callback?: (params: OnPlayerEventTriggeredParams) => void,
    ) {
        const eventName = 'Blaze.onPlayerEventTriggered'
        if (callback) {
            BlazeGlobalEvents.createEventSubscription(
                eventName,
                (data: any) => {
                    BlazeBasePlayerDelegateHandler.handlePlayerEventTriggered(data, callback);
                },
            );
        } else {
            BlazeGlobalEvents.cancelEventSubscription(eventName)
        }
    };

    private static onTriggerCustomActionButton(
        callback?: (params: BlazeOnTriggerCustomActionButtonParams) => void,
    ) {
        const eventName = 'Blaze.onTriggerCustomActionButton'
        if (callback) {
            BlazeGlobalEvents.createEventSubscription(
                eventName,
                (data: any) => {
                    BlazeBasePlayerDelegateHandler.handleTriggerCustomActionButton(data, callback);
                },
            );
        } else {
            BlazeGlobalEvents.cancelEventSubscription(eventName)
        }
    };

    private static onReadStatusChanged(
        callback?: (params: BlazeOnReadStatusChangedParams) => void,
    ) {
        const eventName = 'Blaze.onReadStatusChanged'
        if (callback) {
            BlazeGlobalEvents.createEventSubscription(
                eventName,
                (data: any) => {
                    try {
                        const playerType = data['playerType'] as BlazePlayerType;
                        const sourceId = data['sourceId'];
                        const dataSourceStringRepresentation = data['dataSourceStringRepresentation'];
                        const isEntireContentRead = data['isEntireContentRead'];
                        const itemReadStatus = data['itemReadStatus'];
                        callback({
                            playerType,
                            sourceId,
                            dataSourceStringRepresentation,
                            isEntireContentRead,
                            itemReadStatus
                        });
                    } catch (e) {
                        console.error('BlazeEntryPointDelegateHelper.onReadStatusChanged', e);
                    }
                },
            );
        } else {
            BlazeGlobalEvents.cancelEventSubscription(eventName)
        }
    };
}

