/**
 * 对讲功能 Helper
 * 从 EZRealPlayActivity 拆分出来，负责对讲的发起、停止、弹窗管理、状态回调等逻辑
 */
package com.videogo.ui.realplay.helper;

import android.Manifest;
import android.content.res.Configuration;

import com.videogo.errorlayer.ErrorInfo;
import com.videogo.exception.ErrorCode;
import com.videogo.openapi.EZConstants.EZTalkbackCapability;
import com.videogo.openapi.EZConstants.EZVoiceChangeType;
import com.videogo.realplay.RealPlayStatus;
import com.videogo.ui.common.EZBusinessTool;
import com.videogo.ui.common.EZStreamConfigLoader;
import com.videogo.ui.realplay.EZRealPlayActivity;
import com.videogo.ui.realplay.popWindow.TalkPopWindow;
import com.videogo.util.LogUtil;
import com.videogo.util.Utils;
import com.videogo.widget.bottommenu.BottomMenuFragment;

import android.widget.ImageButton;

import java.util.Arrays;
import java.util.List;

import ezviz.ezopensdk.R;
import ezviz.ezopensdkcommon.common.EZPermissionUtil;

/**
 * 对讲功能 Helper
 * 管理对讲的发起/停止、对讲弹窗的打开/关闭、对讲状态的回调处理
 *
 * 直接持有 Activity 引用，生命周期与 Activity 一致，无内存泄漏风险
 */
public class VoiceTalkHelper {

    private static final String TAG = "VoiceTalkHelper";

    private ImageButton mRealPlayTalkBtn;// 对讲按钮

    private final EZRealPlayActivity mActivity;// Activity 引用
    private TalkPopWindow mTalkPopupWindow;// 对讲弹窗
    private boolean mIsOnTalk = false;// 对讲中
    private boolean mIsStartingTalk = false;// 是否在启动对讲

    public VoiceTalkHelper(EZRealPlayActivity activity) {
        this.mActivity = activity;
        initView();
    }

    /**
     * 初始化对讲相关视图
     */
    private void initView() {
        mRealPlayTalkBtn = (ImageButton) mActivity.findViewById(R.id.realplay_talk_btn);
        mRealPlayTalkBtn.setEnabled(false);
        mRealPlayTalkBtn.setOnClickListener(v -> {
            EZPermissionUtil.requestPermissions(
                    mActivity,
                    new String[]{Manifest.permission.MODIFY_AUDIO_SETTINGS, Manifest.permission.RECORD_AUDIO},
                    1000,
                    () -> selectTalkbackItems()
            );
        });
    }

    // region --- 公开方法 ---

    /**
     * 对讲Action — 弹出选择对讲方式的菜单
     */
    public void selectTalkbackItems() {
        List<String> talkbackTypes = Arrays.asList(
                mActivity.getResources().getString(R.string.talkback_current_device),
                mActivity.getResources().getString(R.string.talkback_nvr_channel_device));
        new BottomMenuFragment(mActivity)
                .setHeadTitle(mActivity.getResources().getString(R.string.talkback_select_tip))
                .addMenuItems(talkbackTypes)
                .setOnItemClickListener(position -> {
                    if (position == 0) {// 当前设备对讲
                        startVoiceTalk(true);
                    } else {// 选择NVR-通道设备对讲
                        startVoiceTalk(false);
                    }
                })
                .show();
    }

    /**
     * 发起对讲
     * @param isDeviceTalkBack true:当前设备对讲  false:nvr下的ipc设备对讲
     */
    public void startVoiceTalk(boolean isDeviceTalkBack) {
        LogUtil.d(TAG, "startVoiceTalk");
        if (mActivity.mCameraInfo == null) {
            LogUtil.d(TAG, "mCameraInfo is null");
            return;
        }
        mIsOnTalk = true;
        mIsStartingTalk = true;

        mActivity.mOrientationHelper.updateOrientation();

        Utils.showToast(mActivity, R.string.start_voice_talk);
        mRealPlayTalkBtn.setEnabled(false);
        // 对讲开启前，关闭播放器的声音；否则画面码流和对讲码流中同时播放声音，导致回音
        // Turn off the sound of the player before starting the intercom; Otherwise,
        // playing sound simultaneously in both the picture stream and the intercom stream
        if (mActivity.mEZPlayer != null) {
            mActivity.mEZPlayer.closeSound();
        }
        mActivity.mEZPlayer.setVoiceTalkLoudnessCallback(v -> {
            LogUtil.d(TAG, "VoiceTalkLoudness--->" + v);
            mActivity.mHandler.post(() -> {
                if (mTalkPopupWindow != null) {
                    mTalkPopupWindow.setTalkLocalLoudness(v);
                }
            });
        }, 0.15f);
        // 加载对讲特殊配置，一般开发者可不用配置，按需设置
        EZStreamConfigLoader.loadVoicetalkSpecialConfigToPlayer(mActivity.mEZPlayer);
        mActivity.mEZPlayer.startVoiceTalk(isDeviceTalkBack);
    }

    /**
     * 停止对讲
     */
    public void stopVoiceTalk() {
        if (mActivity.mCameraInfo == null || mActivity.mEZPlayer == null) {
            return;
        }
        LogUtil.d(TAG, "stopVoiceTalk");

        mActivity.mEZPlayer.stopVoiceTalk();
        handleVoiceTalkStoped();
    }

    /**
     * 对讲成功后处理
     */
    public void handleVoiceTalkSucceed() {
        openTalkPopupWindow(true);
        mRealPlayTalkBtn.setEnabled(true);
    }

    /**
     * 对讲结束后处理
     */
    public void handleVoiceTalkStoped() {
        if (mIsOnTalk) {
            mIsOnTalk = false;
            mActivity.mOrientationHelper.setForceOrientation(0);
        }
        if (mActivity.mStatus == RealPlayStatus.STATUS_PLAY && mActivity.mEZPlayer != null) {
            if (mActivity.mLocalInfo.isSoundOpen()) {
                mActivity.mEZPlayer.openSound();
            } else {
                mActivity.mEZPlayer.closeSound();
            }
        }
    }

    /**
     * 对讲失败后处理
     */
    public void handleVoiceTalkFailed(ErrorInfo errorInfo) {
        LogUtil.d(TAG, "Talkback failed. " + errorInfo.toString());
        closeTalkPopupWindow(true);
        if (errorInfo.errorCode == ErrorCode.ERROR_CHANNEL_NO_SUPPORT_TALKBACK) {
            Utils.showToast(mActivity, R.string.device_no_support_talkback, errorInfo.errorCode);
        } else {
            Utils.showToast(mActivity, R.string.realplay_play_talkback_fail, errorInfo.errorCode);
        }
    }

    /**
     * 打开对讲弹窗
     */
    public void openTalkPopupWindow(boolean showAnimation) {
        int height = mActivity.mLocalInfo.getScreenHeight() - mActivity.mPortraitTitleBar.getHeight()
                - mActivity.mRealPlayPlayRl.getHeight()
                - (mActivity.mRealPlayRect != null ? mActivity.mRealPlayRect.top : mActivity.mLocalInfo.getNavigationBarHeight());
        mTalkPopupWindow = new TalkPopWindow(mActivity, mActivity.mRealPlayPlayRl, height,
                EZBusinessTool.isSupportTalk(mActivity.mDeviceInfo, mActivity.mCameraInfo) == EZTalkbackCapability.EZTalkbackFullDuplex);
        mTalkPopupWindow.setTalkPopupWindowListener(new TalkPopWindow.OnTalkPopupWindowListener() {
            @Override
            public void onVoiceTalkStatusChanged(boolean pressed) {
                mActivity.mEZPlayer.setVoiceTalkStatus(pressed);
            }

            @Override
            public void onVoiceTalkRemoteMuted(boolean muted) {
                mActivity.mEZPlayer.setTalkRemoteMuted(muted);
            }

            @Override
            public void onVoiceTalkVoiceChangeClick(EZVoiceChangeType voiceChangeType) {
                mActivity.mEZPlayer.startVoiceChange(voiceChangeType, (isSuccess, errorInfo) -> mActivity.mHandler.post(() -> {
                    if (isSuccess) {
                        Utils.showToast(mActivity, "voice change success");
                    } else {
                        String info = errorInfo != null ? "" + errorInfo.errorCode : "";
                        Utils.showToast(mActivity, "voice change failed. " + info);
                    }
                }));
            }

            public void onStopVoiceTalk() {
                stopVoiceTalk();
            }
        });
        mTalkPopupWindow.openTalkPopupWindow(showAnimation);
    }

    /**
     * 关闭对讲弹窗
     */
    public void closeTalkPopupWindow(boolean stopTalk) {
        if (mTalkPopupWindow != null) {
            mTalkPopupWindow.closeTalkPopupWindow(stopTalk);
        }
    }

    /**
     * 更新对讲UI（屏幕方向改变时调用）
     */
    public void updateTalkUI() {
        if (!mIsOnTalk) {
            return;
        }
        if (mActivity.mOrientation == Configuration.ORIENTATION_PORTRAIT) {
            mActivity.mHandler.post(() -> openTalkPopupWindow(false));
        } else {
            closeTalkPopupWindow(false);
        }
    }

    // endregion

    // region --- 状态查询 ---

    /**
     * 是否正在对讲中
     */
    public boolean isOnTalk() {
        return mIsOnTalk;
    }

    /**
     * 是否正在启动对讲
     */
    public boolean isStartingTalk() {
        return mIsStartingTalk;
    }

    /**
     * 重置启动对讲标记（开启预览时调用）
     */
    public void resetStartingTalk() {
        mIsStartingTalk = false;
    }

    /**
     * 设置对讲按钮可用状态
     */
    public void setTalkBtnEnabled(boolean enabled) {
        mRealPlayTalkBtn.setEnabled(enabled);
    }

    // endregion
}
