import {
    IBlazeAnalytics,
    BlazeError
} from '../interfaces';
import { BlazeGlobalEvents } from '../shared/BlazeGlobalEvents';
import { parseBlazeError } from '../interfaces/blaze-error.interface';

export interface BlazeGlobalDelegate {
    onEventTriggered?: (params: BlazeOnEventTriggeredParams) => void
    onErrorThrown?: (params: BlazeOnErrorThrownParams) => void
}

export interface BlazeOnEventTriggeredParams {
    event: IBlazeAnalytics;
}

export interface BlazeOnErrorThrownParams {
    error: BlazeError;
}

export class BlazeGlobalDelegateHelper {

    static registerGlobalDelegate(globalDelegate?: BlazeGlobalDelegate | null) {
        BlazeGlobalDelegateHelper.onEventTriggered(globalDelegate?.onEventTriggered)
        BlazeGlobalDelegateHelper.onErrorThrown(globalDelegate?.onErrorThrown)
    }

    private static onEventTriggered(
        callback?: (params: BlazeOnEventTriggeredParams) => void,
    ) {
        const eventName = 'Blaze.onEventTriggered'
        if (callback) {
            BlazeGlobalEvents.createEventSubscription(
                eventName,
                (data: any) => {
                    try {
                        if (data) {
                            const parsed = JSON.parse(data['eventData']);
                            callback({
                                event: parsed as IBlazeAnalytics
                            });
                        } else {
                            console.error('onEventTriggered: was called with no data.');
                        }
                    } catch (e) {
                        console.error('onEventTriggered', e);
                    }
                },
            );
        } else {
            BlazeGlobalEvents.cancelEventSubscription(eventName)
        }

    }

    private static onErrorThrown(
        callback?: (params: BlazeOnErrorThrownParams) => void,
    ) {
        const eventName = 'Blaze.onErrorThrown'
        if (callback) {
            BlazeGlobalEvents.createEventSubscription(
                eventName,
                (data: any) => {
                    try {
                        const error = parseBlazeError(data['error']);
                        if (error) {
                            callback({
                                error: error
                            })
                        } else {
                            console.error('onErrorThrown: failed to parse error from data:', data);
                        }
                    } catch (e) {
                        console.error('onErrorThrown', e);
                    }
                },
            );
        } else {
            BlazeGlobalEvents.cancelEventSubscription(eventName)
        }
    }

}