package com.xxrv.video.activity;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.alibaba.android.arouter.launcher.ARouter;
import com.bumptech.glide.Glide;
import com.frame.base.bus.RxBus;
import com.frame.base.bus.SendVideoEvent;
import com.frame.base.url.Constance;
import com.ruiwenliu.wrapper.base.BaseBean;
import com.ruiwenliu.wrapper.base.BaseStatusActivity;
import com.ruiwenliu.wrapper.statusbar.StatusBarUtil;
import com.ruiwenliu.wrapper.weight.TitleView;
import com.xxrv.video.R;
import com.xxrv.video.R2;
import com.xxrv.video.dialog.SelectCoverDialog;
import com.xxrv.video.dialog.SelectMusicDialog;
import com.xxrv.video.presenter.VideoPresenter;
import com.xxrv.video.util.AsyncUtils;
import com.xxrv.video.util.FileUtils;
import com.xxrv.video.util.RecorderUtils;
import com.xxrv.video.weight.Xcoverbar;
import com.xxrv.video.weight.Xpreprogressbar;
import com.xxrv.video.weight.Xspeedbar;
import com.xxrv.video.weight.Xvolumebar;

import java.io.File;

import Jni.FFmpegCmd;
import Jni.VideoUitls;
import VideoHandle.EpEditor;
import VideoHandle.OnEditorListener;
import butterknife.BindView;
import butterknife.OnClick;
import fm.jiecao.jcvideoplayer_lib.JCVideoPlayer;
import fm.jiecao.jcvideoplayer_lib.JCVideoViewbyXuan;
import fm.jiecao.jcvideoplayer_lib.OnJcvdListener;

public class PreviewxActivity extends BaseStatusActivity<VideoPresenter> {

    @BindView(R2.id.x_video)
    JCVideoViewbyXuan mVideoView;
    @BindView(R2.id.iv_thumb)
    ImageView iv_thumb;
    @BindView(R2.id.iv_back)
    ImageView ivBack;
    @BindView(R2.id.ll_back)
    LinearLayout llBack;


    @BindView(R2.id.bar_change)
    Xspeedbar mSpeedBar;
    @BindView(R2.id.bar_volume)
    Xvolumebar mVolumeBar;
    @BindView(R2.id.tv_loading)
    TextView mTvLoding;
    @BindView(R2.id.ll_loding)
    LinearLayout mWaitDialog;
    @BindView(R2.id.xpb_pro)
    Xpreprogressbar progressbar;
    @BindView(R2.id.ll_select_volume)
    LinearLayout llSelectVolume;
    @BindView(R2.id.ll_select_show)
    LinearLayout rlSelectShow;
    @BindView(R2.id.xcover_bar)
    Xcoverbar xcoverBar;
    @BindView(R2.id.iv_hint1)
    ImageView ivHint1;
    @BindView(R2.id.iv_hint2)
    ImageView ivHint2;
    @BindView(R2.id.iv_hint3)
    ImageView ivHint3;
    @BindView(R2.id.ll_item_hint)
    LinearLayout llItemHint;
    @BindView(R2.id.tv_item_video_speed)
    TextView tvItemVideoSpeed;
    @BindView(R2.id.tv_item_volume)
    TextView tvItemVolume;
    @BindView(R2.id.tv_item_cover)
    TextView tvItemCover;


    private String mCurrPath; // 当前的视屏
    private String mVideoPath; // 原版视屏
    private int loadCover;
    private SelectCoverDialog coverDialog;
    private String mCoverPath;
    private String mHitText;
    private String thumbPath;
    private SelectMusicDialog mSelectDialog;
    private String mCurrBgmName;
    private String mCurrBgmId;
    private String mCurrBgmPath;


    BroadcastReceiver closeReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            finish();
        }
    };


    Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case RecorderUtils.COMPRESS_SUCCESS: // 压缩成功
                    Log.e("xuan", "压缩成功" + mCurrPath);
                    // appendWatermark(mCurrPath);
                    // todo 先隐藏添加水印功能
                    start(mCurrPath);
                    break;
                case RecorderUtils.COMPRESS_FAILURE: // 压缩失败
                    Log.e("xuan", "压缩失败" + mCurrPath);
                    showToast(getString(R.string.compre_failure));
                    // appendWatermark(mCurrPath);
                    // todo 先隐藏添加水印功能
                    start(mCurrPath);
                    break;
                case RecorderUtils.WATERMARK_SUCCESS: // 添加水印成功
                    Log.e("xuan", "添加水印成功" + mCurrPath);
                    start(mCurrPath);
                    break;
                case RecorderUtils.WATERMARK_FAILURE: // 添加水印失败
                    Log.e("xuan", "添加水印失败" + mCurrPath);
                    start(mCurrPath);
                    break;
                case RecorderUtils.COVER_SUCCESS:
                    // 获取封面成功
                    if (loadCover == RecorderUtils.COVER_SUCCESS) {
                        xcoverBar.setCoverBackground(mCoverPath);
                        rlSelectShow.setVisibility(rlSelectShow.getVisibility() == View.VISIBLE && xcoverBar.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
                        xcoverBar.setVisibility(xcoverBar.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
                        mVideoView.pause();
                        iv_thumb.setVisibility(View.VISIBLE);
                    }

                    loadCover = RecorderUtils.COVER_SUCCESS;
                    break;
                case RecorderUtils.COVER_FAILURE: // 获取封面失败
//                    findViewById(R.id.ll_cover).setVisibility(View.GONE);
                    // TODO: 2019/11/14
                    break;
                case RecorderUtils.SPEED_SUCCESS: // 变速成功
                    mSpeedBar.isEnabled(false);
                case RecorderUtils.VOLUME_SUCCESS: // 修改音量成功
                    mVolumeBar.isEnabled(false);
                case RecorderUtils.MUSIC_SUCCESS: // 修改音乐成功
                    mVideoView.play(mCurrPath);
                    break;
                case RecorderUtils.SPEED_FAILURE: // 变速失败
                    showToast(getString(R.string.edit_failed));
                    mSpeedBar.isEnabled(false);
                    break;
                case RecorderUtils.VOLUME_FAILURE: // 修改音量失败
                    showToast(getString(R.string.edit_failed));
                    mVolumeBar.isEnabled(false);
                    break;
                default:
                    mTvLoding.setText(mHitText + " " + msg.what + "%");
                    break;
            }

            if (msg.what > 100) {
                showWaitDialog(false, "");
                mSpeedBar.isEnabled(false);
                mVolumeBar.isEnabled(false);
            }
            return false;
        }
    });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        StatusBarUtil.setRootViewFitsSystemWindows(mActivity, false);
    }

    @Override
    protected int setLayout() {
        return R.layout.activity_previewx;
    }

    @Override
    protected void initView(Bundle savedInstanceState, TitleView titleView, Intent intent) {
        showTitle(false);

        mVideoPath = getIntent().getStringExtra("file_path");
        mCurrBgmName = getIntent().getStringExtra("music_name");
        mCurrBgmId = getIntent().getStringExtra("music_id");

        mCurrPath = mVideoPath;
        File file = new File(mVideoPath);
        if (!file.exists()) {
            Log.e("xuan", "onCreate: 视频文件不存在");
        }

        Log.e("xuan", "onCreate: " + mVideoPath);
        init();
        broadcast();
    }

    @Override
    protected void onPause() {
        super.onPause();

        if (mVideoView != null) {
            mVideoView.stop();
        }
    }

    @Override
    public void onBackPressedSupport() {
        if (mWaitDialog.getVisibility() == View.VISIBLE) {
            return;
        }
        super.onBackPressedSupport();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(closeReceiver);
    }

    private void broadcast() {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("action.colse_trill");
        registerReceiver(closeReceiver, intentFilter);
    }


    private void init() {

        iv_thumb.setVisibility(View.GONE);

        mVideoView.addOnJcvdListener(new OnJcvdListener() {
            @Override
            public void onPrepared() {
                long length = mVideoView.getDuration();

                if (mVideoView.mCurrState == JCVideoPlayer.CURRENT_STATE_PAUSE) {
                    progressbar.play(mVideoView.getDuration());
                } else {
                    progressbar.play(0, mVideoView.getDuration());
                }

                if (loadCover == 0) {
                    loadCover(mVideoView.mCurrUrl, length);
                }
            }

            @Override
            public void onCompletion() {
                progressbar.clear();
            }

            @Override
            public void onError() {

            }

            @Override
            public void onPause() {
                progressbar.cancelProgressTimer();
            }

            @Override
            public void onReset() {

            }
        });


        mVideoView.play(mVideoPath);

        mSpeedBar.addOnChangeListener(select -> {
            float speed = 0.5f + select * 0.25f;
            Log.e("xuan", "init: 选择速度" + speed);
            changeSpeed(speed);
        });


        mVolumeBar.addOnChangeListener(curr -> {
            int vol = (int) ((curr - 50) / 10f * 3); // ( -15 - 15)范围
            Log.e("xuan", "选择音量 Volume: " + vol);
            changeVolume(vol);
        });

        xcoverBar.addOnChangeListener(new Xcoverbar.OnChangeListener() {
            @Override
            public void change(String curr) {
                Glide.with(PreviewxActivity.this).load(curr).into(iv_thumb);
                thumbPath = curr;
                Log.e("xuan", "init: 选择封面" + curr);
            }
        });
    }

    @Override
    public void onShowResult(int requestType, BaseBean result) {

    }

    @OnClick({R2.id.ll_back, R2.id.tv_item_video_speed, R2.id.tv_item_cover, R2.id.tv_item_next, R2.id.tv_item_volume, R2.id.v_show})
    public void onViewClicked(View view) {
        int id = view.getId();
        if (id == R.id.ll_back) {
            finish();

        } else if (id == R.id.tv_item_video_speed) {
            //视频速度
            xcoverBar.setVisibility(View.GONE);
            llSelectVolume.setVisibility(View.GONE);
            rlSelectShow.setVisibility(rlSelectShow.getVisibility() == View.VISIBLE && mSpeedBar.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
            mSpeedBar.setVisibility(mSpeedBar.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
            ivHint1.setVisibility(View.VISIBLE);
            ivHint2.setVisibility(View.INVISIBLE);
            ivHint3.setVisibility(View.INVISIBLE);
            iv_thumb.setVisibility(View.GONE);
            mVideoView.play("");

            tvItemVolume.setTextColor(getResources().getColor(R.color.colorWrite));
            tvItemCover.setTextColor(getResources().getColor(R.color.colorWrite));
            if (mSpeedBar.getVisibility() == View.VISIBLE) {
                tvItemVideoSpeed.setTextColor(getResources().getColor(R.color.gray_FFB74B));
            } else {
                tvItemVideoSpeed.setTextColor(getResources().getColor(R.color.colorWrite));
            }

        } else if (id == R.id.tv_item_cover) {
            //封面图
            if (loadCover == RecorderUtils.COVER_SUCCESS) {
                xcoverBar.setCoverBackground(mCoverPath);
                rlSelectShow.setVisibility(rlSelectShow.getVisibility() == View.VISIBLE && xcoverBar.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
                xcoverBar.setVisibility(xcoverBar.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);

                mSpeedBar.setVisibility(View.GONE);
                llSelectVolume.setVisibility(View.GONE);
                ivHint1.setVisibility(View.INVISIBLE);
                ivHint2.setVisibility(View.INVISIBLE);
                ivHint3.setVisibility(View.VISIBLE);

                tvItemVolume.setTextColor(getResources().getColor(R.color.colorWrite));
                tvItemVideoSpeed.setTextColor(getResources().getColor(R.color.colorWrite));

                if (xcoverBar.getVisibility() == View.GONE) {
                    iv_thumb.setVisibility(View.GONE);
                    mVideoView.play("");
                    tvItemCover.setTextColor(getResources().getColor(R.color.colorWrite));
                } else {
                    mVideoView.pause();
                    iv_thumb.setVisibility(View.VISIBLE);
                    tvItemCover.setTextColor(getResources().getColor(R.color.gray_FFB74B));
                }

            } else if (loadCover == RecorderUtils.COVER_LOADING) {
                // loadCover = RecorderUtils.COVER_AUTOOPEN;
                showToast(getString(R.string.tip_load_cover));
            }

        } else if (id == R.id.tv_item_next) {
            onNext();

        } else if (id == R.id.tv_item_volume) {
            //音量
            xcoverBar.setVisibility(View.GONE);
            mSpeedBar.setVisibility(View.GONE);
            rlSelectShow.setVisibility(rlSelectShow.getVisibility() == View.VISIBLE && llSelectVolume.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
            llSelectVolume.setVisibility(llSelectVolume.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
            ivHint1.setVisibility(View.INVISIBLE);
            ivHint2.setVisibility(View.VISIBLE);
            ivHint3.setVisibility(View.INVISIBLE);

            tvItemVideoSpeed.setTextColor(getResources().getColor(R.color.colorWrite));
            tvItemCover.setTextColor(getResources().getColor(R.color.colorWrite));
            if (llSelectVolume.getVisibility() == View.VISIBLE) {
                tvItemVolume.setTextColor(getResources().getColor(R.color.gray_FFB74B));
            } else {
                tvItemVolume.setTextColor(getResources().getColor(R.color.colorWrite));
            }

            iv_thumb.setVisibility(View.GONE);
            mVideoView.play("");
        } else if (id == R.id.v_show) {
            rlSelectShow.setVisibility(View.GONE);
            xcoverBar.setVisibility(View.GONE);
            mSpeedBar.setVisibility(View.GONE);
            llSelectVolume.setVisibility(View.GONE);
            iv_thumb.setVisibility(View.GONE);
            mVideoView.play("");

            tvItemVideoSpeed.setTextColor(getResources().getColor(R.color.colorWrite));
            tvItemVolume.setTextColor(getResources().getColor(R.color.colorWrite));
            tvItemCover.setTextColor(getResources().getColor(R.color.colorWrite));
        }
    }


    private void loadCover(String inPath, long time) {
        final int coverCount = 6;
        loadCover = RecorderUtils.COVER_LOADING;
        // 帧提取器
        String thumb = RecorderUtils.getThumb(inPath);
        String out = RecorderUtils.getThumbPath(inPath);
        String cmd = RecorderUtils.ffmpegFindThumbMultipleCmd(inPath, out, time / 1000f, coverCount);
        EpEditor.execCmd(cmd, time, new OnEditorListener() {
            @Override
            public void onSuccess() {
                mCoverPath = out;
                mVideoView.mCurrState = JCVideoPlayer.CURRENT_STATE_NORMAL;
                handler.sendEmptyMessage(RecorderUtils.COVER_SUCCESS);
                Log.e("xuan", "FFmpeg_EpMedia:封面 获取成功" + out);
            }

            @Override
            public void onFailure() {
/*
                loadCover = RecorderUtils.COVER_FAILURE;
                handler.sendEmptyMessage(RecorderUtils.COVER_FAILURE);
*/
                Log.e("xuan", "FFmpeg_EpMedia:封面 获取失败--->" + mVideoView.getDuration());
                /**
                 * FFmpeg_EpMedia获取帧图片失败，我们在通过系统提供的api获取帧图片
                 */
                AsyncUtils.doAsync(this, (AsyncUtils.Function<AsyncUtils.AsyncContext<OnEditorListener>>) onEditorListenerAsyncContext -> {
                    MediaMetadataRetriever mmr = new MediaMetadataRetriever();
                    mmr.setDataSource(inPath);
                    for (int i = 0; i < coverCount; i++) {
                        // 取出  视频时长/当前张数取反 *1000 μs 的bitmap
                        Bitmap frameBitmap = mmr.getFrameAtTime(mVideoView.getDuration() / (coverCount - i) * 1000); // unit is μs 1 ms = 1000 μs
                        FileUtils.saveFileByBitmap(frameBitmap, thumb, RecorderUtils.getThumbPath(inPath, i + 1));
                        if (i == coverCount - 1) {
                            mmr.release();
                        }
                    }

                    mCoverPath = out;
                    mVideoView.mCurrState = JCVideoPlayer.CURRENT_STATE_NORMAL;
                    handler.sendEmptyMessage(RecorderUtils.COVER_SUCCESS);
                    Log.e("xuan", "FFmpeg_EpMedia:封面 获取成功" + out);
                });
            }

            @Override
            public void onProgress(float v) {
                Log.e("xuan", "FFmpeg_EpMedia:封面中");
            }
        });
    }

    private void changeSpeed(float speed) {
        if (speed == 1) {
            mCurrPath = mVideoPath;
            mVideoView.mCurrState = JCVideoPlayer.CURRENT_STATE_NORMAL;
            handler.sendEmptyMessage(RecorderUtils.SPEED_SUCCESS);
            return;
        }

        File file = new File(RecorderUtils.changeFileNameBySpeed(mVideoPath, speed));
        mCurrPath = file.getAbsolutePath();
        if (file.exists()) {
            mVideoView.mCurrState = JCVideoPlayer.CURRENT_STATE_NORMAL;
            mVideoView.play(file.getAbsolutePath());
            return;
        }

        mSpeedBar.isEnabled(true);

        showWaitDialog(true, getString(R.string.modified));
        EpEditor.changePTS(mVideoPath, file.getAbsolutePath(), speed, EpEditor.PTS.ALL, new OnEditorListener() {
            @Override
            public void onSuccess() {
                mVideoView.mCurrState = JCVideoPlayer.CURRENT_STATE_NORMAL;
                handler.sendEmptyMessage(RecorderUtils.SPEED_SUCCESS);
            }

            @Override
            public void onFailure() {
                mCurrPath = mVideoPath;
                handler.sendEmptyMessage(RecorderUtils.SPEED_FAILURE);
            }

            @Override
            public void onProgress(float progress) {
                int pro = Math.round(progress * 100);
                if (pro <= 100) {
                    handler.sendEmptyMessage(pro);
                }
            }
        });
    }

    private void changeVolume(int volume) {
        showWaitDialog(true, getString(R.string.modified));
        mVolumeBar.isEnabled(true);
        mVideoView.stop();

        final String out = RecorderUtils.changeFileName(mVideoPath, "vol");
        String[] cmd = RecorderUtils.ffmpegVolumeCmd(mVideoPath, out, volume);
        long duration = VideoUitls.getDuration(mVideoPath);
        FFmpegCmd.exec(cmd, duration, new OnEditorListener() {
            public void onSuccess() {
                mCurrPath = out;
                mVideoView.mCurrState = JCVideoPlayer.CURRENT_STATE_NORMAL;
                handler.sendEmptyMessage(RecorderUtils.VOLUME_SUCCESS);
                Log.e("xuan", "onProgress: 修改声音成功" + out);
            }

            public void onFailure() {
                handler.sendEmptyMessage(RecorderUtils.VOLUME_FAILURE);
                Log.e("xuan", "onProgress: 修改声音失败");
            }

            public void onProgress(float progress) {
                int pro = Math.max(Math.min(Math.round(progress * 100), 100), 0);
                handler.sendEmptyMessage(pro);
            }
        });
    }

    private void changeMusic(final String musicPath) {
        final String outfilePath = RecorderUtils.getVideoFileByTime();

        // 合并音效
        EpEditor.music(mCurrPath, musicPath, outfilePath, 0f, 1f, new OnEditorListener() {
            @Override
            public void onSuccess() {
                mCurrPath = outfilePath;
                mVideoPath = mCurrPath;
                mVideoView.mCurrState = JCVideoPlayer.CURRENT_STATE_NORMAL;
                handler.sendEmptyMessage(RecorderUtils.MUSIC_SUCCESS);
            }

            @Override
            public void onFailure() {
                handler.sendEmptyMessage(RecorderUtils.MUSIC_SUCCESS);
            }

            @Override
            public void onProgress(float progress) {
                //这里获取处理进度
                int pro = Math.max(Math.min(Math.round(progress * 100), 100), 0);
                handler.sendEmptyMessage(pro);
            }
        });
    }

    private void onNext() {
        compressVideo();
    }

    private void compressVideo() {
        showWaitDialog(true, getString(R.string.compressed));

        final String out = RecorderUtils.getVideoFileByTime();
        String[] cmd = RecorderUtils.ffmpegComprerssCmd(mCurrPath, out);
        long duration = VideoUitls.getDuration(mCurrPath);

        FFmpegCmd.exec(cmd, duration, new OnEditorListener() {
            public void onSuccess() {
                mCurrPath = out;
                handler.sendEmptyMessage(RecorderUtils.COMPRESS_SUCCESS);
            }

            public void onFailure() {
                handler.sendEmptyMessage(RecorderUtils.COMPRESS_FAILURE);
            }

            public void onProgress(float progress) {
                int pro = Math.round(progress * 100);
                if (pro < 100) {
                    handler.sendEmptyMessage(pro);
                }
                Log.e("xuan", "onProgress: 压缩中" + pro);
            }
        });
    }

    /**
     * 跳转到发布界面
     */
    private void start(String filePath) {
        mVideoView.stop();
        mVideoView.reset();

        if (TextUtils.isEmpty(thumbPath)) {
            if (TextUtils.isEmpty(mCoverPath)) {
                thumbPath = RecorderUtils.saveThumbByStrote(filePath);
            } else {
                thumbPath = String.format(mCoverPath, 1);
            }
        }

        long length = mVideoView.getDuration();

        ARouter.getInstance()
                .build(Constance.ACTIVITY_URL_SENDVIDEO)
                .withString("mVideoFilePath", filePath)
                .withLong("mTimeLen", length)
                .withString("mThumbPath", thumbPath)
                .withString("mCurrBgmId", mCurrBgmId)
                .navigation();

        RxBus.post(new SendVideoEvent());
        finish();
    }


    public void showWaitDialog(boolean show, String hit) {
        mWaitDialog.setVisibility(show ? View.VISIBLE : View.INVISIBLE);
        if (show) {
            mHitText = hit;
            mTvLoding.setText(hit + " 0%");
        }
    }

    public void showToast(String content) {
        Toast.makeText(this, content, Toast.LENGTH_SHORT).show();
    }
}
