package com.hc.lib.video;

import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.hc.lib.R;
import com.hc.lib.store.LastPlayTimeStore;
import com.jewel.mplayer.ControlView;
import com.jewel.mplayer.CoreVideoView;
import com.jewel.mplayer.OnVideoChangeListener;
import com.jewel.mplayer.content.VideoData;
import com.jewel.mplayer.system.SystemVideoView;
import com.orhanobut.logger.Logger;

import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

public class MVideoPlayer extends FrameLayout implements IVideoPlayer {

    private SystemVideoView videoView;
    private ControlView controlView;

    private RelativeLayout layoutTop;
    private LinearLayout layoutBottom;
    private FrameLayout layoutLoading;

    private boolean isChangingProgress = false;
    private boolean isFullVideo = false;
    private boolean isLooping = false;
    private boolean showCompleteDialog = true;
    private long limitTime = PLAY_TIME_NO_LIMIT;

    private boolean needSeek = false;
    private SeekBar progressBar;

    private VideoHideControlViewRunnable videoHideControlViewRunnable;
    private VideoHideLastPlayBarRunnable videoHideLastPlayBarRunnable;
    private OnPlayerPausedListener onPlayerPausedListener;

    //add by 许林 2018/12/5
    private boolean isPrepared = false;     //当前视频是否已经加载完毕
    private long currentTime = 0;           //记录滑动的时间点
    private View seekContainer;
    private SeekBar seekBar;
    TextView percentText;

    //延迟滑动计时器
    private Timer timer;
    private TimerTask timerTask;

    private VideoData currentVideoData;

    //页面activity
    Activity mainActivity;

    //本地存储
    LastPlayTimeStore lastPlayTimeStore;
    String mLastPlayTime = "";
    static boolean isShowLastPlayBar = false;

    //上次退出界面
    LinearLayout lastPlayBar;
    TextView lastTimeText;
    ImageView resumePlayButton;

    private int seekPercent = 5; //快进百分比

    private String TAG = "MVideoPlayer";

    public void setMargins (int l, int t, int r, int b) {
        if (videoView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
            ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) videoView.getLayoutParams();
            p.setMargins(l, t, r, b);
            videoView.requestLayout();
        }
    }

    public MVideoPlayer(final Context context) {
        super(context);

        View root = View.inflate(getContext(), R.layout.layout_m_player, this);

        videoView = root.findViewById(R.id.videoView);
        controlView = root.findViewById(R.id.controlView);

        layoutTop = root.findViewById(R.id.layout_top);
        layoutBottom = root.findViewById(R.id.layout_bottom);
        layoutLoading = root.findViewById(R.id.loading);
        progressBar = root.findViewById(R.id.progress);
        progressBar.setProgress(0);

        //add by 许林 2018/12/5
        seekContainer = findViewById(R.id.seek_container_show);
        seekBar = findViewById(R.id.seek_bar_tv);
        percentText = findViewById(R.id.percent_text);

        //上次退出界面 add by 许林 2019/2/26
        lastPlayBar = findViewById(R.id.last_play_bar);
        lastTimeText = findViewById(R.id.last_time_text);
        resumePlayButton = findViewById(R.id.resume_play_btn);


        seekBar.setMax(1000);
        seekBar.setProgress(0);
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                int mProgress = 0;

               /* if (fromUser) {
                    mProgress = progress;
                }*/
                mProgress = progress;
                Log.d(TAG,"progress:" + progress);
                percentText.setText(mProgress/10 + "%");

                if(progress<=0){
                    seekBar.setProgress(10);
                    percentText.setText("1%");
                }

                if(progress >= 1000){
                    seekBar.setProgress(990);
                    percentText.setText("99%");
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        controlView.attachToVideo(this, videoView);

        videoView.addOnVideoChangeListener(new OnVideoChangeListener() {
            @Override
            public void onVideoPrepared(CoreVideoView coreVideoView) {
                Log.d(TAG,"lastPlayTimeInt:" + mLastPlayTime);
                isPrepared = true;
                if(isFullVideo && !mLastPlayTime.isEmpty()){
                    new Timer().schedule(new TimerTask() {
                        @Override
                        public void run() {
                            Activity activity = (Activity)context;
                            activity.runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    int lastPlayTimeInt = Integer.parseInt(mLastPlayTime);
                                    Log.d(TAG,"lastPlayTimeInt:" + lastPlayTimeInt);
                                    videoView.seekTo(lastPlayTimeInt);
                                    showLastTimeBar(mLastPlayTime);
                                    hideAllWidget();
                                }
                            });
                        }
                    },200);

                }
            }

            @Override
            public void onVideoStarted(CoreVideoView coreVideoView) {

            }

            @Override
            public void onVideoBufferStart(CoreVideoView coreVideoView) {
                layoutLoading.setVisibility(VISIBLE);
            }

            @Override
            public void onVideoBufferEnd(CoreVideoView coreVideoView) {
                layoutLoading.setVisibility(GONE);
                Log.d(TAG,"onVideoBufferEnd,layoutLoading gone");
            }

            @Override
            public void onVideoProgress(CoreVideoView coreVideoView, int currentPosition, int bufferPercentage, int duration) {
                if (videoView.isBuffering()) {
                    layoutLoading.setVisibility(VISIBLE);
                } else if (layoutLoading.getVisibility() == VISIBLE) {
                    layoutLoading.setVisibility(GONE);
                    Log.d(TAG,"onVideoProgress,videoView is not buffer,layoutLoading gone");
                }

                if (needSeek && currentPosition >= 2000) {
                    Toast.makeText(getContext(), "正在跳转到上次播放时间", Toast.LENGTH_LONG).show();
                    needSeek = false;
                    int seekTime = videoView.getVideo().getSeekTimeWhenStart() * 1000;
                    if (seekTime >= duration) {
                        return;
                    }
                    Logger.d("视频开始播放时快进时长：%s秒", seekTime);
                    videoView.seekTo(seekTime);
                }
            }

            @Override
            public void onVideoSeekCompleted(CoreVideoView coreVideoView, int currentPosition, int bufferPercentage, int duration) {

            }

            @Override
            public void onVideoPaused(CoreVideoView coreVideoView) {

            }

            @Override
            public void onVideoCompleted(CoreVideoView coreVideoView) {
                if (isLooping) {
                    start(videoView.getVideo());
                } else if (isFullVideo && onPlayerPausedListener != null) {
                    if (showCompleteDialog) {
                        onPlayerPausedListener.videoCompleted();
                    } else {
                        onVideoDestroy();
                        onPlayerPausedListener.videoToNext();
                    }
                }
            }

            @Override
            public void onVideoReleased(CoreVideoView coreVideoView) {
                if(videoView == null || videoView.getVideo() == null) {
                    return;
                }
                Logger.d("视频结束播放，时长(%s秒), 视频id(%s)", videoView.getVideo().getCurrentPosition(), videoView.getVideo().getId());
            }

            @Override
            public void onVideoError(CoreVideoView coreVideoView, int errorCode, String msg) {

            }
        });

        lastPlayTimeStore = new LastPlayTimeStore(context);
    }

    public void start(final VideoData videoData) {
        currentVideoData = videoData;
        if (videoData != null) {
            onVideoDestroy();
            videoView.setVideo(videoData);
            if (videoData.getSeekTimeWhenStart() > 0) {
                needSeek = true;
            }
            videoView.start();
            controlView.setTitle(videoData.getTitle());
            //获取上次播放时间，add by xulin 2019/2/26
            if (isFullVideo) {
                String lastPlayTime = getLastPlayTime(videoData.getId());
                //Log.d(TAG,"lastPlayTime:" + lastPlayTime + ";  sourceId:" + videoData.getId());
                lastPlayTimeStore.delete(videoData.getId());
                if(!lastPlayTime.isEmpty()){
                    mLastPlayTime = lastPlayTime;
                }else{
                    showControlWidget();
                    mLastPlayTime= "";
                }
            }
        }
        if(layoutLoading != null){
            layoutLoading.setVisibility(VISIBLE);
        }
    }

    public void resumePlay(){
        lastPlayBar.setVisibility(INVISIBLE);
        isShowLastPlayBar = false;
        videoView.seekTo(0);
    }

    private String getLastPlayTime(String sourceId){
        return lastPlayTimeStore.getTimeBySourceId(sourceId);
    }

    public void start() {
        videoView.start();
    }

    //向前或者向后移动滑块一段距离,add by 许林 2018/12/5
    public void seek(final int position){
        if(!isPrepared){
            return;
        }

        mainActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                seekBar.setProgress(position);
                currentTime =Calendar.getInstance().getTimeInMillis();
            }
        });

        cancelTimer();
        initTimer();
    }

    private void cancelTimer(){
        if(timerTask != null){
            timerTask.cancel();
        }
    }

    /*
     * 传递activity实例
     * by xuling 20180726
     */
    public void setActivity(Activity activity){
        this.mainActivity = activity;
    }

    /**
     * 获取当前视频时长(毫秒)
     * by xuling 20180726
     */
    public int getDuration(){
        try{
            if(!isPrepared){
                return 0;
            }

            return videoView.getDuration();
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }

    }

    /**
     * 获取当前播放时间(毫秒)
     * by xuling 20180726
     */
    public int getCurrentPos(){
        try{
            if(!isPrepared){
                return 0;
            }

            return videoView.getCurrentPositionWhenPlaying();
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }

    }

    /*
     * 延迟执行视频快进任务
     * by xuling 20180726
     */
    public void storeLastPlayTime(){
        int currentPos = getCurrentPos();
        int duration = getDuration();
        if(currentPos < duration){
            lastPlayTimeStore.insert(String.valueOf(currentPos),currentVideoData.getId());
        }
    }

    /*
     * 延迟执行视频快进任务
     * by xuling 20180726
     */
    private void initTimer(){
        if(mainActivity == null){
            Log.d(TAG,"请向播放器传递activity实例");
            return;
        }
        if(timer == null){
            timer = new Timer();
        }
        timerTask = new TimerTask() {
            @Override
            public void run() {
                mainActivity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        long myCurrentTime = Calendar.getInstance().getTimeInMillis();
                        if(myCurrentTime - currentTime > 3){
                            int position = seekBar.getProgress();
                            int duration = getDuration();
                            float fPostion = position;
                            float fDuration = duration;
                            position = (int)(fPostion*fDuration/1000);
                            seekTo(position);
                            seekContainer.setVisibility(GONE);
                        }
                    }
                });
            }
        };

        timer.schedule(timerTask,2000);
    }

    /* 跳转
     * by xuling 20180726
     */
    private void seekTo(int position){
        videoView.seekTo(position);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        Logger.d("HCVideoPlayer onKeyDown start: %s, %s", keyCode, event.getAction());
        switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_LEFT:
               /* if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    changeProgress(true);
                } else if (event.getAction() == KeyEvent.ACTION_UP) {
                    isChangingProgress = false;
                }*/
               if(!isShowLastPlayBar){
                   if(isPrepared){
                       seekBack();
                   }else{
                       Toast.makeText(mainActivity,"视频准备中，暂时不能拖动快进",Toast.LENGTH_SHORT).show();
                   }
               }
                return true;
            case KeyEvent.KEYCODE_DPAD_RIGHT:
//                if(isChangingProgress) {
//                    seekToTime += TIME;
//                    if(seekToTime >= 10 * 60 * 1000) {
//                        seekToTime = 10 * 60 * 1000;
//                    }
//                }
               /* if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    changeProgress(false);
                } else if (event.getAction() == KeyEvent.ACTION_UP) {
                    isChangingProgress = false;
                }*/
                if(!isShowLastPlayBar){
                    if(isPrepared){
                        seekForward();
                    }else{
                        Toast.makeText(mainActivity,"视频准备中，暂时不能拖动快进",Toast.LENGTH_SHORT).show();
                    }
                }
                return true;
            case KeyEvent.KEYCODE_DPAD_UP:
                if(!isShowLastPlayBar){
                    showControlWidget();
                }
//                changeVolume(true);
                break;
            case KeyEvent.KEYCODE_DPAD_DOWN:
                if(!isShowLastPlayBar){
                    showControlWidget();
                }
//                changeVolume(false);
                break;
            case KeyEvent.KEYCODE_DPAD_CENTER:
                if(isShowLastPlayBar){
                    resumePlay();
                }else{
                    if (event.getAction() == KeyEvent.ACTION_DOWN ) {
                        if(videoView.isPlaying()){
                            pauseOrPlay(false);
                        }
                    }
                }
                break;
            case KeyEvent.KEYCODE_ENTER:
                if (event.getAction() == KeyEvent.ACTION_DOWN ) {
                    if(videoView.isPlaying()){
                        pauseOrPlay(false);
                    }
                }
                break;
            default:
                break;
        }
        Logger.d("HCVideoPlayer onKeyDown end: %s", keyCode);
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public void keyCodeBack(){
        if(isShowLastPlayBar){
            lastPlayBar.setVisibility(INVISIBLE);
            isShowLastPlayBar = false;
        }else{
            pauseOrPlay(false);
        }
    }

    //add by 许林 ,2018/12/5
    private void seekBack(){
        if(seekContainer.getVisibility() != VISIBLE){
            mainActivity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    hideAllWidget();
                    seekContainer.setVisibility(VISIBLE);
                    int currentPos = videoView.getCurrentPositionWhenPlaying();
                    int durationSec = videoView.getDuration()/1000;
                    int position = currentPos/ durationSec;
                    seekBar.setProgress(position);
                    currentTime =Calendar.getInstance().getTimeInMillis();
                }
            });
        }

        int position = seekBar.getProgress() - seekPercent* 10;
        seek(position);
    }

    private void seekForward(){
        /*if(vipState == -1){
            if(isFee != 1){
                return;
            }
        }*/

        if(seekContainer.getVisibility() != VISIBLE){
            mainActivity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    hideAllWidget();
                    seekContainer.setVisibility(VISIBLE);
                    int currentPos = videoView.getCurrentPositionWhenPlaying();
                    int durationSec = videoView.getDuration()/1000;
                    int position = currentPos/ durationSec;
                    seekBar.setProgress(position);
                    currentTime =Calendar.getInstance().getTimeInMillis();
                }
            });
        }

        int position = seekBar.getProgress() + seekPercent* 10;
        seek(position);
    }

    @Override
    public void setAudioMute(boolean needMute) {
        videoView.setMute(needMute);
    }

    @Override
    public void setFullVideo(boolean fullVideo) {
        this.isFullVideo = fullVideo;
        if (fullVideo) {
            showControlWidget();
        } else {
            hideAllWidget();
        }
    }

    @Override
    public void setLimitTime(long limitTime) {
        this.limitTime = limitTime;
    }

    @Override
    public void hideAllWidget() {
        layoutTop.setVisibility(GONE);
        layoutBottom.setVisibility(GONE);
        layoutLoading.setVisibility(GONE);
        Log.d(TAG,"hideAllWidget,layoutLoading gone");
    }

    /*
    * 显示上次退出播放的时间
    * */
    private void showLastTimeBar(String lastTime){
        lastPlayBar.setVisibility(VISIBLE);
        //resumePlayButton.requestFocus();
        isShowLastPlayBar = true;
        int lastTimeCount = Integer.parseInt(lastTime)/1000;
        String lastTimeToShow = "上次观看到" + secToTime(lastTimeCount)+ ",已为您继续播放";
        lastTimeText.setText(lastTimeToShow);

        if (videoHideLastPlayBarRunnable == null) {
            videoHideLastPlayBarRunnable = new VideoHideLastPlayBarRunnable(lastPlayBar);
        }
        getRootView().getHandler().removeCallbacks(videoHideLastPlayBarRunnable);
        getRootView().getHandler().postDelayed(videoHideLastPlayBarRunnable, 5000);
    }

    /*
    * 将秒转化为时秒分
    * */
    public static String secToTime(int time) {
        String timeStr = null;
        int hour = 0;
        int minute = 0;
        int second = 0;
        if (time <= 0)
            return "00:00";
        else {
            minute = time / 60;
            if (minute < 60) {
                second = time % 60;
                timeStr = unitFormat(minute) + ":" + unitFormat(second);
            } else {
                hour = minute / 60;
                if (hour > 99)
                    return "99:59:59";
                minute = minute % 60;
                second = time - hour * 3600 - minute * 60;
                timeStr = unitFormat(hour) + ":" + unitFormat(minute) + ":" + unitFormat(second);
            }
        }
        return timeStr;
    }

    public static String unitFormat(int i) {
        String retStr = null;
        if (i >= 0 && i < 10)
            retStr = "0" + Integer.toString(i);
        else
            retStr = "" + i;
        return retStr;
    }



    /**
     * 显示控制器
     */
    private void showControlWidget() {
        layoutTop.setVisibility(VISIBLE);
        layoutBottom.setVisibility(VISIBLE);

        if (getRootView() == null || getRootView().getHandler() == null) {
            return;
        }

        if (videoHideControlViewRunnable == null) {
            videoHideControlViewRunnable = new VideoHideControlViewRunnable(this);
        }
        getRootView().getHandler().removeCallbacks(videoHideControlViewRunnable);
        getRootView().getHandler().postDelayed(videoHideControlViewRunnable, 3000);
    }

    /**
     * 更改播放进度
     *
     * @param back 是否回退，false为跨快进
     */
    private void changeProgress(boolean back) {
        showControlWidget();
        if (isChangingProgress) {
            return;
        }
        isChangingProgress = true;
        VideoSeekRunnable videoSeekRunnable = new VideoSeekRunnable(this);
        videoSeekRunnable.setBack(back);
        getRootView().getHandler().post(videoSeekRunnable);
    }


    @Override
    public void setLoop(boolean looping) {
        this.isLooping = looping;
    }

    @Override
    public void setShowCompleteDialog(boolean showCompleteDialog) {
        this.showCompleteDialog = showCompleteDialog;
    }

    public void setOnPlayerPausedListener(OnPlayerPausedListener onPlayerPausedListener) {
        this.onPlayerPausedListener = onPlayerPausedListener;
    }

    public void hideSeekContainer(){
        if(seekContainer != null){
            seekContainer.setVisibility(INVISIBLE);
        }
    }

    @Override
    public void pauseOrPlay(boolean play) {

        if (videoView.isPlaying() && play) { //已是播放状态，忽略
            return;
        }
        if (play) {
            videoView.start();
            //add by 许林 2018/12/6
            hideAllWidget();
        } else {
            videoView.pause();
            if (onPlayerPausedListener != null) { // 非播放状态显示弹窗
                onPlayerPausedListener.videoPaused();
            }
            //add by 许林 2018/12/6
            showControlWidget();
        }
    }

    @Override
    public void onVideoResume() {
        videoView.resume();
    }

    @Override
    public void onVideoPause() {
        videoView.pause();
    }

    @Override
    public void onVideoDestroy() {
        hideSeekContainer();
        cancelTimer();
        videoView.release();
    }

    @Override
    public void restart() {
        //Toast.makeText(mainActivity,"重新播放",Toast.LENGTH_SHORT).show();
        start(currentVideoData);
    }



    /**
     * 视频控制视图消失线程
     */
    private static class VideoHideControlViewRunnable implements Runnable {

        private MVideoPlayer videoPlayer;

        VideoHideControlViewRunnable(MVideoPlayer videoPlayer) {
            this.videoPlayer = videoPlayer;
        }

        @Override
        public void run() {
            videoPlayer.hideAllWidget();
            videoPlayer.isChangingProgress = false;
        }
    }

    private static class VideoHideLastPlayBarRunnable implements Runnable {

        private View view;

        VideoHideLastPlayBarRunnable(View view) {
            this.view = view;
        }

        @Override
        public void run() {
            view.setVisibility(INVISIBLE);
            isShowLastPlayBar = false;
        }
    }



    /**
     * 视频控制视图消失线程
     */
    private static class VideoSeekRunnable implements Runnable {

        private MVideoPlayer videoPlayer;
        private boolean back;
        private int seekTimePos;
        private boolean first = true;

        private int originPos;

        VideoSeekRunnable(MVideoPlayer videoPlayer) {
            this.videoPlayer = videoPlayer;
        }

        public void setBack(boolean back) {
            this.back = back;
        }

        @Override
        public void run() {
            if (!videoPlayer.isChangingProgress) {
                if (seekTimePos > videoPlayer.videoView.getVideo().getCurrentPosition()) {
                    videoPlayer.videoView.seekTo(seekTimePos);
                }
                videoPlayer.controlView.setChangeProgress(true);
                return;
            }

            if (seekTimePos == 0) {
                seekTimePos = videoPlayer.videoView.getVideo().getCurrentPosition();
                originPos = seekTimePos;
            }
            int totalTimeDuration = videoPlayer.videoView.getVideo().getDuration();
            if (back) {
                seekTimePos -= TIME; // 快退10s
                if (seekTimePos < 0) {
                    seekTimePos = 1;
                }
            } else {
                seekTimePos += TIME; // 快进10s
                if (seekTimePos > totalTimeDuration) {
                    seekTimePos = totalTimeDuration - 5;
                }
            }
            videoPlayer.controlView.setProgress(seekTimePos, totalTimeDuration);

            if (first) {
                videoPlayer.videoView.seekTo(seekTimePos);
                videoPlayer.controlView.setChangeProgress(true);
            }

            if (Math.abs(seekTimePos - originPos) > TIME * 5) {
                videoPlayer.videoView.seekTo(seekTimePos);
                originPos = seekTimePos;
            }

            if (videoPlayer.isChangingProgress) {
                videoPlayer.controlView.setChangeProgress(false);
                videoPlayer.getRootView().getHandler().postDelayed(this, first ? 1000 : 100);
                first = false;
            } else {
                videoPlayer.videoView.seekTo(seekTimePos);
                videoPlayer.controlView.setChangeProgress(true);
            }
        }
    }
}
