import { findNodeHandle, UIManager } from 'react-native';
import React from 'react';
import { BluestackSDK } from '../BluestackManager';
import { BannerModuleView } from './BannerViewManager';
import type { BannerViewProperties } from './ViewProperties';
import type { BluestackPreference } from '../Preference';
import logger from '../Utils/Logger';

export class BannerView extends React.Component<
    BannerViewProperties,
    { shouldLoadNow: boolean; visible: boolean }
> {
    private _preferenceJSON = '{}';
    private _shouldAutoLoadWhenReady = false;

    constructor(props: BannerViewProperties) {
        super(props);
        this.handleBannerAdFailedToLoad =
            this.handleBannerAdFailedToLoad.bind(this);

        this.state = {
            shouldLoadNow: false,
            visible: true,
        };

        if (this.props.shouldLoadWhenReady != null) {
            this._shouldAutoLoadWhenReady = this.props.shouldLoadWhenReady;
        }

        if (this.props.preference != null && this._preferenceJSON === '{}') {
            this._preferenceJSON = this.props.preference.getPreferenceJSON();
        } else {
            this._preferenceJSON = '{}';
        }
    }

    public load(bsPreference?: BluestackPreference): void {
        if (this._shouldAutoLoadWhenReady) {
            logger.log(
                'Banner load call is not required when shouldLoadWhenReady is true'
            );
        }

        if (bsPreference != null) {
            this._preferenceJSON = bsPreference.getPreferenceJSON();
        } else {
            this._preferenceJSON = '{}';
        }

        this.loadWithPreferenceJSON(this._preferenceJSON);
    }

    private loadWithPreferenceJSON(preferenceJSON: String): void {
        this.setState({ shouldLoadNow: true });

        logger.log('Loading Banner ad with preference: ' + preferenceJSON);
        UIManager.dispatchViewManagerCommand(
            findNodeHandle(this),
            'create' as any,
            [preferenceJSON]
        );
    }

    public destroy(): void {
        UIManager.dispatchViewManagerCommand(
            findNodeHandle(this),
            'destroy' as any,
            undefined
        );
    }

    public toggleRefresh(state: boolean = false): void {
        UIManager.dispatchViewManagerCommand(
            findNodeHandle(this),
            'refresh' as any,
            [state]
        );
    }

    public hide(): void {
        this.setState({
            visible: false,
        });
    }

    public show(): void {
        this.setState({
            visible: true,
        });
    }

    private handleBannerAdFailedToLoad(error: any): void {
        error.persist();

        // If SDK is not initialized
        if (
            error?.nativeEvent?.message === 'SDK is not initialized' &&
            this._shouldAutoLoadWhenReady
        ) {
            // logger.log('handleBannerAdFailedToLoad: ' + error?.nativeEvent?.message);
            let appId: string = this.props.placementId.split('/')[1];
            BluestackSDK.initialize(appId, true)
                .then(() => {
                    this.loadWithPreferenceJSON(this._preferenceJSON);
                })
                .catch(() => {
                    if (this.props.onAdFailedToLoad) {
                        this.props.onAdFailedToLoad(error);
                    }
                });
        } else if (this.props.onAdFailedToLoad) {
            // logger.log('handleBannerAdFailedToLoad: onAdFailedToLoad');
            this.props.onAdFailedToLoad(error);
        }
    }

    public render(): React.ReactNode {
        return (
            <BannerModuleView
                shouldLoadNow={this.state.shouldLoadNow}
                shouldLoadWhenReady={this._shouldAutoLoadWhenReady}
                visible={this.state.visible}
                type={this.props.type}
                placementId={this.props.placementId}
                preference={this._preferenceJSON}
                onBannerAdLoaded={this.props.onAdLoaded}
                onBannerAdFailedToLoad={this.handleBannerAdFailedToLoad}
                onBannerAdRefreshed={this.props.onAdRefreshed}
                onBannerAdFailedToRefresh={this.props.onAdFailedToRefresh}
                onBannerAdClicked={this.props.onAdClicked}
                //reset shouldLoadNow for next call
                onBannerAdLoadCalled={() => {
                    this.setState({ shouldLoadNow: false });
                }}
            />
        );
    }
}
