package com.reactnativezoom.videosdk;

import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.widget.FrameLayout;

import com.reactnativezoom.videosdk.broadcaststream.BroadcastStreamingAudioPlayer;
import com.reactnativezoom.videosdk.broadcaststream.BroadcastStreamingVideoRenderer;

import us.zoom.sdk.ZoomVideoSDK;
import us.zoom.sdk.ZoomVideoSDKBroadcastStreamingViewer;
import us.zoom.sdk.ZoomVideoSDKVideoResolution;

/**
 * Renders the active broadcast stream's video onto its surface and plays
 * the broadcast audio through the device speaker.
 *
 * Subscribes / unsubscribes via the SDK's singleton broadcast streaming
 * viewer helper on attach / detach. The host app must already be in the
 * StreamingJoinStatus.Joined state before this view is mounted.
 */
public class RNZoomBroadcastStreamingView extends FrameLayout {

    private static final String TAG = "RNZoomBroadcastStreamingView";

    private final BroadcastStreamingVideoRenderer renderer;
    private final BroadcastStreamingAudioPlayer audioPlayer;

    private ZoomVideoSDKVideoResolution videoResolution =
            ZoomVideoSDKVideoResolution.VideoResolution_720P;
    private boolean subscribed = false;

    public RNZoomBroadcastStreamingView(Context context) {
        super(context);
        setBackgroundColor(Color.BLACK);
        renderer = new BroadcastStreamingVideoRenderer(context);
        addView(renderer, new FrameLayout.LayoutParams(
                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        audioPlayer = new BroadcastStreamingAudioPlayer();
    }

    public void setVideoResolution(ZoomVideoSDKVideoResolution resolution) {
        if (resolution == null || resolution == this.videoResolution) {
            return;
        }
        this.videoResolution = resolution;
        if (subscribed) {
            // Re-subscribe video at new resolution.
            ZoomVideoSDKBroadcastStreamingViewer viewer = getViewer();
            if (viewer != null) {
                viewer.unSubscribeVideo(renderer);
                viewer.subscribeVideo(videoResolution, renderer);
            }
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        subscribeIfNeeded();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        unsubscribeIfNeeded();
    }

    private void subscribeIfNeeded() {
        if (subscribed) {
            return;
        }
        ZoomVideoSDKBroadcastStreamingViewer viewer = getViewer();
        if (viewer == null) {
            Log.w(TAG, "viewer helper unavailable; not subscribing");
            return;
        }
        int vErr = viewer.subscribeVideo(videoResolution, renderer);
        int aErr = viewer.subscribeAudio(audioPlayer);
        if (vErr != 0 || aErr != 0) {
            Log.w(TAG, "subscribe error video=" + vErr + " audio=" + aErr);
        }
        subscribed = (vErr == 0 || aErr == 0);
    }

    private void unsubscribeIfNeeded() {
        if (!subscribed) {
            return;
        }
        ZoomVideoSDKBroadcastStreamingViewer viewer = getViewer();
        if (viewer != null) {
            viewer.unSubscribeVideo(renderer);
            viewer.unSubscribeAudio();
        }
        subscribed = false;
        audioPlayer.stop();
    }

    private ZoomVideoSDKBroadcastStreamingViewer getViewer() {
        try {
            return ZoomVideoSDK.getInstance().getBroadcastStreamingViewer();
        } catch (Exception e) {
            return null;
        }
    }
}
