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;
}

export interface BlazeOnDataLoadCompleteParams {
    playerType: BlazePlayerType;
    sourceId?: string;
    itemsCount: number;
    error?: BlazeError;
}

export interface BlazeOnPlayerDidAppearParams {
    playerType: BlazePlayerType;
    sourceId?: string;
}

export interface BlazeOnPlayerDidDismissParams {
    playerType: BlazePlayerType;
    sourceId?: string;
}

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

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

export interface OnPlayerEventTriggeredParams {
    playerType: BlazePlayerType;
    sourceId?: string;
    playerEvent: BlazePlayerEvent;
}

export interface BlazeOnTriggerCustomActionButtonParams {
    playerType: BlazePlayerType;
    sourceId?: string;
    buttonId: string;
    buttonName: string;
    appMetadata?: Record<string, any>;
}

// 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;
    onTriggerCustomActionButton?: (params: BlazeOnTriggerCustomActionButtonParams) => 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);
        }
    }

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

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