package com.xixun.xixunplayer;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.SurfaceTexture;
import android.view.Surface;
import android.view.TextureView;

import androidx.annotation.NonNull;
import androidx.annotation.OptIn;
import androidx.media3.common.MediaItem;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.SeekParameters;

import tv.danmaku.ijk.media.player.IMediaPlayer;
import tv.danmaku.ijk.media.player.IjkMediaPlayer;

public class EleVideo extends TextureView implements TextureView.SurfaceTextureListener {

    String path;
    float vol;
    IjkMediaPlayer ijkPlayer;
    ExoPlayer exoPlayer;
    long bitRate;

    public EleVideo(Context context, String path, float vol) {
        super(context);
        this.path = path;
        this.vol = vol;
        initIjk();
    }

    @OptIn(markerClass = UnstableApi.class)
    void initExo() {
        exoPlayer = new ExoPlayer.Builder(getContext()).build();
        exoPlayer.setMediaItem(MediaItem.fromUri(path));
        exoPlayer.setRepeatMode(ExoPlayer.REPEAT_MODE_ONE);
        exoPlayer.setSeekParameters(SeekParameters.CLOSEST_SYNC);
        exoPlayer.setVolume(vol);
        exoPlayer.setVideoTextureView(this);
        exoPlayer.prepare();
    }
    void initIjk() {
        ijkPlayer = new IjkMediaPlayer();
        //ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);
        ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 0);
        ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzeduration", 1);
        ijkPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48);
        try {
            setSurfaceTextureListener(this);
            ijkPlayer.setDataSource(path);
            ijkPlayer.setLooping(true);
            ijkPlayer.setVolume(vol, vol);
            ijkPlayer.setOnPreparedListener((IMediaPlayer var1)->{
                bitRate = ijkPlayer.getBitRate();
                if(bitRate > 12000000) {
                    setSurfaceTextureListener(null);
                    release();
                    initExo();
                }
                if(isShown()) start();
            });
            ijkPlayer.prepareAsync();
        } catch (Throwable e) {
            Util.makeText(getContext(), Util.toStr(e)).show();
            Util.printStackTrace(e);
            ijkPlayer = null;
        }
    }
    @Override
    public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) {
        if(ijkPlayer!=null) ijkPlayer.setSurface(new Surface(surface));
    }
    @Override
    public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {
    }
    @Override
    public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
        return false;
    }
    @Override
    public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {
    }

    void start() {
        if(ijkPlayer!=null) {
            ijkPlayer.seekTo(0);
            ijkPlayer.start();
        } else if(exoPlayer!=null) {
            if(exoPlayer.getPlaybackState()==ExoPlayer.STATE_IDLE) exoPlayer.prepare();
            exoPlayer.play();
        }
    }
    void pause() {
        if(ijkPlayer!=null) {
            ijkPlayer.pause();
            ijkPlayer.seekTo(0);
        }
        if(exoPlayer!=null && exoPlayer.isPlaying()) {
            exoPlayer.pause();
            exoPlayer.seekToDefaultPosition();
        }
    }
    void release() {
        if(ijkPlayer!=null) {
            ijkPlayer.release();
            ijkPlayer = null;
        }
        if(exoPlayer!=null) {
            exoPlayer.release();
            exoPlayer = null;
        }
    }

    String getState() {
        if(exoPlayer!=null) {
            var state = exoPlayer.getPlaybackState();
            if(state==ExoPlayer.STATE_IDLE) return "STATE_IDLE";
            if(state==ExoPlayer.STATE_BUFFERING) return "STATE_BUFFERING";
            if(state==ExoPlayer.STATE_READY) return "STATE_READY";
            if(state==ExoPlayer.STATE_ENDED) return "STATE_ENDED";
        }
        return "null";
    }

    @Override
    public void onVisibilityAggregated(boolean isVisible) {
        super.onVisibilityAggregated(isVisible);
        if(isVisible) start();
        else pause();
    }
}