package com.reactlibrary;

import android.os.Handler;
import android.util.Log;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.VideoView;

import com.appnexus.opensdk.AdListener;
import com.appnexus.opensdk.AdView;
import com.appnexus.opensdk.NativeAdResponse;
import com.appnexus.opensdk.ResultCode;
import com.appnexus.opensdk.instreamvideo.Quartile;
import com.appnexus.opensdk.instreamvideo.ResultCallback;
import com.appnexus.opensdk.instreamvideo.VideoAd;
import com.appnexus.opensdk.instreamvideo.VideoAdLoadListener;
import com.appnexus.opensdk.instreamvideo.VideoAdPlaybackListener;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
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.ViewGroupManager;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.RCTEventEmitter;

import java.util.Map;

import javax.annotation.Nullable;

class RTCAppNexusVideoBannerManager extends ViewGroupManager<RTCAppNexusVideoBannerView> {

    private VideoAd videoAd;
    public VideoView videoPlayer;
    private RTCAppNexusVideoBannerView baseContainer;


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

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

    @Override
    protected RTCAppNexusVideoBannerView createViewInstance(ThemedReactContext reactContext) {
        baseContainer = new RTCAppNexusVideoBannerView(reactContext.getCurrentActivity());
        context = reactContext;
        videoPlayer = new VideoView(context);
        videoPlayer.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
        baseContainer.addView(videoPlayer);


        return baseContainer;
    }

    private static final int COMMAND_START_PLAYING = 1;
    private static final int COMMAND_RELOAD_VIDEO  = 2;


    @Override
    public Map<String,Integer> getCommandsMap() {
        Log.d("React"," View manager getCommandsMap:");
        return MapBuilder.of(
                "startPlayingVideoAdWithTag",
                COMMAND_START_PLAYING,
                "reloadVideo",
                COMMAND_RELOAD_VIDEO);
    }

    private boolean isStartPlaying = false;

    @Override
    public void receiveCommand(final RTCAppNexusVideoBannerView root, int commandId, @Nullable ReadableArray args) {
        super.receiveCommand(root, commandId, args);

        switch (commandId) {
            case COMMAND_START_PLAYING:
                if (isStartPlaying)
                    return;

                if (videoAd.isReady()) {
                    // Play the VideoAd by passing the container.
                    videoAd.playAd(baseContainer);
                    isStartPlaying = true;

                    // Continue to main content video if the ad doesnot start in 2 seconds.
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            videoAd.getAdPlayElapsedTime(new ResultCallback() {
                                @Override
                                public void onResult(int result) {
                                    if( result <=0){
                                        videoPlayer.start();
                                    }
                                }
                            });
                        }
                    }, 2000);
                } else {
                    videoPlayer.start();
                }
                break;
            case COMMAND_RELOAD_VIDEO:
                isStartPlaying = false;
                videoAd.removeAd();
                videoAd.loadAd();
                break;

        }
    }


    public void onPlayStatusChange(int id, VideoAdPlaybackListener.PlaybackCompletionState state) {

        WritableMap event = Arguments.createMap();
        switch (state) {
            case COMPLETED:
                event.putInt("playbackState",0);
                break;
            case SKIPPED:
                event.putInt("playbackState",1);
                break;
            case ERROR:
                event.putInt("playbackState",-1);
                break;

        }

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

    }

    public void onEnentChange(int id, String event_txt) {

        WritableMap event = Arguments.createMap();
        event.putString("event",event_txt);

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

    }

    public void onAdLoadSuccess(int id) {

        WritableMap event = Arguments.createMap();
        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);

    }

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



    @ReactProp(name="placementId")
    public void setPlacementId(final RTCAppNexusVideoBannerView v, String placement_id) {

        videoAd = new VideoAd(context, placement_id);
        // Set the Ad-Load Listener
        videoAd.setAdLoadListener(new VideoAdLoadListener() {
            @Override
            public void onAdLoaded(final VideoAd videoAd) {
                onAdLoadSuccess(v.getId());
            }

            @Override
            public void onAdRequestFailed(VideoAd videoAd, ResultCode errorCode) {
                onAdLoadFail(v.getId(),"Error "+errorCode);
            }
        });


        //Load the Ad.
        videoAd.loadAd();


        // Set PlayBack Listener.
        videoAd.setVideoPlaybackListener(new VideoAdPlaybackListener() {

            @Override
            public void onAdPlaying(final VideoAd videoAd) {
                onEnentChange(v.getId(),"AdPlaying");
            }

            @Override
            public void onQuartile(VideoAd view, Quartile quartile) {
                onEnentChange(v.getId(),"Quartile");
            }

            @Override
            public void onAdCompleted(VideoAd view, PlaybackCompletionState playbackState) {
                onPlayStatusChange(v.getId(), playbackState);
            }

            @Override
            public void onAdMuted(VideoAd view, boolean isMute) {
                onEnentChange(v.getId(),"AdMuted");
            }

            @Override
            public void onAdClicked(VideoAd adView) {
                onEnentChange(v.getId(),"AdClicked");
            }

            @Override
            public void onAdClicked(VideoAd videoAd, String clickUrl) {
                onEnentChange(v.getId(),"AdClicked:"+clickUrl);
            }
        });


    }

}
