import {
    BlazeCTAActionType,
    BlazeError,
    BlazePlayerType,
} from '../interfaces';
import { BlazePlayerEvent } from '../interfaces/blaze-player-event';
import { CommonParser } from './common-parser';
import { parseBlazeError } from '../interfaces/blaze-error.interface';

// Shared parameter interfaces for base player delegate
export interface BlazeOnDataLoadStartedParams {
    playerType: BlazePlayerType;
    sourceId: string | undefined;
}

export interface BlazeOnDataLoadCompleteParams {
    playerType: BlazePlayerType;
    sourceId: string | undefined;
    itemsCount: number;
    error: BlazeError | 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;
    playerEvent: BlazePlayerEvent;
}

// Base player delegate interface - shared between Widget and EntryPoint delegates
export interface BlazeBasePlayerDelegate {
    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;
}

// Base player delegate handler - eliminates duplicate code between Widget and EntryPoint delegates
export class BlazeBasePlayerDelegateHandler {
    private static extractPlayerType(data: any): BlazePlayerType {
        return data['playerType'] as BlazePlayerType
    }

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

    static handleDataLoadStarted(
        data: any,
        callback?: (params: BlazeOnDataLoadStartedParams) => void,
    ) {
        if (!callback) return;

        try {
            const playerType = this.extractPlayerType(data);
            const sourceId = data['sourceId'];
            callback({
                playerType,
                sourceId
            });
        } catch (e) {
            console.error('BlazeBasePlayerDelegateHandler.handleDataLoadStarted', e);
        }
    }

    static handleDataLoadComplete(
        data: any,
        callback?: (params: BlazeOnDataLoadCompleteParams) => void,
    ) {
        if (!callback) return;

        try {
            const playerType = this.extractPlayerType(data);
            const sourceId = data['sourceId'];
            const itemsCount = data['itemsCount'];
            const error = parseBlazeError(data['error']);

            callback({
                playerType,
                sourceId,
                itemsCount,
                error
            });
        } catch (e) {
            console.error('BlazeBasePlayerDelegateHandler.handleDataLoadComplete', e);
        }
    }

    static handlePlayerDidAppear(
        data: any,
        callback?: (params: BlazeOnPlayerDidAppearParams) => void,
    ) {
        if (!callback) return;

        try {
            const playerType = this.extractPlayerType(data);
            const sourceId = data['sourceId'];
            callback({
                playerType,
                sourceId
            });
        } catch (e) {
            console.error('BlazeBasePlayerDelegateHandler.handlePlayerDidAppear', e);
        }
    }

    static handlePlayerDidDismiss(
        data: any,
        callback?: (params: BlazeOnPlayerDidDismissParams) => void,
    ) {
        if (!callback) return;

        try {
            const playerType = this.extractPlayerType(data);
            const sourceId = data['sourceId'];
            callback({
                playerType,
                sourceId
            });
        } catch (e) {
            console.error('BlazeBasePlayerDelegateHandler.handlePlayerDidDismiss', e);
        }
    }

    static handleTriggerCTA(
        data: any,
        callback?: (params: BlazeOnTriggerCTAParams) => void,
    ) {
        if (!callback) return;

        try {
            const playerType = this.extractPlayerType(data);
            const sourceId = data['sourceId'];
            const actionType = this.extractCTAActionType(data);
            const actionParam = data['actionParam'];
            callback({
                playerType,
                sourceId,
                actionType,
                actionParam
            });
        } catch (e) {
            console.error('BlazeBasePlayerDelegateHandler.handleTriggerCTA', e);
        }
    }

    static handleTriggerPlayerBodyTextLink(
        data: any,
        callback?: (params: BlazeOnTriggerPlayerBodyTextLinkParams) => void,
    ) {
        if (!callback) return;

        try {
            const playerType = this.extractPlayerType(data);
            const sourceId = data['sourceId'];
            const actionParam = data['actionParam'];
            callback({
                playerType,
                sourceId,
                actionParam
            });
        } catch (e) {
            console.error('BlazeBasePlayerDelegateHandler.handleTriggerPlayerBodyTextLink', e);
        }
    }

    static handlePlayerEventTriggered(
        data: any,
        callback?: (params: OnPlayerEventTriggeredParams) => void,
    ) {
        if (!callback) return;

        try {
            const playerType = this.extractPlayerType(data);
            const sourceId = data['sourceId'];
            const playerEventType = data['playerEventType'];
            const playerEventParams = data['playerEventParams'];

            const result = CommonParser.extractPlayerEvent(playerEventType, playerEventParams);

            if (result != null) {
                callback({
                    playerType,
                    sourceId,
                    playerEvent: result
                });
            }
        } catch (e) {
            console.error('BlazeBasePlayerDelegateHandler.handlePlayerEventTriggered', e);
        }
    }
} 