package com.reactlibrary;

import android.os.Handler;
import android.util.Log;

import com.appnexus.opensdk.ANClickThroughAction;
import com.appnexus.opensdk.AdListener;
import com.appnexus.opensdk.AdSize;
import com.appnexus.opensdk.AdView;
import com.appnexus.opensdk.NativeAdResponse;
import com.appnexus.opensdk.ResultCode;
import com.appnexus.opensdk.utils.Clog;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.RCTEventEmitter;

import java.util.ArrayList;
import java.util.Map;

import javax.annotation.Nullable;

class RTCAppNexusBannerManager extends SimpleViewManager<RTCAppNexusBannerView> {

    public static final String REACT_CLASS = "RCTAppNexusBanner";
    private ThemedReactContext context;

    @Override
    public String getName() {
        return REACT_CLASS;
    }

    @Override
    protected RTCAppNexusBannerView createViewInstance(ThemedReactContext reactContext) {
        RTCAppNexusBannerView bannerView = new RTCAppNexusBannerView(reactContext.getCurrentActivity());
        context = reactContext;
        return bannerView;
    }

    @ReactProp(name = "autoRefreshInterval", defaultInt = 60)
    public void setBorderRadius(final RTCAppNexusBannerView bav, int interval) {
        bav.setAutoRefreshInterval(interval);
        Log.d("testr","set refresh interval = "+interval);
    }

    public void onAdLoadSuccess(int id, int width, int height) {

        WritableMap event = Arguments.createMap();
        event.putInt("width",width);
        event.putInt("height",height);

        context.getJSModule(RCTEventEmitter.class)
                .receiveEvent(id,
                        "onAdLoadSuccess", event);

    }

    public void onAdLoadFail(int id, String error) {
        WritableMap event = Arguments.createMap();
        event.putString("error",error);
        context.getJSModule(RCTEventEmitter.class)
                .receiveEvent(id,
                        "onAdLoadSuccess", event);

    }

    @ReactProp(name = "keywords")
    public void setKeywords(final RTCAppNexusBannerView bav, ReadableMap map) {
        for (String key:map.toHashMap().keySet()) {
            bav.addCustomKeywords(key,map.getString(key));
            Log.d("testr","add keyword key = "+key+", val = "+map.getString(key));
        }

    }

    @ReactProp(name = "sizes")
    public void setSizes(final RTCAppNexusBannerView bav, ReadableArray sizes) {
        ArrayList<AdSize> list = new ArrayList<>();
        for (int i = 0;i<sizes.size();i++) {
            list.add(new AdSize(sizes.getArray(i).getInt(0),sizes.getArray(i).getInt(1)));
        }

        bav.setAdSizes(list);
    }

    @Nullable @Override
    public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
        return MapBuilder.<String, Object>builder()
                .put("onAdLoadSuccess",
                        MapBuilder.of("registrationName", "onAdLoadSuccess"))
                .put("onAdLoadFail",
                        MapBuilder.of("registrationName", "onAdLoadFail"))
                .build();
    }

    @ReactProp(name="placementId")
    public void setPlacementId(final RTCAppNexusBannerView bav, String placement_id) {
        // This is your AppNexus placement ID.
        bav.setPlacementID(placement_id);

//        // Turning this on so we always get an ad during testing.
//        bav.setShouldServePSAs(true);
//
        // By default ad clicks open in an in-app WebView.
        bav.setClickThroughAction(ANClickThroughAction.OPEN_SDK_BROWSER);

        // Resizes the container size to fit the banner ad
        bav.setResizeAdToFitContainer(true);
//        // Set up a listener on this ad view that logs events.
        AdListener adListener = new AdListener() {
            @Override
            public void onAdRequestFailed(AdView bav, ResultCode errorCode) {
                if (errorCode == null) {
                    onAdLoadFail(bav.getId(),"Call to loadAd failed");
                } else {
                    onAdLoadFail(bav.getId(),"Ad request failed: " + errorCode);
                }
            }

            @Override
            public void onAdLoaded(AdView bav) {
                onAdLoadSuccess(bav.getId(),bav.getCreativeWidth(),bav.getCreativeHeight());

            }

            @Override
            public void onAdLoaded(NativeAdResponse nativeAdResponse) {
                onAdLoadSuccess(bav.getId(),bav.getCreativeWidth(),bav.getCreativeHeight());
            }

            @Override
            public void onAdExpanded(AdView bav) {
            //    Clog.v("SIMPLEBANNER", "Ad expanded");
            }

            @Override
            public void onAdCollapsed(AdView bav) {
            //    Clog.v("SIMPLEBANNER", "Ad collapsed");
            }

            @Override
            public void onAdClicked(AdView bav) {
            //    Clog.v("SIMPLEBANNER", "Ad clicked; opening browser");
            }

            @Override
            public void onAdClicked(AdView adView, String clickUrl) {
            //    Clog.v("SIMPLEBANNER", "onAdClicked with click URL");
            }
        };

        bav.setAdListener(adListener);

        // If auto-refresh is enabled (the default), a call to
        // `FrameLayout.addView()` followed directly by
        // `BannerAdView.loadAd()` will succeed.  However, if
        // auto-refresh is disabled, the call to
        // `BannerAdView.loadAd()` needs to be wrapped in a `Handler`
        // block to ensure that the banner ad view is in the view
        // hierarchy *before* the call to `loadAd()`.  Otherwise the
        // visibility check in `loadAd()` will fail, and no ad will be
        // shown.
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                bav.loadAd();
            }
        }, 0);
    }
}
