import React, { useState, useCallback } from 'react';
import {
    Platform,
    requireNativeComponent,
    StyleProp,
    UIManager,
    ViewStyle,
} from 'react-native';

import type { BannerAdType } from './AdType';

interface NativeBannerViewProps {
    placementId: string;
    shouldLoadWhenReady: boolean;
    preference: string | undefined;
    adSize: string;
    visible: boolean;
    style: StyleProp<ViewStyle>;
    onAdLoaded?: Function;
    onAdFailedToLoad?: Function;
    onAdRefreshed?: Function;
    onAdFailedToRefresh?: Function;
    onAdClicked?: Function;
}

interface BannerViewProps {
    visible: boolean;
    type: BannerAdType;
    shouldLoadWhenReady: boolean;
    placementId: string;
    preference: string | undefined;
    onBannerAdLoaded?: Function;
    onBannerAdFailedToLoad?: Function;
    onBannerAdRefreshed?: Function;
    onBannerAdFailedToRefresh?: Function;
    onBannerAdClicked?: Function;
}

const sizeForType: Record<BannerAdType, { width: number; height: number }> = {
    standard: { width: 320, height: 50 },
    large: { width: 320, height: 100 },
    full: { width: 468, height: 60 },
    mediumRectangle: { width: 300, height: 250 },
    leaderboard: { width: 728, height: 90 },
    dynamic: { width: -1, height: 50 },
    dynamicLeaderboard: { width: -1, height: 90 },
};

const getSizeForType = (type: BannerAdType) => sizeForType[type];

const LINKING_ERROR =
    `The package '@azerion/bluestack-sdk-react-native' doesn't seem to be linked. Make sure: \n\n` +
    Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
    '- You rebuilt the app after installing the package\n' +
    '- You are not using Expo managed workflow\n';

const ComponentName = 'BluestackModuleView';

export const BluestackModuleView =
    UIManager.getViewManagerConfig(ComponentName) != null
        ? requireNativeComponent<NativeBannerViewProps>(ComponentName)
        : () => {
              throw new Error(LINKING_ERROR);
          };

// export const BannerModuleView = (props: BannerViewProps) => {
export const BannerModuleView: React.FC<BannerViewProps> = (props) => {
    const {
        onBannerAdLoaded,
        onBannerAdFailedToLoad,
        onBannerAdRefreshed,
        onBannerAdFailedToRefresh,
        onBannerAdClicked,
        type,
        visible,
        ...restProps
    } = props;

    let adType = type;
    if (adType === undefined) {
        adType = 'standard';
    }
    const size = getSizeForType(adType);

    // Track dynamic height from native side
    const [dynamicHeight, setDynamicHeight] = useState<number>(size.height);

    // Handle ad loaded event and update height
    const handleAdLoaded = useCallback(
        (event: any) => {
            if (event?.nativeEvent?.size) {
                setDynamicHeight(event.nativeEvent.size);
            }
            onBannerAdLoaded?.(event);
        },
        [onBannerAdLoaded]
    );

    return (
        <BluestackModuleView
            {...restProps}
            style={[{ width: size.width, height: dynamicHeight }]}
            adSize={adType.toString()}
            visible={visible}
            onAdLoaded={handleAdLoaded}
            onAdFailedToLoad={onBannerAdFailedToLoad}
            onAdRefreshed={onBannerAdRefreshed}
            onAdFailedToRefresh={onBannerAdFailedToRefresh}
            onAdClicked={onBannerAdClicked}
        />
    );
};
