package app.fedilab.fedilabtube;

import android.content.Context;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;

import androidx.appcompat.app.AppCompatActivity;

import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.gms.cast.MediaInfo;
import com.google.android.gms.cast.MediaMetadata;
import com.google.android.gms.cast.framework.CastButtonFactory;
import com.google.android.gms.cast.framework.CastContext;
import com.google.android.gms.cast.framework.CastSession;
import com.google.android.gms.cast.framework.SessionManagerListener;
import com.google.android.gms.cast.framework.media.RemoteMediaClient;
import com.google.android.gms.common.images.WebImage;

import app.fedilab.fedilabtube.client.data.VideoData;
import app.fedilab.fedilabtube.databinding.ActivityPeertubeBinding;
import app.fedilab.fedilabtube.helper.Helper;

/* Copyright 2021 Thomas Schneider
 *
 * This file is a part of TubeLab
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * TubeLab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with TubeLab; if not,
 * see <http://www.gnu.org/licenses>. */

public class BasePeertubeActivity extends AppCompatActivity {

    protected ActivityPeertubeBinding binding;
    protected VideoData.Video peertube;
    protected SimpleExoPlayer player;
    protected String videoURL;
    protected String subtitlesStr;

    private CastContext mCastContext;
    private CastSession mCastSession;
    private SessionManagerListener<CastSession> mSessionManagerListener;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityPeertubeBinding.inflate(getLayoutInflater());
        View view = binding.getRoot();
        setContentView(view);
        final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);

        int search_cast = sharedpreferences.getInt(getString(R.string.set_cast_choice), BuildConfig.cast_enabled);
        if (search_cast == 1) {
            setupCastListener();
            mCastContext = CastContext.getSharedInstance(this);
            mCastSession = mCastContext.getSessionManager().getCurrentCastSession();

        }

    }


    protected void loadCast() {
        MediaMetadata movieMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE);

        movieMetadata.putString(MediaMetadata.KEY_TITLE, peertube.getTitle());
        movieMetadata.putString(MediaMetadata.KEY_ARTIST, peertube.getAccount().getDisplayName());
        if (subtitlesStr != null) {
            movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, subtitlesStr);
        }
        movieMetadata.addImage(new WebImage(Uri.parse("https://" + peertube.getChannel().getHost() + peertube.getPreviewPath())));
        MediaInfo mediaInfo = new MediaInfo.Builder(videoURL)
                .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
                .setMetadata(movieMetadata)
                .setStreamDuration(peertube.getDuration() * 1000)
                .build();
        if (mCastSession != null) {
            RemoteMediaClient remoteMediaClient = mCastSession.getRemoteMediaClient();
            remoteMediaClient.load(mediaInfo);
        }
    }


    private void setupCastListener() {
        mSessionManagerListener = new SessionManagerListener<CastSession>() {
            @Override
            public void onSessionStarting(CastSession castSession) {
            }

            @Override
            public void onSessionStarted(CastSession castSession, String s) {
                onApplicationConnected(castSession, true);
            }

            @Override
            public void onSessionStartFailed(CastSession castSession, int i) {
                onApplicationDisconnected();
            }

            @Override
            public void onSessionEnding(CastSession castSession) {
                onApplicationDisconnected();
            }

            @Override
            public void onSessionEnded(CastSession castSession, int i) {
                onApplicationDisconnected();
            }

            @Override
            public void onSessionResuming(CastSession castSession, String s) {
            }

            @Override
            public void onSessionResumed(CastSession castSession, boolean b) {
                onApplicationConnected(castSession, false);
            }

            @Override
            public void onSessionResumeFailed(CastSession castSession, int i) {
                onApplicationDisconnected();
            }

            @Override
            public void onSessionSuspended(CastSession castSession, int i) {
                onApplicationDisconnected();
            }

            private void onApplicationConnected(CastSession castSession, boolean hide) {
                mCastSession = castSession;
                supportInvalidateOptionsMenu();
                player.setPlayWhenReady(false);
                if (hide) {
                    binding.doubleTapPlayerView.setVisibility(View.INVISIBLE);
                }
                binding.minController.castMiniController.setVisibility(View.VISIBLE);
                loadCast();
            }

            private void onApplicationDisconnected() {
                binding.doubleTapPlayerView.setVisibility(View.VISIBLE);
                binding.minController.castMiniController.setVisibility(View.GONE);
                supportInvalidateOptionsMenu();
            }
        };
    }

    @Override
    protected void onResume() {
        mCastContext.getSessionManager().addSessionManagerListener(
                mSessionManagerListener, CastSession.class);
        super.onResume();
    }

    @Override
    protected void onPause() {
        mCastContext.getSessionManager().removeSessionManagerListener(
                mSessionManagerListener, CastSession.class);
        super.onPause();
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.video_menu, menu);
        CastButtonFactory.setUpMediaRouteButton(getApplicationContext(),
                menu,
                R.id.media_route_button);
        return true;
    }
}
