package com.tencent.qcloud.tuicore.calling.videocall;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.blankj.utilcode.util.ToastUtils;
import com.tencent.imsdk.v2.V2TIMGroupListener;
import com.tencent.imsdk.v2.V2TIMGroupMemberInfo;
import com.tencent.imsdk.v2.V2TIMManager;
import com.tencent.liteav.TXLiteAVCode;
import com.tencent.liteav.device.TXDeviceManager;
import com.tencent.qcloud.tuicore.R;
import com.tencent.qcloud.tuicore.calling.basic.UserModel;
import com.tencent.qcloud.tuicore.calling.basic.UserModelManager;
import com.tencent.qcloud.tuicore.calling.trtccalling.model.TRTCCalling;
import com.tencent.qcloud.tuicore.calling.trtccalling.model.impl.base.CallingInfoManager;
import com.tencent.qcloud.tuicore.util.MDTRxActivityTool;
import com.tencent.qcloud.tuicore.util.StatusBarUtil;
import com.tencent.qcloud.tuicore.util.ToastUtil;
import com.tencent.rtmp.ui.TXCloudVideoView;
import com.tencent.trtc.TRTCCloud;
import com.tencent.trtc.TRTCCloudDef;
import com.tencent.trtc.TRTCCloudListener;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

/**
 * TRTC视频通话的主页面
 * <p>
 * 包含如下简单功能：
 * - 进入视频通话房间{@link VideoCallingActivity#enterRoom()}
 * - 退出视频通话房间{@link VideoCallingActivity#exitRoom()}
 * - 切换前置/后置摄像头{@link VideoCallingActivity#switchCamera()}
 * - 打开/关闭摄像头{@link VideoCallingActivity#muteVideo()}
 * - 打开/关闭麦克风{@link VideoCallingActivity#muteAudio()}
 * - 显示房间内其他用户的视频画面（当前示例最多可显示6个其他用户的视频画面）{@link TRTCCloudImplListener#refreshRemoteVideoViews()}
 * <p>
 * - 详见接入文档{https://cloud.tencent.com/document/product/647/42045}
 */
public class VideoCallingActivity extends TRTCBaseActivity implements View.OnClickListener {

    private static final String TAG = "VideoCallingActivity";
    private static final int OVERLAY_PERMISSION_REQ_CODE = 1234;

    private TextView mTextTitle;
    private TXCloudVideoView mTXCVVLocalPreviewView;
    private ImageView mImageBack;
    private TextView tvLeave;
    private LinearLayout btnVideo;
    private LinearLayout btnAudio;
    private ImageView ivVideo;
    private ImageView ivAudio;
    private ImageView ivNetworkMe;
    private ImageView ivAudioMe;
    private TextView tvMe;
    private LinearLayout llMe;

    private TRTCCloud mTRTCCloud;
    private TXDeviceManager mTXDeviceManager;
    private boolean mIsFrontCamera = true;
    private List<String> mRemoteUidList;
    private List<TXCloudVideoView> mRemoteViewList;
    // 远端用户的昵称、网络状态、麦克风状态控件
    private List<LinearLayout> mLlUserViewList;
    private List<ImageView> mIvNetWorkViewList;
    private List<ImageView> mIvAudioViewList;
    private List<TextView> mTvNameViewList;
    private TextView tvAudio;
    private TextView tvVideo;

    private int mUserCount = 0;
    private String mRoomId;
    private String mUserId;
    private boolean mAudioRouteFlag = true;
    private UserModel mUserModel;


    @SuppressLint("NewApi")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MDTRxActivityTool.addActivity(this);
        StatusBarUtil.StatusBarLightMode(this);
        handleIntent();
        setContentView(R.layout.videocall_activity_calling);
        if (checkPermission()) {
            initView();
            enterRoom();
        }
        enterGroup();
    }

    private void enterGroup() {
        V2TIMManager.getInstance().addGroupListener(mGroupListener);
    }

    private void handleIntent() {
        Intent intent = getIntent();
        if (null != intent) {
            if (intent.getStringExtra(Constant.USER_ID) != null) {
                mUserId = intent.getStringExtra(Constant.USER_ID);
            }
            if (intent.getStringExtra(Constant.ROOM_ID) != null) {
                mRoomId = intent.getStringExtra(Constant.ROOM_ID);
            }

        }
    }

    private void initView() {
        mTextTitle = findViewById(R.id.tv_room_number);
        mImageBack = findViewById(R.id.iv_back);
        mTXCVVLocalPreviewView = findViewById(R.id.trtc_view_me);
        btnVideo = findViewById(R.id.btn_video);
        btnAudio = findViewById(R.id.btn_audio);
        btnVideo.setSelected(true);
        btnAudio.setSelected(false);
        ivVideo = findViewById(R.id.iv_video);
        tvVideo = findViewById(R.id.tv_video);
        ivAudio = findViewById(R.id.iv_audio);
        tvAudio = findViewById(R.id.tv_audio);
        tvLeave = findViewById(R.id.tv_leave);
        ivNetworkMe = findViewById(R.id.iv_network_me);
        ivAudioMe = findViewById(R.id.iv_audio_me);
        tvMe = findViewById(R.id.tv_me);
        llMe = findViewById(R.id.ll_me);


        if (!TextUtils.isEmpty(mRoomId)) {
            mTextTitle.setText("房间号:" + mRoomId);
        }
        mImageBack.setOnClickListener(this);
        btnVideo.setOnClickListener(this);
        btnAudio.setOnClickListener(this);
        tvLeave.setOnClickListener(this);

        mRemoteUidList = new ArrayList<>();
        mRemoteViewList = new ArrayList<>();
        mLlUserViewList = new ArrayList<>();
        mIvNetWorkViewList = new ArrayList<>();
        mIvAudioViewList = new ArrayList<>();
        mTvNameViewList = new ArrayList<>();
        mRemoteViewList.add(findViewById(R.id.trtc_view_1));
        mRemoteViewList.add(findViewById(R.id.trtc_view_2));
        mRemoteViewList.add(findViewById(R.id.trtc_view_3));
        mRemoteViewList.add(findViewById(R.id.trtc_view_4));
        mRemoteViewList.add(findViewById(R.id.trtc_view_5));
        mRemoteViewList.add(findViewById(R.id.trtc_view_6));
        mIvNetWorkViewList.add(findViewById(R.id.iv_network_1));
        mIvNetWorkViewList.add(findViewById(R.id.iv_network_2));
        mIvNetWorkViewList.add(findViewById(R.id.iv_network_3));
        mIvNetWorkViewList.add(findViewById(R.id.iv_network_4));
        mIvNetWorkViewList.add(findViewById(R.id.iv_network_5));
        mIvNetWorkViewList.add(findViewById(R.id.iv_network_6));
        mIvAudioViewList.add(findViewById(R.id.iv_other_audio_1));
        mIvAudioViewList.add(findViewById(R.id.iv_other_audio_2));
        mIvAudioViewList.add(findViewById(R.id.iv_other_audio_3));
        mIvAudioViewList.add(findViewById(R.id.iv_other_audio_4));
        mIvAudioViewList.add(findViewById(R.id.iv_other_audio_5));
        mIvAudioViewList.add(findViewById(R.id.iv_other_audio_6));
        mLlUserViewList.add(findViewById(R.id.ll_user_1));
        mLlUserViewList.add(findViewById(R.id.ll_user_2));
        mLlUserViewList.add(findViewById(R.id.ll_user_3));
        mLlUserViewList.add(findViewById(R.id.ll_user_4));
        mLlUserViewList.add(findViewById(R.id.ll_user_5));
        mLlUserViewList.add(findViewById(R.id.ll_user_6));
        mTvNameViewList.add(findViewById(R.id.tv_name_1));
        mTvNameViewList.add(findViewById(R.id.tv_name_2));
        mTvNameViewList.add(findViewById(R.id.tv_name_3));
        mTvNameViewList.add(findViewById(R.id.tv_name_4));
        mTvNameViewList.add(findViewById(R.id.tv_name_5));
        mTvNameViewList.add(findViewById(R.id.tv_name_5));
    }

    private void enterRoom() {
        mTRTCCloud = TRTCCloud.sharedInstance(getApplicationContext());
        mTRTCCloud.setListener(new TRTCCloudImplListener(VideoCallingActivity.this));
        mTXDeviceManager = mTRTCCloud.getDeviceManager();
        mUserModel = UserModelManager.getInstance().getUserModel();
        TRTCCloudDef.TRTCParams trtcParams = new TRTCCloudDef.TRTCParams();
        trtcParams.sdkAppId = mUserModel.appId;
        trtcParams.userId = mUserId;
        trtcParams.roomId = Integer.parseInt(mRoomId);
        Log.d("userSig", mUserModel.userSig);
        trtcParams.userSig = mUserModel.userSig;

        mTRTCCloud.startLocalPreview(mIsFrontCamera, mTXCVVLocalPreviewView);
        mTRTCCloud.startLocalAudio(TRTCCloudDef.TRTC_AUDIO_QUALITY_SPEECH);
        mTRTCCloud.enterRoom(trtcParams, TRTCCloudDef.TRTC_APP_SCENE_VIDEOCALL);
    }

     V2TIMGroupListener mGroupListener = new  V2TIMGroupListener(){

        @Override
        public void onGroupDismissed(String groupID, V2TIMGroupMemberInfo opUser) {
            super.onGroupDismissed(groupID, opUser);
            ToastUtil.toastShortMessage("房间已解散");
        }
    };

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        MDTRxActivityTool.removeActivity(this);
        V2TIMManager.getInstance().removeGroupListener(mGroupListener);
        exitRoom();
    }

    private void exitRoom() {
        TRTCCalling.sharedInstance(this).mIsInRoom = false;
        if (mTRTCCloud != null) {
            mTRTCCloud.stopLocalAudio();
            mTRTCCloud.stopLocalPreview();
            mTRTCCloud.exitRoom();
            mTRTCCloud.setListener(null);
        }
        mTRTCCloud = null;
        TRTCCloud.destroySharedInstance();
    }

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

    }

    @Override
    protected void onPermissionGranted() {
        initView();
        enterRoom();
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.tv_leave) {
            showLeaveRoom();
        } else if (id == R.id.btn_audio) {
            muteAudio();
        } else if (id == R.id.btn_video) {
            muteVideo();
        }
    }


    /**
     * 操作摄像头打开或者关闭
     */
    private void muteVideo() {
        boolean isSelected = btnVideo.isSelected();
        if (isSelected) {
            mTRTCCloud.stopLocalPreview();
            ivVideo.setImageResource(R.drawable.trtccalling_ic_me_video_close);
            tvVideo.setText("摄像头已关闭");
            llMe.setVisibility(View.GONE);
        } else {
            mTRTCCloud.startLocalPreview(mIsFrontCamera, mTXCVVLocalPreviewView);
            ivVideo.setImageResource(R.drawable.trtccalling_ic_me_video_open);
            tvVideo.setText("摄像头已开启");
            llMe.setVisibility(View.VISIBLE);
        }
        btnVideo.setSelected(!isSelected);
    }

    /**
     * 操作麦克风开启或者关闭
     */
    private void muteAudio() {
        boolean isSelected = btnAudio.isSelected();
        if (!isSelected) {
            mTRTCCloud.muteLocalAudio(true);
            ivAudio.setImageResource(R.drawable.trtccalling_ic_me_audio_close);
            tvAudio.setText("麦克风已关闭");
            ivAudioMe.setImageResource(R.drawable.trtccalling_ic_other_audio_close);
        } else {
            mTRTCCloud.muteLocalAudio(false);
            ivAudio.setImageResource(R.drawable.trtccalling_ic_me_audio_open);
            tvAudio.setText("麦克风已开启");
            ivAudioMe.setImageResource(R.drawable.trtccalling_ic_other_audio_open);
        }
        btnAudio.setSelected(!isSelected);
    }

    /**
     * 转换摄像头
     */
    private void switchCamera() {
        mIsFrontCamera = !mIsFrontCamera;
        mTXDeviceManager.switchCamera(mIsFrontCamera);
        if (mIsFrontCamera) {
//            mButtonSwitchCamera.setText( "使用后置摄像头");
        } else {
//            mButtonSwitchCamera.setText("使用前置摄像头");
        }
    }

    /**
     * 听筒和扬声器切换
     */
    private void audioRoute() {
        if (mAudioRouteFlag) {
            mAudioRouteFlag = false;
            mTXDeviceManager.setAudioRoute(TXDeviceManager.TXAudioRoute.TXAudioRouteEarpiece);
//            mButtonAudioRoute.setText("使用扬声器");
        } else {
            mAudioRouteFlag = true;
            mTXDeviceManager.setAudioRoute(TXDeviceManager.TXAudioRoute.TXAudioRouteSpeakerphone);
//            mButtonAudioRoute.setText("使用听筒");
        }
    }

    @Override
    public void onBackPressed() {

    }

    private class TRTCCloudImplListener extends TRTCCloudListener {

        private WeakReference<VideoCallingActivity> mContext;

        public TRTCCloudImplListener(VideoCallingActivity activity) {
            super();
            mContext = new WeakReference<>(activity);
        }

        /**
         * 自己进入房间
         *
         * @param result
         */
        @Override
        public void onEnterRoom(long result) {
            super.onEnterRoom(result);
            TRTCCalling.sharedInstance(VideoCallingActivity.this).mIsInRoom = true;
            llMe.setVisibility(View.VISIBLE);
            if (mUserModel != null) {
                tvMe.setText(mUserModel.userName);
            }
        }


        /**
         * 离开房间
         */
        @Override
        public void onExitRoom(int reason) {
            super.onExitRoom(reason);
            TRTCCalling.sharedInstance(VideoCallingActivity.this).mIsInRoom = false;
            finish();
        }

        /**
         * 远端用户进入房间
         *
         * @param userId
         */
        @Override
        public void onRemoteUserEnterRoom(String userId) {
            super.onRemoteUserEnterRoom(userId);
            refreshRemoteUserName();
        }

        /**
         * 网络质量的实时统计回调
         *
         * @param localQuality
         * @param remoteQuality
         */
        @Override
        public void onNetworkQuality(TRTCCloudDef.TRTCQuality localQuality, ArrayList<TRTCCloudDef.TRTCQuality> remoteQuality) {
            Log.e(TAG, "网络质量的实时统计回调 userId:" + localQuality.userId + "uid:" + localQuality.quality + "quality:" + localQuality.quality);
            Log.e(TAG, "远端用户数量:" + remoteQuality.size());
            if (localQuality.quality == TRTCCloudDef.TRTC_VOICE_CHANGER_TYPE_0) {
                ivNetworkMe.setImageResource(R.drawable.trtccalling_ic_network_bad);
            } else if (localQuality.quality <= TRTCCloudDef.TRTC_VOICE_CHANGER_TYPE_3) {
                ivNetworkMe.setImageResource(R.drawable.trtccalling_ic_network_poor);
            } else if (localQuality.quality <= TRTCCloudDef.TRTC_VOICE_CHANGER_TYPE_8) {
                ivNetworkMe.setImageResource(R.drawable.trtccalling_ic_network_good);
            } else if (localQuality.quality <= TRTCCloudDef.TRTC_VOICE_CHANGER_TYPE_11) {
                ivNetworkMe.setImageResource(R.drawable.trtccalling_ic_network_excellent);
            }
            if (remoteQuality.size() > 0) {
                refreshRemoteUserNetWorkStatus(remoteQuality);
            }
        }

        /**
         * 音频麦克风开启或关闭回调
         *
         * @param userId
         * @param available
         */
        @Override
        public void onUserAudioAvailable(String userId, boolean available) {
            Log.e(TAG, "onUserAudioAvailable userId " + userId + ", mUserCount " + mUserCount + ",available " + available);
            if (!TextUtils.isEmpty(userId) && mRemoteUidList.size() > 0) {
                refreshRemoteUserAudioStatus(userId, available);
            }
        }

        /**
         * 视频开启或关闭回调
         *
         * @param userId
         * @param available
         */
        @Override
        public void onUserVideoAvailable(String userId, boolean available) {
            Log.e(TAG, "onUserVideoAvailable userId " + userId + ", mUserCount " + mUserCount + ",available " + available);
            int index = mRemoteUidList.indexOf(userId);
            if (available) {
                if (index != -1) {
                    return;
                }
                mRemoteUidList.add(userId);
            } else {
                if (index == -1) {
                    return;
                }
                mTRTCCloud.stopRemoteView(userId);
                mRemoteUidList.remove(index);
            }
            refreshRemoteVideoViews();
            refreshRemoteUserName();

        }

        private void refreshRemoteVideoViews() {
            for (int i = 0; i < mRemoteViewList.size(); i++) {
                if (i < mRemoteUidList.size()) {
                    String remoteUid = mRemoteUidList.get(i);
                    mRemoteViewList.get(i).setVisibility(View.VISIBLE);
                    mLlUserViewList.get(i).setVisibility(View.VISIBLE);
                    mTRTCCloud.startRemoteView(remoteUid, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_SMALL, mRemoteViewList.get(i));
                } else {
                    mRemoteViewList.get(i).setVisibility(View.GONE);
                    mLlUserViewList.get(i).setVisibility(View.GONE);
                }
            }
        }

        @Override
        public void onError(int errCode, String errMsg, Bundle extraInfo) {
            Log.d(TAG, "sdk callback onError");
            VideoCallingActivity activity = mContext.get();
            if (activity != null) {
                Toast.makeText(activity, "onError: " + errMsg + "[" + errCode + "]", Toast.LENGTH_SHORT).show();
                if (errCode == TXLiteAVCode.ERR_ROOM_ENTER_FAIL) {
                    activity.exitRoom();
                }
            }
        }
    }


    /**
     * 更新远端用户的麦开启或者关闭
     *
     * @param userId
     * @param available
     */
    private void refreshRemoteUserAudioStatus(String userId, boolean available) {
        for (int i = 0; i < mRemoteUidList.size(); i++) {
            if (userId.equals(mRemoteUidList.get(i))) {
                if (available) {
                    mIvAudioViewList.get(i).setImageResource(R.drawable.trtccalling_ic_other_audio_open);
                } else {
                    mIvAudioViewList.get(i).setImageResource(R.drawable.trtccalling_ic_other_audio_close);
                }
                return;
            }
        }
    }

    /**
     * 更新远端用户的网络状态
     *
     * @param remoteQuality
     */
    private void refreshRemoteUserNetWorkStatus(ArrayList<TRTCCloudDef.TRTCQuality> remoteQuality) {
        for (int i = 0; i < remoteQuality.size(); i++) {
            if (mLlUserViewList.get(i).getVisibility() == View.GONE) {
                mLlUserViewList.get(i).setVisibility(View.VISIBLE);
            }
            ImageView ivNetWorkView = mIvNetWorkViewList.get(i);
            int quality = remoteQuality.get(i).quality;
            if (quality == TRTCCloudDef.TRTC_VOICE_CHANGER_TYPE_0) {
                ivNetWorkView.setImageResource(R.drawable.trtccalling_ic_network_excellent);
            } else if (quality <= TRTCCloudDef.TRTC_VOICE_CHANGER_TYPE_3) {
                ivNetWorkView.setImageResource(R.drawable.trtccalling_ic_network_good);
            } else if (quality <= TRTCCloudDef.TRTC_VOICE_CHANGER_TYPE_8) {
                ivNetWorkView.setImageResource(R.drawable.trtccalling_ic_network_poor);
            } else if (quality <= TRTCCloudDef.TRTC_VOICE_CHANGER_TYPE_11) {
                ivNetWorkView.setImageResource(R.drawable.trtccalling_ic_network_bad);
            }
        }
    }

    /**
     * 更新远端用户的昵称
     */
    private void refreshRemoteUserName() {
        for (int i = 0; i < mRemoteUidList.size(); i++) {
            TextView tvName = mTvNameViewList.get(i);
            CallingInfoManager.getInstance().getUserInfoByUserId(mRemoteUidList.get(i), new CallingInfoManager.UserCallback() {
                @Override
                public void onSuccess(UserModel model) {
                    tvName.setText(model.userName);
                }

                @Override
                public void onFailed(int code, String msg) {
                    if (code == 206) {
                        ToastUtils.showLong("用户不存在");
                    } else {
                        ToastUtils.showLong(getString(R.string.trtccalling_toast_search_fail, msg));
                    }
                }
            });
        }
    }

    /**
     * 退出房间
     */
    private void showLeaveRoom() {
        final Dialog dialog = new Dialog(this, R.style.DialogStyle);
        dialog.setContentView(R.layout.dialog_leave_room);
        Button btnSure= dialog.findViewById(R.id.btn_sure);
        Button btnCancel = dialog.findViewById(R.id.btn_cancel);
        btnSure.setOnClickListener(v -> {
            exitRoom();
            finish();
        });
        btnCancel.setOnClickListener(v -> dialog.dismiss());
        dialog.show();
    }

}
