package com.tytv.twiliovideo;

import android.content.Context;

import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;

import com.facebook.react.bridge.WritableNativeMap;
import com.facebook.react.uimanager.ThemedReactContext;
import com.twilio.video.RemoteAudioTrack;
import com.twilio.video.RemoteAudioTrackPublication;
import com.twilio.video.RemoteDataTrack;
import com.twilio.video.RemoteDataTrackPublication;
import com.twilio.video.RemoteParticipant;
import com.twilio.video.RemoteVideoTrack;
import com.twilio.video.RemoteVideoTrackPublication;
import com.twilio.video.TwilioException;
import com.twilio.video.VideoTextureView;


public class RemoteView extends ConstraintLayout {
    VideoTextureView preview;

    RemoteViewManager manager;
    ThemedReactContext reactContext;
    // State

    RemoteParticipant participant;


    public RemoteView(Context context, RemoteViewManager manager){
        super(context);
        reactContext = (ThemedReactContext) context;
        this.manager = manager;
        preview = new VideoTextureView(context);
        addView(preview, 0, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    }

    public void confifureWithParticipant(String participantIdentity, TwilioRoomView roomView){
        RemoteParticipant participant = roomView.participants.stream()
                .filter(par -> par.getIdentity().equals(participantIdentity))
                .findFirst().get();
        this.participant = participant;

        if(participant.getRemoteVideoTracks().size() > 0){
            RemoteVideoTrackPublication trackPublication = participant.getRemoteVideoTracks().get(0);
            RemoteVideoTrack track = trackPublication.getRemoteVideoTrack();
            if(track != null) {
                track.addRenderer(this.preview);
            }
        }

        this.participant.setListener(listener());
    }

    private RemoteParticipant.Listener listener(){
        RemoteView view = this;
        return new RemoteParticipant.Listener() {
            @Override
            public void onAudioTrackPublished(@NonNull RemoteParticipant remoteParticipant, @NonNull RemoteAudioTrackPublication remoteAudioTrackPublication) {
                manager.pushEvent(reactContext, view, RemoteViewManager.onPublishedAudioTrack, new WritableNativeMap());
            }

            @Override
            public void onAudioTrackUnpublished(@NonNull RemoteParticipant remoteParticipant, @NonNull RemoteAudioTrackPublication remoteAudioTrackPublication) {
                manager.pushEvent(reactContext, view, RemoteViewManager.onUnPublishedAudioTrack, new WritableNativeMap());
            }

            @Override
            public void onAudioTrackSubscribed(@NonNull RemoteParticipant remoteParticipant, @NonNull RemoteAudioTrackPublication remoteAudioTrackPublication, @NonNull RemoteAudioTrack remoteAudioTrack) {
                manager.pushEvent(reactContext, view, RemoteViewManager.onSubcribeAudioTrack, new WritableNativeMap());
            }

            @Override
            public void onAudioTrackSubscriptionFailed(@NonNull RemoteParticipant remoteParticipant, @NonNull RemoteAudioTrackPublication remoteAudioTrackPublication, @NonNull TwilioException twilioException) {
                manager.pushEvent(reactContext, view, RemoteViewManager.onFailedToSubscribeVideoTrack, new WritableNativeMap());
            }

            @Override
            public void onAudioTrackUnsubscribed(@NonNull RemoteParticipant remoteParticipant, @NonNull RemoteAudioTrackPublication remoteAudioTrackPublication, @NonNull RemoteAudioTrack remoteAudioTrack) {
                manager.pushEvent(reactContext, view, RemoteViewManager.onUnPublishedAudioTrack, new WritableNativeMap());
            }

            @Override
            public void onVideoTrackPublished(@NonNull RemoteParticipant remoteParticipant, @NonNull RemoteVideoTrackPublication remoteVideoTrackPublication) {
                manager.pushEvent(reactContext, view, RemoteViewManager.onPublishedVideoTrack, new WritableNativeMap());
            }

            @Override
            public void onVideoTrackUnpublished(@NonNull RemoteParticipant remoteParticipant, @NonNull RemoteVideoTrackPublication remoteVideoTrackPublication) {
                manager.pushEvent(reactContext, view, RemoteViewManager.onUnPublishedVideoTrack, new WritableNativeMap());
            }

            @Override
            public void onVideoTrackSubscribed(@NonNull RemoteParticipant remoteParticipant, @NonNull RemoteVideoTrackPublication remoteVideoTrackPublication, @NonNull RemoteVideoTrack remoteVideoTrack) {
                remoteVideoTrack.addRenderer(preview);
                manager.pushEvent(reactContext, view, RemoteViewManager.onSubcribeVideoTrack, new WritableNativeMap());
            }

            @Override
            public void onVideoTrackSubscriptionFailed(@NonNull RemoteParticipant remoteParticipant, @NonNull RemoteVideoTrackPublication remoteVideoTrackPublication, @NonNull TwilioException twilioException) {
                manager.pushEvent(reactContext, view, RemoteViewManager.onFailedToSubscribeVideoTrack, new WritableNativeMap());
            }

            @Override
            public void onVideoTrackUnsubscribed(@NonNull RemoteParticipant remoteParticipant, @NonNull RemoteVideoTrackPublication remoteVideoTrackPublication, @NonNull RemoteVideoTrack remoteVideoTrack) {
                remoteVideoTrack.removeRenderer(preview);
                manager.pushEvent(reactContext, view, RemoteViewManager.onUnSubcribeVideoTrack, new WritableNativeMap());
            }

            @Override
            public void onDataTrackPublished(@NonNull RemoteParticipant remoteParticipant, @NonNull RemoteDataTrackPublication remoteDataTrackPublication) {
//                manager.pushEvent(reactContext, view, RemoteViewManager.onPublishedAudioTrack, new WritableNativeMap());
            }

            @Override
            public void onDataTrackUnpublished(@NonNull RemoteParticipant remoteParticipant, @NonNull RemoteDataTrackPublication remoteDataTrackPublication) {
//                manager.pushEvent(reactContext, view, RemoteViewManager.onPublishedAudioTrack, new WritableNativeMap());
            }

            @Override
            public void onDataTrackSubscribed(@NonNull RemoteParticipant remoteParticipant, @NonNull RemoteDataTrackPublication remoteDataTrackPublication, @NonNull RemoteDataTrack remoteDataTrack) {
//                manager.pushEvent(reactContext, view, RemoteViewManager.onPublishedAudioTrack, new WritableNativeMap());
            }

            @Override
            public void onDataTrackSubscriptionFailed(@NonNull RemoteParticipant remoteParticipant, @NonNull RemoteDataTrackPublication remoteDataTrackPublication, @NonNull TwilioException twilioException) {
//                manager.pushEvent(reactContext, view, RemoteViewManager.onPublishedAudioTrack, new WritableNativeMap());
            }

            @Override
            public void onDataTrackUnsubscribed(@NonNull RemoteParticipant remoteParticipant, @NonNull RemoteDataTrackPublication remoteDataTrackPublication, @NonNull RemoteDataTrack remoteDataTrack) {
//                manager.pushEvent(reactContext, view, RemoteViewManager.onPublishedAudioTrack, new WritableNativeMap());
            }

            @Override
            public void onAudioTrackEnabled(@NonNull RemoteParticipant remoteParticipant, @NonNull RemoteAudioTrackPublication remoteAudioTrackPublication) {
                manager.pushEvent(reactContext, view, RemoteViewManager.onEnabledAudioTrack, new WritableNativeMap());
            }

            @Override
            public void onAudioTrackDisabled(@NonNull RemoteParticipant remoteParticipant, @NonNull RemoteAudioTrackPublication remoteAudioTrackPublication) {
                manager.pushEvent(reactContext, view, RemoteViewManager.onDisabledAudioTrack, new WritableNativeMap());
            }

            @Override
            public void onVideoTrackEnabled(@NonNull RemoteParticipant remoteParticipant, @NonNull RemoteVideoTrackPublication remoteVideoTrackPublication) {
                manager.pushEvent(reactContext, view, RemoteViewManager.onEnabledVideoTrack, new WritableNativeMap());
            }

            @Override
            public void onVideoTrackDisabled(@NonNull RemoteParticipant remoteParticipant, @NonNull RemoteVideoTrackPublication remoteVideoTrackPublication) {
                manager.pushEvent(reactContext, view, RemoteViewManager.onDisabledVideoTrack, new WritableNativeMap());
            }
        };
    }
}
