package com.xxrv.video.activity;


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Rect;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.alibaba.android.arouter.facade.annotation.Route;
import com.frame.base.bus.Observer;
import com.frame.base.bus.RxBus;
import com.frame.base.bus.SendVideoEvent;
import com.frame.base.url.Constance;
import com.joe.camera2recorddemo.View.CameraRecordView;
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.xxfc.imcamera.cameralibrary.CameraInterface;
import com.xxrv.video.R;
import com.xxrv.video.R2;
import com.xxrv.video.audio_x.VoiceManager;
import com.xxrv.video.bean.circle.MusicInfo;
import com.xxrv.video.bean.circle.VideoFile;
import com.xxrv.video.dialog.FilterPreviewDialog;
import com.xxrv.video.presenter.VideoPresenter;
import com.xxrv.video.util.RecorderUtils;
import com.xxrv.video.util.ScreenUtil;
import com.xxrv.video.util.UiUtils;
import com.xxrv.video.weight.MarqueTextView;
import com.xxrv.video.weight.RecordButton;
import com.xxrv.video.weight.Xrecprogressbar;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import VideoHandle.EpEditor;
import VideoHandle.EpVideo;
import VideoHandle.OnEditorListener;
import butterknife.BindView;
import butterknife.OnClick;
import io.reactivex.schedulers.Schedulers;

/**
 * 发短视频
 */
@Route(path = Constance.ACTIVITY_URL_RECORDXACTIVITY)
public class RecordxActivity extends BaseStatusActivity<VideoPresenter> {

    @BindView(R2.id.surfaceView)
    CameraRecordView mRecordView;
    @BindView(R2.id.xpbar)
    Xrecprogressbar xbar;
    @BindView(R2.id.tv_bgname)
    MarqueTextView tvBgName;
    @BindView(R2.id.ll_select_music)
    LinearLayout llMusic;
    @BindView(R2.id.ll_back)
    LinearLayout llBack;
    @BindView(R2.id.ll_swith)
    LinearLayout llSwith;
    @BindView(R2.id.ll_filter)
    LinearLayout llFilter;
    @BindView(R2.id.iv_comp)
    ImageView ivComp;
    @BindView(R2.id.iv_local)
    ImageView ivLocal;
    @BindView(R2.id.iv_del)
    ImageView ivDel;
    @BindView(R2.id.rl_more)
    RelativeLayout rlMore;
    @BindView(R2.id.btn_rec)
    RecordButton mRecordBtn;
    @BindView(R2.id.progress_ing)
    FrameLayout waitPar;

    private static final int STATE_INIT = 0;
    private static final int STATE_RECORDING = 1;
    private static final int STATE_PAUSE = 2;
    private static final int REQUEST_CODE_SELECT_VIDEO = 10;

    private List<EpVideo> videos;
    private int mRecorderState;
    private String mCurrBgmPath;
    private String mCurrBgmName;
    private String mCurrPath;
//    private SelectMusicDialog mSelectDialog;

    private FilterPreviewDialog mDialog;


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

    FilterPreviewDialog.OnUpdateFilterListener listener = new FilterPreviewDialog.OnUpdateFilterListener() {
        @Override
        public void select(int type) {
            mRecordView.switchFilter(type);
        }

        @Override
        public void dismiss() {
            rlMore.setVisibility(View.VISIBLE);
            mRecordBtn.setVisibility(View.VISIBLE);
        }
    };

    private boolean isStop = false;
    Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            waitPar.setVisibility(View.GONE);
            switch (msg.what) {
                case RecorderUtils.ACTIVATE_BTN: // 激活按钮
                    mRecordBtn.setEnabled(true);
                    break;
                case RecorderUtils.MUSIC_SUCCESS: // 音乐拼合成功
                    intentPreview(mCurrPath);
                    break;
                case RecorderUtils.MERGE_FAILURE: // 视频合并失败
                    showToast(getString(R.string.flatten_failure));
                    break;
            }
            return false;
        }
    });
    private int handlerTime = 0;// 连续对焦

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

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

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

        xbar.setTotalTime(25);
        videos = new ArrayList<>();
        mDialog = new FilterPreviewDialog(this, listener);

        initRxBus();

        xbar.addOnComptListener(new Xrecprogressbar.OnCompteListener() {
            @Override
            public void onCompte() {
                Log.e("xuan", "onCompte: ");
                stopRecord();
                mRecorderState = STATE_INIT;
                refreshControlUI();
                compteRecord();
            }
        });


        broadcast();
        // 对焦
        mRecordView.post(() -> handleFocus(ScreenUtil.getScreenWidth(mActivity) / 2, ScreenUtil.getScreenHeight(mActivity) / 2));
    }

    private void initRxBus() {
        RxBus.tObservable(SendVideoEvent.class)
                .observeOn(Schedulers.newThread())
                .subscribe(new Observer<SendVideoEvent>(disposable) {
                    @Override
                    public void onNext(SendVideoEvent event) {
                       finish();
                    }
                });
    }


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

        }
    }


    @Override
    public void onResume() {
        super.onResume();
        isStop = false;
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (!isStop) {
            VoiceManager.instance().pause();
        }
        stopRecord();
        mRecorderState = STATE_INIT;
        //  refreshControlUI();
    }

    @Override
    public void onBackPressedSupport() {
        if (waitPar.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);
    }


    @OnClick({R2.id.ll_select_music, R2.id.ll_back, R2.id.ll_swith, R2.id.ll_filter, R2.id.iv_comp, R2.id.iv_local, R2.id.iv_del, R2.id.btn_rec, R2.id.progress_ing})
    public void onViewClicked(View view) {
        int id = view.getId();
        if (id == R.id.ll_select_music) {
            startActivityForResult(SelectMusicActivity.getIntent(mActivity), 112);
//            mSelectDialog.show();

        } else if (id == R.id.ll_back) {
            // 退出录制
            VoiceManager.instance().pause();
            mRecorderState = STATE_INIT;
            refreshControlUI();
            stopRecord();
            exitRecord();

        } else if (id == R.id.ll_swith) {
            if (UiUtils.isNormalClick(view)) {
                // 这个切换摄像头连续切换会在部分设备崩溃，测试没法根治，只能限制点击频率了，
                mRecordView.switchCamera();
            }

        } else if (id == R.id.ll_filter) {
            mDialog.show();
            rlMore.setVisibility(View.GONE);
            mRecordBtn.setVisibility(View.GONE);

        } else if (id == R.id.iv_comp) {
            compteRecord();

        } else if (id == R.id.iv_local) {
            // 选择本地视频，
            startActivityForResult(SelectVideoActivity.getIntent(mActivity), 109);

        } else if (id == R.id.iv_del) {
            // 删除一段视频
            popDelVideo();
            refreshControlUI();

        } else if (id == R.id.btn_rec) {
            if (mRecorderState == STATE_INIT) {
                if (!xbar.isNotOver()) {
                    showToast(getString(R.string.delete_some));
                    return;
                }

                if (!TextUtils.isEmpty(mCurrBgmPath)) {
                    VoiceManager.instance().play(mCurrBgmPath);
                    int msec = xbar.getCurrentPro() - 1800;
                    if (msec < 0) {
                        msec = 0;
                    }
                    VoiceManager.instance().seek(msec);
                }

                //开始录制视频
                if (startRecord(RecorderUtils.getVideoFileByTime())) {
                    mRecorderState = STATE_RECORDING;
                    refreshControlUI();
                }

            } else if (mRecorderState == STATE_RECORDING) {
                //停止视频录制
                VoiceManager.instance().pause();
                stopRecord();
                mRecorderState = STATE_INIT;
                refreshControlUI();
            }

        }
    }


    /**
     * 开始录制
     *
     * @return
     */
    private boolean startRecord(String path) {
        try {
            Log.e("xuan", "开始录制：" + path);
            mRecordView.startRecord(path);
            videos.add(new EpVideo(path));
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 结束录制
     *
     * @return
     */
    private boolean stopRecord() {
        try {
            mRecordView.stopRecord();
        } catch (InterruptedException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    private void exitRecord() {
        for (int i = videos.size() - 1; i > -1; i--) {
            EpVideo video = videos.get(i);
            RecorderUtils.delVideoFile(video.getVideoPath());
        }
        finish();
    }

    /**
     * 删除上一段视频
     */
    private void popDelVideo() {
        if (videos.size() > 0) {
            EpVideo video = videos.get(videos.size() - 1);
            RecorderUtils.delVideoFile(video.getVideoPath());
            videos.remove(videos.size() - 1);
        }

        if (videos.size() == 0) {
            llMusic.setVisibility(View.GONE);
        }

        xbar.popTask();

        Log.e("xuan", "popDelVideo: " + videos.size());
    }

    /**
     * 完成录制
     */
    public void compteRecord() {
        VoiceManager.instance().stop();
        int length = videos == null ? 0 : videos.size();
        if (length == 0) {
            showToast(getString(R.string.record_frist_video));
        } else if (length == 1) { // 直接去拼合音乐
            showWaitDialog();
            EpVideo video = videos.get(0);
            appendBgm(video.getVideoPath());
        } else {
            VoiceManager.instance().stop();
            showWaitDialog();
            // 先去拼合视频
            Log.e("xuan", "即将要拼合: " + videos.size() + "个视频");
            final String outFile = RecorderUtils.getVideoFileByTime();
            EpEditor.mergeByLc(this, videos, new EpEditor.OutputOption(outFile), new OnEditorListener() {
                @Override
                public void onSuccess() {
                    appendBgm(outFile);
                }

                @Override
                public void onFailure() {
                    Log.e("xuan", "合并失败");
                    handler.sendEmptyMessage(RecorderUtils.MERGE_FAILURE);
                }

                @Override
                public void onProgress(float progress) {
                    //这里获取处理进度
                    Log.e("xuan", "正在合并" + progress);
                }
            });
        }
    }

    private void appendBgm(final String filePath) {
        if (TextUtils.isEmpty(mCurrBgmPath)) {
            mCurrPath = filePath;
            handler.sendEmptyMessage(RecorderUtils.MUSIC_SUCCESS);
            return;
        }

        final String outfilePath = RecorderUtils.getVideoFileByTime();
        mCurrPath = outfilePath;

        // 合并音效
        EpEditor.music(filePath, mCurrBgmPath, outfilePath, 0f, 1f, new OnEditorListener() {
            @Override
            public void onSuccess() {
                handler.sendEmptyMessage(RecorderUtils.MUSIC_SUCCESS);
            }

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

            @Override
            public void onProgress(float progress) {
                //这里获取处理进度
                Log.e("xuan", "music正在合并" + progress);
            }
        });
    }

    private void refreshControlUI() {
        if (mRecorderState == STATE_RECORDING) {
            //1s后才能按停止录制按钮
            mRecordBtn.setEnabled(false);
            handler.sendEmptyMessageDelayed(RecorderUtils.ACTIVATE_BTN, 1000);
            mRecordBtn.record();
            rlMore.setVisibility(View.GONE);
            llMusic.setVisibility(View.GONE);
            ivComp.setVisibility(View.GONE);
            xbar.record();
        } else if (mRecorderState == STATE_INIT) {
            mRecordBtn.pause();
            xbar.pause();
            rlMore.setVisibility(View.VISIBLE);
            if (videos.size() == 0) {
                ivDel.setVisibility(View.GONE);
                ivLocal.setVisibility(View.VISIBLE);
                ivComp.setVisibility(View.GONE);
            } else {
                ivDel.setVisibility(View.VISIBLE);
                ivLocal.setVisibility(View.GONE);
                ivComp.setVisibility(View.VISIBLE);
            }
        }
    }

    /**
     * 跳转到视频预览界面
     */
    private void intentPreview(String filePath) {
        isStop = true;

        videos.clear();
        xbar.reset();
        llMusic.setVisibility(View.GONE);
        ivComp.setVisibility(View.GONE);
        ivDel.setVisibility(View.GONE);
        ivLocal.setVisibility(View.VISIBLE);

        Intent intent = new Intent(this, PreviewxActivity.class);
        intent.putExtra("file_path", filePath);
        if (!TextUtils.isEmpty(mCurrBgmName)) {
            intent.putExtra("music_name", mCurrBgmName);
        }
        startActivity(intent);
    }

    public void showWaitDialog() {
        waitPar.setVisibility(View.VISIBLE);
    }

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

    private void handleFocus(float x, float y) {
        Camera mCamera = mRecordView.getCamera();
        if (mCamera == null) {
            return;
        }
        final Camera.Parameters params = mCamera.getParameters();
        Rect focusRect = CameraInterface.calculateTapArea(x, y, 1f, this);
        mCamera.cancelAutoFocus();
        if (params.getMaxNumFocusAreas() > 0) {
            List<Camera.Area> focusAreas = new ArrayList<>();
            focusAreas.add(new Camera.Area(focusRect, 800));
            params.setFocusAreas(focusAreas);
        } else {
            return;
        }
        final String currentFocusMode = params.getFocusMode();
        try {
            params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
            mCamera.setParameters(params);
            mCamera.autoFocus((success, camera) -> {
                if (success || handlerTime > 10) {
                    Camera.Parameters params1 = camera.getParameters();
                    params1.setFocusMode(currentFocusMode);
                    camera.setParameters(params1);
                    handlerTime = 0;
                } else {
                    handlerTime++;
                    handleFocus(x, y);
                }
            });
        } catch (Exception e) {

        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 109 && resultCode == 201) {
            if (data == null) {
                return;
            }
            VideoFile videoFile = (VideoFile) data.getSerializableExtra("videofile");

            String filePath = videoFile.getFilePath();
            if (TextUtils.isEmpty(filePath)) {
                // 不可到达，列表里有做过滤，

            } else {
                videos.clear();
                videos.add(new EpVideo(filePath));
                handler.postDelayed(() -> {
                    // 立即调用结束录制跳到预览会出现播放失败的情况，原因不明，可能是什么资源没来得及释放导致冲突，总之post一段时间就好，
                    // 测试下来延迟100ms不行，延迟500ms正常，
                    compteRecord();
                }, 500);
            }
        } else if (requestCode == 112 && resultCode == 203) {
            MusicInfo info = (MusicInfo) data.getSerializableExtra("music");
            mCurrBgmPath = info.path;
            mCurrBgmName = info.getName();
            tvBgName.setText(info.getName() + "  " + info.getName() + "   " + info.getName());
            tvBgName.setTextColor(getResources().getColor(R.color.white));
        }
    }
}
