package com.tencent.liteav.demo.superplayer;

import static com.tencent.liteav.demo.superplayer.SuperPlayerModel.PLAY_ACTION_AUTO_PLAY;
import static com.tencent.liteav.demo.superplayer.SuperPlayerModel.PLAY_ACTION_MANUAL_PLAY;
import static com.tencent.liteav.demo.superplayer.SuperPlayerModel.PLAY_ACTION_PRELOAD;

import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.RelativeLayout;
import android.widget.Toast;


import com.tencent.liteav.demo.superplayer.model.ISuperPlayerListener;
import com.tencent.liteav.demo.superplayer.model.SuperPlayer;
import com.tencent.liteav.demo.superplayer.model.SuperPlayerImpl;
import com.tencent.liteav.demo.superplayer.model.SuperPlayerObserver;
import com.tencent.liteav.demo.superplayer.model.utils.NetWatcher;
import com.tencent.liteav.demo.superplayer.ui.player.FullScreenPlayer;
import com.tencent.liteav.demo.superplayer.ui.player.Player;
import com.tencent.liteav.demo.superplayer.ui.player.WindowPlayer;
import com.tencent.rtmp.ui.TXCloudVideoView;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;

public class SuperPlayerView extends RelativeLayout {
    private static final String TAG = "SuperPlayerView";

    private Context mContext;
    private ViewGroup mRootView;                                 // SuperPlayerView的根view

    private TXCloudVideoView mTXCloudVideoView;                         // 腾讯云视频播放view
    private FullScreenPlayer mFullScreenPlayer;                         // 全屏模式控制view
    private WindowPlayer mWindowPlayer;                             // 窗口模式控制view

    private ViewGroup.LayoutParams mLayoutParamWindowMode;          // 窗口播放时SuperPlayerView的布局参数
    private ViewGroup.LayoutParams mLayoutParamFullScreenMode;      // 全屏播放时SuperPlayerView的布局参数

    private LayoutParams mVodControllerWindowParams;      // 窗口controller的布局参数
    private LayoutParams mVodControllerFullScreenParams;  // 全屏controller的布局参数

    private OnSuperPlayerViewCallback mPlayerViewCallback;             // SuperPlayerView回调
    private NetWatcher mWatcher;                        // 网络质量监视器
    private SuperPlayer mSuperPlayer;                    // 超级播放器

    private SuperPlayerModel mCurrentSuperPlayerModel;        // 当前正在播放的SuperPlayerModel
    private int mPlayAction;                     // 播放模式
    private int mPlayIndex;                      // 正在播放model的索引
    private boolean mIsLoopPlayList;                 // 是否循环
    private List<SuperPlayerModel> mSuperPlayerModelList;           // SuperPlayerModel列表
    private long mDuration;                       // 时长
    private long mProgress;                       // 进度
    private boolean mIsPlayInit;                     // 防止mSuperPlayer.stop()继续调用playNextVideo的变量
    private boolean isCallResume = false;            //resume方法时候被调用，在预加载模式使用
    private ISuperPlayerListener mSuperPlayerListener;

    private float topLeftRadius;
    private float topRightRadius;
    private float bottomLeftRadius;
    private float bottomRightRadius;

    public SuperPlayerView(Context context) {
        this(context, null);
    }

    public SuperPlayerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SuperPlayerView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttrs(context, attrs);
        initialize(context);

    }

    private void initialize(Context context) {
        mContext = context;
        initView();
        initPlayer();
    }

    private void initAttrs(Context context, AttributeSet attrs) {
        if (attrs != null) {
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView);
            float radius = a.getDimension(R.styleable.RoundImageView_radius, 0f);
            topLeftRadius = a.getDimension(R.styleable.RoundImageView_topLeftRadius, radius);
            topRightRadius = a.getDimension(R.styleable.RoundImageView_topRightRadius, radius);
            bottomLeftRadius = a.getDimension(R.styleable.RoundImageView_bottomLeftRadius, radius);
            bottomRightRadius = a.getDimension(R.styleable.RoundImageView_bottomRightRadius, radius);
            a.recycle();
        }

        setWillNotDraw(false);
    }

    /**
     * 初始化view
     */
    private void initView() {
        mRootView = (ViewGroup) LayoutInflater.from(mContext).inflate(R.layout.superplayer_vod_view, null);

        mTXCloudVideoView = (TXCloudVideoView) mRootView.findViewById(R.id.superplayer_cloud_video_view);
        mFullScreenPlayer = (FullScreenPlayer) mRootView.findViewById(R.id.superplayer_controller_large);
        mWindowPlayer = (WindowPlayer) mRootView.findViewById(R.id.superplayer_controller_small);
        //防止stop中空指针异常
        mSuperPlayerModelList = new ArrayList<>();

        mVodControllerWindowParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        mVodControllerFullScreenParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);

        mFullScreenPlayer.setCallback(mControllerCallback);
        mWindowPlayer.setCallback(mControllerCallback);

        removeAllViews();
        mRootView.removeView(mTXCloudVideoView);
        mRootView.removeView(mWindowPlayer);
        mRootView.removeView(mFullScreenPlayer);

        addView(mTXCloudVideoView);
    }

    private void initPlayer() {
        mSuperPlayer = new SuperPlayerImpl(mContext, mTXCloudVideoView);
        mSuperPlayer.setObserver(new PlayerObserver());

        if (mSuperPlayer.getPlayerMode() == SuperPlayerDef.PlayerMode.FULLSCREEN) {
            addView(mFullScreenPlayer);
            mFullScreenPlayer.hide();
        } else if (mSuperPlayer.getPlayerMode() == SuperPlayerDef.PlayerMode.WINDOW) {
            addView(mWindowPlayer);
            mWindowPlayer.hide();
        }

        post(new Runnable() {
            @Override
            public void run() {
                if (mSuperPlayer.getPlayerMode() == SuperPlayerDef.PlayerMode.WINDOW) {
                    mLayoutParamWindowMode = getLayoutParams();
                }
                try {
                    // 依据上层Parent的LayoutParam类型来实例化一个新的fullscreen模式下的LayoutParam
                    Class parentLayoutParamClazz = getLayoutParams().getClass();
                    Constructor constructor = parentLayoutParamClazz.getDeclaredConstructor(int.class, int.class);
                    mLayoutParamFullScreenMode = (ViewGroup.LayoutParams) constructor.newInstance(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        if (mWatcher == null) {
            mWatcher = new NetWatcher(mContext);
        }

    }

    /**
     * 播放视频列表
     *
     * @param models         superPlayerModel列表
     * @param isLoopPlayList 是否循环
     * @param index          开始播放的视频索引
     */
    public void playWithModelList(List<SuperPlayerModel> models, boolean isLoopPlayList, int index) {
        mSuperPlayerModelList = models;
        mIsLoopPlayList = isLoopPlayList;
        playModelInList(index);
    }

    private void playModelInList(int index) {
//        mIsPlayInit = false;
        mSuperPlayer.stop();
        mPlayIndex = index;
        updateNextButton();
        mCurrentSuperPlayerModel = mSuperPlayerModelList.get(mPlayIndex);
        playWithModelInner(mCurrentSuperPlayerModel);
        mIsPlayInit = true;
    }

    private void updateNextButton() {
        if (mPlayIndex < mSuperPlayerModelList.size() - 1) {
            mWindowPlayer.setPlayNextButtonVisibility(true);
            mFullScreenPlayer.setPlayNextButtonVisibility(true);
        } else {
            mWindowPlayer.setPlayNextButtonVisibility(false);
            mFullScreenPlayer.setPlayNextButtonVisibility(false);
        }
    }

    /**
     * 播放视频
     *
     * @param model
     */
    public void playWithModel(SuperPlayerModel model, boolean hasNext) {
        isCallResume = false;
        mIsPlayInit = false;
        mSuperPlayer.stop();
        mIsLoopPlayList = false;
        mWindowPlayer.setPlayNextButtonVisibility(hasNext);
        mFullScreenPlayer.setPlayNextButtonVisibility(hasNext);
        //防止点击循环列表后再次回到其他列表后依然循环
        mSuperPlayerModelList.clear();
        mCurrentSuperPlayerModel = model;
        playWithModelInner(mCurrentSuperPlayerModel);
        mIsPlayInit = true;
    }

    private void playWithModelInner(SuperPlayerModel model) {
        mPlayAction = mCurrentSuperPlayerModel.playAction;
        if (mPlayAction == PLAY_ACTION_AUTO_PLAY || mPlayAction == PLAY_ACTION_PRELOAD) {
            mSuperPlayer.play(model);
        } else {
            mSuperPlayer.reset();
        }
        if (mPlayerViewCallback != null) {
            mPlayerViewCallback.onPlayIndex(mPlayIndex, model);
        }
        mFullScreenPlayer.preparePlayVideo(model);
        mWindowPlayer.preparePlayVideo(model);
    }

    /**
     * 更新标题
     *
     * @param title 视频名称
     */
    private void updateTitle(String title) {
        mWindowPlayer.updateTitle(title);
        mFullScreenPlayer.updateTitle(title);
    }

    /**
     * resume生命周期回调
     */
    public void onResume() {
        if (mPlayAction == PLAY_ACTION_MANUAL_PLAY && mSuperPlayer.getPlayerState() == SuperPlayerDef.PlayerState.INIT) {
            return;
        }
        mSuperPlayer.resume();
        isCallResume = true;
    }

    /**
     * pause生命周期回调
     */
    public void onPause() {
        if (mPlayAction == PLAY_ACTION_MANUAL_PLAY && mSuperPlayer.getPlayerState() == SuperPlayerDef.PlayerState.INIT) {
            return;
        }
        mSuperPlayer.pauseVod();
    }

    /**
     * 重置播放器
     */
    public void resetPlayer() {
        mSuperPlayerModelList.clear();
        stopPlay();
    }

    /**
     * 停止播放
     */
    public void stopPlay() {
        mSuperPlayer.stop();
        if (mWatcher != null) {
            mWatcher.stop();
        }
    }

    /**
     * 设置超级播放器的回掉
     *
     * @param callback
     */
    public void setPlayerViewCallback(OnSuperPlayerViewCallback callback) {
        mPlayerViewCallback = callback;
    }

    /**
     * 设置超级播放器中点播播放器和直播播放器的回调
     *
     * @param superPlayerListener
     */
    public void setSuperPlayerListener(ISuperPlayerListener superPlayerListener) {
        mSuperPlayerListener = superPlayerListener;
        if (mSuperPlayer != null) {
            mSuperPlayer.setSuperPlayerListener(mSuperPlayerListener);
        }
    }

    private void onSwitchFullMode(SuperPlayerDef.PlayerMode playerMode) {
        if (mLayoutParamFullScreenMode == null) {
            return;
        }

        removeView(mWindowPlayer);
        addView(mFullScreenPlayer, mVodControllerFullScreenParams);
        setLayoutParams(mLayoutParamFullScreenMode);
        if (mPlayerViewCallback != null) {
            mPlayerViewCallback.onStartFullScreenPlay();
        }

        mSuperPlayer.switchPlayMode(playerMode);
    }

    private void onSwitchWindowMode(SuperPlayerDef.PlayerMode playerMode) {
        if (mLayoutParamWindowMode == null) {
            return;
        }

        removeView(mFullScreenPlayer);
        addView(mWindowPlayer, mVodControllerWindowParams);
        setLayoutParams(mLayoutParamWindowMode);
        if (mPlayerViewCallback != null) {
            mPlayerViewCallback.onStopFullScreenPlay();
        }

        mSuperPlayer.switchPlayMode(playerMode);
    }

    private void handleSwitchPlayMode(SuperPlayerDef.PlayerMode playerMode) {
        mFullScreenPlayer.hide();
        mWindowPlayer.hide();
        //请求全屏模式
        if (playerMode == SuperPlayerDef.PlayerMode.FULLSCREEN) {
            onSwitchFullMode(playerMode);
        } else if (playerMode == SuperPlayerDef.PlayerMode.WINDOW) { // 请求窗口模式
            onSwitchWindowMode(playerMode);
        }
    }

    /**
     * 初始化controller回调
     */
    private Player.Callback mControllerCallback = new Player.Callback() {
        @Override
        public void onSwitchPlayMode(SuperPlayerDef.PlayerMode playerMode) {
            handleSwitchPlayMode(playerMode);
        }

        @Override
        public void onBackPressed(SuperPlayerDef.PlayerMode playMode) {
            switch (playMode) {
                case FULLSCREEN:// 当前是全屏模式，返回切换成窗口模式
                    onSwitchPlayMode(SuperPlayerDef.PlayerMode.WINDOW);
                    break;
                case WINDOW:// 当前是窗口模式，返回退出播放器
                    break;
                default:
                    break;
            }
        }

        @Override
        public void onPause() {
            mSuperPlayer.pause();
            if (mSuperPlayer.getPlayerType() != SuperPlayerDef.PlayerType.VOD) {
                if (mWatcher != null) {
                    mWatcher.stop();
                }
            }
        }

        @Override
        public void onResume() {
            handleResume();
        }


        @Override
        public void onSeekTo(int position) {
            mSuperPlayer.seek(position);
        }

        @Override
        public void playNext() {
            playNextVideo();
        }

        @Override
        public List<SuperPlayerModel> getPlayList() {
            if (null == mSuperPlayerModelList || mSuperPlayerModelList.isEmpty()) {
                return new ArrayList<SuperPlayerModel>() {{
                    add(mCurrentSuperPlayerModel);
                }};
            }
            return mSuperPlayerModelList;
        }

        @Override
        public SuperPlayerModel getPlayingVideoModel() {
            return mCurrentSuperPlayerModel;
        }
    };

    private void handleResume() {
        if (mSuperPlayer.getPlayerState() == SuperPlayerDef.PlayerState.LOADING
                && mPlayAction == PLAY_ACTION_PRELOAD) {
            mSuperPlayer.resume();
        } else if (mSuperPlayer.getPlayerState() == SuperPlayerDef.PlayerState.INIT) {
            if (mPlayAction == PLAY_ACTION_PRELOAD) {
                mSuperPlayer.resume();
            } else if (mPlayAction == PLAY_ACTION_MANUAL_PLAY) {
                mSuperPlayer.play(mCurrentSuperPlayerModel);
            }
        } else if (mSuperPlayer.getPlayerState() == SuperPlayerDef.PlayerState.END) { //重播
            mSuperPlayer.restart();
        } else if (mSuperPlayer.getPlayerState() == SuperPlayerDef.PlayerState.PAUSE) { //继续播放
            mSuperPlayer.resume();
        }
    }

    private void playNextVideo() {
        playIndexVideo(++mPlayIndex);
//        if (!mIsLoopPlayList && (mPlayIndex == mSuperPlayerModelList.size() - 1)) {
//            return;
//        }
//        mPlayIndex = (++mPlayIndex) % mSuperPlayerModelList.size();
//        playModelInList(mPlayIndex);
    }

    private void playIndexVideo(int index) {
        if (!mIsLoopPlayList && (index >= mSuperPlayerModelList.size())) {
            return;
        }

        mPlayIndex = (index) % mSuperPlayerModelList.size();
        playModelInList(mPlayIndex);
    }

    /**
     * SuperPlayerView的回调接口
     */
    public interface OnSuperPlayerViewCallback {

        /**
         * 开始全屏播放
         */
        void onStartFullScreenPlay();

        /**
         * 结束全屏播放
         */
        void onStopFullScreenPlay();

        /**
         * 开始播放回调
         */
        void onPlaying();

        /**
         * 播放下一个视频------
         */
        void onPlayIndex(int index, SuperPlayerModel model);

        /**
         * 播放结束
         */
        void onPlayEnd();

        /**
         * 当播放失败的时候回调
         *
         * @param code
         */
        void onError(int code);
    }

    public void release() {
        if (mWindowPlayer != null) {
            mWindowPlayer.release();
        }
        if (mFullScreenPlayer != null) {
            mFullScreenPlayer.release();
        }
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        try {
            release();
        } catch (Throwable e) {
            Log.e(TAG, Log.getStackTraceString(e));
        }
    }

    public void switchPlayMode(SuperPlayerDef.PlayerMode playerMode) {
        if (mControllerCallback != null) {
            mControllerCallback.onSwitchPlayMode(playerMode);
        }

    }

    public SuperPlayerDef.PlayerMode getPlayerMode() {
        return mSuperPlayer.getPlayerMode();
    }

    public SuperPlayerDef.PlayerState getPlayerState() {
        return mSuperPlayer.getPlayerState();
    }

    private void actonOfPreloadOnPlayPrepare() {
        if (mPlayAction != PLAY_ACTION_PRELOAD) {
            mWindowPlayer.prepareLoading();
            mFullScreenPlayer.prepareLoading();
        }
    }


    class PlayerObserver extends SuperPlayerObserver {

        @Override
        public void onPlayPrepare() {
            mWindowPlayer.updatePlayState(SuperPlayerDef.PlayerState.INIT);
            mFullScreenPlayer.updatePlayState(SuperPlayerDef.PlayerState.INIT);
            actonOfPreloadOnPlayPrepare();
            // 清空关键帧和视频打点信息
            if (mWatcher != null) {
                mWatcher.stop();
            }
        }

        @Override
        public void onPlayBegin(String name) {
            mWindowPlayer.updatePlayState(SuperPlayerDef.PlayerState.PLAYING);
            mFullScreenPlayer.updatePlayState(SuperPlayerDef.PlayerState.PLAYING);
            updateTitle(name);
            mWindowPlayer.hideBackground();
            if (mWatcher != null) {
                mWatcher.exitLoading();
            }
            notifyCallbackPlaying();
        }

        @Override
        public void onPlayPause() {
            mWindowPlayer.updatePlayState(SuperPlayerDef.PlayerState.PAUSE);
            mFullScreenPlayer.updatePlayState(SuperPlayerDef.PlayerState.PAUSE);
        }

        @Override
        public void onPlayStop() {
            playNextVideo();

//            if (mSuperPlayerModelList.size() >= 1 && mIsPlayInit && mIsLoopPlayList) {
//            } else {
//                mWindowPlayer.updatePlayState(SuperPlayerDef.PlayerState.END);
//                mFullScreenPlayer.updatePlayState(SuperPlayerDef.PlayerState.END);
//                // 清空关键帧和视频打点信息
//                if (mWatcher != null) {
//                    mWatcher.stop();
//                }
//            }
            notifyCallbackPlayEnd();
        }

        @Override
        public void onPlayLoading() {
            //预加载模式进行特殊处理
            if (mPlayAction == PLAY_ACTION_PRELOAD) {
                if (isCallResume) {
                    mWindowPlayer.updatePlayState(SuperPlayerDef.PlayerState.LOADING);
                    mFullScreenPlayer.updatePlayState(SuperPlayerDef.PlayerState.LOADING);
                }
            } else {
                mWindowPlayer.updatePlayState(SuperPlayerDef.PlayerState.LOADING);
                mFullScreenPlayer.updatePlayState(SuperPlayerDef.PlayerState.LOADING);
            }
            if (mWatcher != null) {
                mWatcher.enterLoading();
            }
        }

        @Override
        public void onPlayProgress(long current, long duration) {
            mProgress = current;
            mDuration = duration;
            mWindowPlayer.updateVideoProgress(current, duration);
            mFullScreenPlayer.updateVideoProgress(current, duration);
        }

        @Override
        public void onSeek(int position) {
            if (mSuperPlayer.getPlayerType() != SuperPlayerDef.PlayerType.VOD) {
                if (mWatcher != null) {
                    mWatcher.stop();
                }
            }
        }

        @Override
        public void onError(int code, String message) {
            showToast(message);
            notifyCallbackPlayError(code);
        }

        @Override
        public void onRcvFirstIframe() {
            super.onRcvFirstIframe();
            mWindowPlayer.toggleCoverView(false);
            mFullScreenPlayer.toggleCoverView(false);
        }
    }

    ;

    private void showToast(String message) {
        Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
    }

    private void showToast(int resId) {
        Toast.makeText(mContext, resId, Toast.LENGTH_SHORT).show();
    }

    /**
     * 通知播放开始，降低圈复杂度，单独提取成一个方法
     */
    private void notifyCallbackPlaying() {
        if (mPlayerViewCallback != null) {
            mPlayerViewCallback.onPlaying();
        }
    }

    /**
     * 通知播放结束，降低圈复杂度，单独提取成一个方法
     */
    private void notifyCallbackPlayEnd() {
        if (mPlayerViewCallback != null) {
            mPlayerViewCallback.onPlayEnd();
        }
    }

    /**
     * 通知播放错误，降低圈复杂度，单独提取成一个方法
     */
    private void notifyCallbackPlayError(int code) {
        if (mPlayerViewCallback != null) {
            mPlayerViewCallback.onError(code);
        }
    }

    public void setNeedToPause(boolean value) {
        mSuperPlayer.setNeedToPause(value);
    }

    public void setIsAutoPlay(boolean b) {
        mSuperPlayer.setAutoPlay(b);
    }

    public void setStartTime(double startTime) {
        mSuperPlayer.setStartTime((float) startTime);
    }

    public void setLoop(boolean b) {
        mSuperPlayer.setLoop(b);
    }

    @Override
    public void draw(Canvas canvas) {
        canvas.save();
        canvas.clipPath(getClipPath(getWidth(), getHeight()));
        super.draw(canvas);
        canvas.restore();
    }

    private Path getClipPath(int width, int height) {
        final Path path = new Path();
        float[] radiusArray = new float[]{
                topLeftRadius, topLeftRadius, topRightRadius, topRightRadius,
                bottomRightRadius, bottomRightRadius, bottomLeftRadius, bottomLeftRadius
        };
        path.addRoundRect(new RectF(0, 0, width, height), radiusArray, Path.Direction.CW);

        return path;
    }
}
