package com.yidianling.uikit.business.session.module.input;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Handler;
import android.os.SystemClock;
import android.text.Editable;
import android.text.InputType;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.blankj.utilcode.util.SPUtils;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.media.record.AudioRecorder;
import com.netease.nimlib.sdk.media.record.IAudioRecordCallback;
import com.netease.nimlib.sdk.media.record.RecordType;
import com.netease.nimlib.sdk.msg.MessageBuilder;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.CustomNotification;
import com.netease.nimlib.sdk.msg.model.CustomNotificationConfig;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.tbruyelle.rxpermissions2.Permission;
import com.tbruyelle.rxpermissions2.RxPermissions;
import com.ydl.ydlcommon.modular.ModularServiceManager;
import com.ydl.ydlcommon.utils.actionutil.ActionCountUtils;
import com.yidianling.common.tools.ToastUtil;
import com.yidianling.im.R;
import com.yidianling.im.bean.ContentBean;
import com.yidianling.im.event.MultipleSelectedEvent;
import com.yidianling.im.ui.adapter.FirstQuestionAdapter;
import com.yidianling.nimbase.api.UIKitOptions;
import com.yidianling.nimbase.api.model.session.SessionCustomization;
import com.yidianling.nimbase.business.session.actions.BaseAction;
import com.yidianling.nimbase.business.session.emoji.EmoticonPickerView;
import com.yidianling.nimbase.business.session.emoji.IEmoticonSelectedListener;
import com.yidianling.nimbase.business.session.emoji.MoonUtil;
import com.yidianling.nimbase.business.session.module.Container;
import com.yidianling.nimbase.common.ToastHelper;
import com.yidianling.nimbase.common.ui.dialog.EasyAlertDialogHelper;
import com.yidianling.nimbase.common.util.log.LogUtil;
import com.yidianling.nimbase.common.util.string.StringUtil;
import com.yidianling.uikit.api.NimUIKit;
import com.yidianling.uikit.api.NimUIKitImpl;
import com.yidianling.uikit.business.ait.AitTextChangeListener;
import com.yidianling.uikit.business.session.helper.ChatStatusCacheHelper;
import com.yidianling.uikit.custom.widget.SafeHelpRemindDialog;
import com.yidianling.user.api.service.IUserService;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import de.greenrobot.event.EventBus;
import io.reactivex.functions.Consumer;

/**
 * 底部文本编辑，语音等模块
 * Created by hzxuwen on 2015/6/16.
 */
public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallback, AitTextChangeListener {

    private static final String TAG = "MsgSendLayout";

    private static final int SHOW_LAYOUT_DELAY = 200;

    protected Container container;
    protected View view;
    protected Handler uiHandler;
    /***更多布局*/
    protected View actionPanelBottomLayout;
    protected LinearLayout messageActivityBottomLayout;
    /***文本消息编辑框*/
    protected EditText messageEditText;
    /***录音按钮*/
    protected Button audioRecordBtn;
    /***录音动画布局*/
    protected View audioAnimLayout;
    /***录音声音动画文件*/
    protected ImageView micImage;
    /***录音时取消显示图片*/
    protected ImageView mCancelImage;
    /***切换文本，语音按钮布局*/
    protected FrameLayout textAudioSwitchLayout;
    /***文本消息选择按钮*/
    protected View switchToTextButtonInInputBar;
    /***语音消息选择按钮*/
    protected View switchToAudioButtonInInputBar;
    /***更多消息选择按钮*/
    protected View moreFuntionButtonInInputBar;
    /***发送消息按钮*/
    protected View sendMessageButtonInInputBar;
    /***发送消息按钮*/
    protected View emojiButtonInInputBar;
    public View messageInputBar;
    protected View messageEditLL;
    protected FrameLayout audioTextSwitchLayout;

    private SessionCustomization customization;

    /***贴图表情控件*/
    protected EmoticonPickerView emoticonPickerView;

    /**首问语相关控件*/
    public ConstraintLayout clFirstQuestion;
    public RecyclerView rvFirstQuestion;
    private FirstQuestionAdapter firstQuestionAdapter;

    /***语音*/
    protected AudioRecorder audioMessageHelper;
    private Chronometer time;
    private TextView timerTip;
    private LinearLayout timerTipContainer;
    private boolean started = false;
    private boolean cancelled = false;
    /***是否按着*/
    private boolean touched = false;
    /***是否显示键盘*/
    private boolean isKeyboardShowed = true;
    /***存放录音动画文件*/
    private Drawable[] micImages;
    private static final int BASE = 600;
    /***间隔取样时间*/
    private static final int SPACE = 200;

    // state
    private boolean isTextAudioSwitchShow = true;

    // adapter
    private List<BaseAction> actions;

    // data
    private long typingTime = 0;

    private TextWatcher aitTextWatcher;
    private Activity context;
    private RxPermissions rxPermissions;

    private SafeHelpRemindDialog safeHelpRemindDialog = null;

    private String sendText = "";

    private Boolean onlyShowInputTest=false;//灵犀2.0 点击其他的时候隐藏除输入框以外的其他内容

    private String uid;

    /***设置输入框内容*/
    public void setInputContent(String content) {
        messageEditText.setText(content == null ? "" : content);
    }

    /***设置输入框hint内容*/
    public void setInputHintContent(String content) {
        messageEditText.setHint(content == null ? "" : content);
    }

    /***获取当前聊天输入框内容*/
    public String getInputContent() {
        return messageEditText.getText().toString();
    }

    public Container getContainer() {
        return container;
    }

    public InputPanel(Activity activity, Container container, View view, List<BaseAction> actions, boolean isTextAudioSwitchShow) {
        this.context = activity;
        this.container = container;
        this.view = view;
        this.actions = actions;
        this.uiHandler = new Handler();
        this.isTextAudioSwitchShow = isTextAudioSwitchShow;
        init();
    }

    public InputPanel(Container container, View view, List<BaseAction> actions, boolean isTextAudioSwitchShow) {
        this.container = container;
        this.view = view;
        this.actions = actions;
        this.uiHandler = new Handler();
        this.isTextAudioSwitchShow = isTextAudioSwitchShow;
        init();
    }

    public InputPanel(Activity activity, Container container, View view, List<BaseAction> actions) {
        this(activity, container, view, actions, true);
    }

    public void onPause() {
        // 停止录音
        if (audioMessageHelper != null) {
            onEndAudioRecord(true);
        }
    }

    public void onDestroy() {
        // release
        if (audioMessageHelper != null) {
            audioMessageHelper.destroyAudioRecorder();
        }
    }

    public boolean collapse(boolean immediately) {
        boolean respond = (emoticonPickerView != null && emoticonPickerView.getVisibility() == View.VISIBLE
                || actionPanelBottomLayout != null && actionPanelBottomLayout.getVisibility() == View.VISIBLE);

        hideAllInputLayout(immediately);

        return respond;
    }

    public void addAitTextWatcher(TextWatcher watcher) {
        aitTextWatcher = watcher;
    }

    private void init() {
        uid = ModularServiceManager.INSTANCE.provide(IUserService.class).getUserInfo().getUid();
        initViews();
        initInputBarListener();
        initTextEdit();
        initAudioRecordButton();
        restoreText(false);
        rxPermissions = new RxPermissions(context);

        initActionPanel();
    }

    public void setCustomization(SessionCustomization customization) {
        this.customization = customization;
        if (customization != null) {
            emoticonPickerView.setWithSticker(customization.withSticker);
        }
    }

    public void reload(Container container, SessionCustomization customization) {
        this.container = container;
        setCustomization(customization);
    }

    private void initViews() {
        // input bar
        messageActivityBottomLayout = view.findViewById(R.id.messageActivityBottomLayout);
        messageInputBar = view.findViewById(R.id.textMessageLayout);
        switchToTextButtonInInputBar = view.findViewById(R.id.buttonTextMessage);
        switchToAudioButtonInInputBar = view.findViewById(R.id.buttonAudioMessage);
        moreFuntionButtonInInputBar = view.findViewById(R.id.buttonMoreFuntionInText);
        emojiButtonInInputBar = view.findViewById(R.id.emoji_button);
        sendMessageButtonInInputBar = view.findViewById(R.id.buttonSendMessage);
        messageEditText = view.findViewById(R.id.editTextMessage);
        messageEditLL = view.findViewById(R.id.ll_ed);
        audioTextSwitchLayout=view.findViewById(R.id.audioTextSwitchLayout);
        // 语音
        audioRecordBtn = view.findViewById(R.id.audioRecord);
        micImage = (ImageView) view.findViewById(R.id.img_antation);
        mCancelImage = (ImageView) view.findViewById(R.id.img_cancel);
        audioAnimLayout = view.findViewById(R.id.layoutPlayAudio);
        time = view.findViewById(R.id.timer);
        timerTip = view.findViewById(R.id.timer_tip);
        timerTipContainer = view.findViewById(R.id.timer_tip_container);

        // 表情
        emoticonPickerView = view.findViewById(R.id.emoticon_picker_view);

        // 显示录音按钮
        switchToTextButtonInInputBar.setVisibility(View.GONE);
        switchToAudioButtonInInputBar.setVisibility(View.VISIBLE);

        // 文本录音按钮切换布局
        textAudioSwitchLayout = view.findViewById(R.id.switchLayout);
        if (isTextAudioSwitchShow) {
            textAudioSwitchLayout.setVisibility(View.VISIBLE);
        } else {
            textAudioSwitchLayout.setVisibility(View.GONE);
        }
        initVoice();
        // 首问语控件初始化
        initFirstQuestion();
    }

    private void initFirstQuestion() {
        clFirstQuestion = view.findViewById(R.id.cl_first_question);
        rvFirstQuestion = view.findViewById(R.id.rv_first_question);
        firstQuestionAdapter = new FirstQuestionAdapter(new ArrayList<>());
        rvFirstQuestion.setLayoutManager(new LinearLayoutManager(context));
        rvFirstQuestion.setAdapter(firstQuestionAdapter);
        firstQuestionAdapter.setOnItemClickListener((adapter, view, position) -> {
            String content = firstQuestionAdapter.getData().get(position).getContent();
            // 埋点
            ActionCountUtils.Companion.baiDuCountSign3("counselor_consult_page","quick_language_click",content,"","");
            onTextMessageSendButtonPressed(content);
            clFirstQuestion.setVisibility(View.GONE);
        });
    }

    /**
     * 设置首问语数据
     * @param data
     */
    public void setFirstQuestion(List<ContentBean> data){
        clFirstQuestion.setVisibility(View.VISIBLE);
        firstQuestionAdapter.getData().addAll(data);
        firstQuestionAdapter.notifyDataSetChanged();
    }

    private void initVoice() {
        // 动画资源文件,用于录制语音时
        micImages = new Drawable[]{
                context.getResources().getDrawable(R.mipmap.im_voice_search_feedback001),
                context.getResources().getDrawable(R.mipmap.im_voice_search_feedback002),
                context.getResources().getDrawable(R.mipmap.im_voice_search_feedback003),
                context.getResources().getDrawable(R.mipmap.im_voice_search_feedback004),
                context.getResources().getDrawable(R.mipmap.im_voice_search_feedback005),
                context.getResources().getDrawable(R.mipmap.im_voice_search_feedback006),
                context.getResources().getDrawable(R.mipmap.im_voice_search_feedback007),
                context.getResources().getDrawable(R.mipmap.im_voice_search_feedback008)
        };
    }


    private void initInputBarListener() {
        switchToTextButtonInInputBar.setOnClickListener(clickListener);
        switchToAudioButtonInInputBar.setOnClickListener(clickListener);
        emojiButtonInInputBar.setOnClickListener(clickListener);
        sendMessageButtonInInputBar.setOnClickListener(clickListener);
        moreFuntionButtonInInputBar.setOnClickListener(clickListener);
    }

    private void initTextEdit() {
        messageEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE);
        messageEditText.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    switchToTextLayout(true);
                }
                return false;
            }
        });

        messageEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {

            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                checkSendButtonEnable(messageEditText);
            }
        });

        messageEditText.addTextChangedListener(new TextWatcher() {
            private int start;
            private int count;

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                this.start = start;
                this.count = count;
                if (aitTextWatcher != null) {
                    aitTextWatcher.onTextChanged(s, start, before, count);
                }
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                if (aitTextWatcher != null) {
                    aitTextWatcher.beforeTextChanged(s, start, count, after);
                }
            }

            @Override
            public void afterTextChanged(Editable s) {
                checkSendButtonEnable(messageEditText);
                MoonUtil.replaceEmoticons(container.activity, s, start, count);

                int editEnd = messageEditText.getSelectionEnd();
                messageEditText.removeTextChangedListener(this);
                while (StringUtil.counterChars(s.toString()) > NimUIKitImpl.getOptions().maxInputTextLength && editEnd > 0) {
                    s.delete(editEnd - 1, editEnd);
                    editEnd--;
                }
                messageEditText.setSelection(editEnd);
                messageEditText.addTextChangedListener(this);

                if (aitTextWatcher != null) {
                    aitTextWatcher.afterTextChanged(s);
                }

                sendTypingCommand();
            }
        });
    }


    /**
     * 发送“正在输入”通知
     */
    private void sendTypingCommand() {
        if (container.account.equals(NimUIKit.getAccount())) {
            return;
        }

        if (container.sessionType == SessionTypeEnum.Team || container.sessionType == SessionTypeEnum.ChatRoom) {
            return;
        }

        if (System.currentTimeMillis() - typingTime > 5000L) {
            typingTime = System.currentTimeMillis();
            CustomNotification command = new CustomNotification();
            command.setSessionId(container.account);
            command.setSessionType(container.sessionType);
            CustomNotificationConfig config = new CustomNotificationConfig();
            config.enablePush = false;
            config.enableUnreadCount = false;
            command.setConfig(config);

            JSONObject json = new JSONObject();
            json.put("id", "1");
            command.setContent(json.toString());

            NIMClient.getService(MsgService.class).sendCustomNotification(command);
        }
    }

    /**
     * ************************* 键盘布局切换 *******************************
     */

    private View.OnClickListener clickListener = new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            //验证用户是否已经绑定手机，若没有绑定则弹出提示

            // 账户信息是null时  判断是否是聊天室  不是聊天室提示用户退出重试
//            if (ActionHandlerStorage.getL(container.account) == null && container.sessionType != SessionTypeEnum.ChatRoom) {
//                ToastUtil.toastShort("请退出聊天界面重试");
//                return;
//            }

            if (v == switchToTextButtonInInputBar) {
                switchToTextLayout(true);// 显示文本发送的布局
            } else if (v == sendMessageButtonInInputBar) {
                if (onlyShowInputTest){
                    EventBus.getDefault().post(new MultipleSelectedEvent(null, null,
                            null,true,false));
                }else{
                    onTextMessageSendButtonPressed();
                }
            } else if (v == switchToAudioButtonInInputBar) {
                rxPermissions.requestEach(Manifest.permission.RECORD_AUDIO)
                        .subscribe(new Consumer<Permission>() {
                            @Override
                            public void accept(Permission permission) {
                                if (permission.granted) {
                                    switchToAudioLayout();
                                } else if (permission.shouldShowRequestPermissionRationale) {
                                    ToastUtil.toastShort("权限被拒绝，无法开始录音");
                                } else {
                                    ToastUtil.toastShort("请到应用设置中开启录音权限");
                                }
                            }
                        });
            } else if (v == moreFuntionButtonInInputBar) {
                toggleActionPanelLayout();
            } else if (v == emojiButtonInInputBar) {
                toggleEmojiLayout();
            }

        }
    };

    // 点击edittext，切换键盘和更多布局
    private void switchToTextLayout(boolean needShowInput) {
        hideEmojiLayout();
        hideFirstQuestionLayout();
        hideActionPanelLayout();

        audioRecordBtn.setVisibility(View.GONE);
        messageEditText.setVisibility(View.VISIBLE);
        messageEditLL.setVisibility(View.VISIBLE);
        switchToTextButtonInInputBar.setVisibility(View.GONE);
        switchToAudioButtonInInputBar.setVisibility(View.VISIBLE);

        messageInputBar.setVisibility(View.VISIBLE);

        if (needShowInput) {
            uiHandler.postDelayed(showTextRunnable, SHOW_LAYOUT_DELAY);
        } else {
            hideInputMethod();
        }
    }

    // 发送文本消息
    private void onTextMessageSendButtonPressed() {
        String text = messageEditText.getText().toString();

        replaceText(text, new TextReplaceCallback() {
            @Override
            public void isBeReplace() {
                //自我保护弹框提醒用户是否继续发送
                showRemindDialog();
            }

            @Override
            public void notBeReplace() {
                onTextMessageSendButtonClick();
            }
        });

    }

    //自我保护弹框提醒用户是否继续发送
    private void showRemindDialog() {
        if (safeHelpRemindDialog == null) {
            safeHelpRemindDialog = new SafeHelpRemindDialog(context, new SafeHelpRemindDialog.SafeHelpRemindListener() {
                @Override
                public void sureClick() {
                    safeHelpRemindDialog.hide();
                    onTextMessageSendButtonClick();
                }
            });
        }
        safeHelpRemindDialog.show();
    }

    /**
     * 替换之后最终发送的字符串
     */
    private void onTextMessageSendButtonClick() {
        IMMessage textMessage = createTextMessage(sendText);
        if (container.proxy.sendMessage(textMessage)) {
            restoreText(true);
        }
    }

    interface TextReplaceCallback {
        void isBeReplace();

        void notBeReplace();
    }

    /**
     * 判定是否需要将长数字字符串部分替换为****
     *
     * @param text
     * @param callback
     */
    private void replaceText(String text, TextReplaceCallback callback) {
        String lastText = "";

        int numberIndex = -1;
        int numberCount = 0;
        boolean isBeReplace = false;
        for (int i = 0; i < text.length(); i++) {

            if (text.charAt(i) >= 48 && text.charAt(i) <= 57) {
                numberIndex = i;
                for (int j = i; j < text.length(); j++) {
                    if (text.charAt(j) >= 48 && text.charAt(j) <= 57) {
                        numberCount++;
                        if (j == text.length() - 1) {
                            if (numberCount >= 5) {
                                isBeReplace = true;
                                while (i < numberIndex + numberCount / 3) {
                                    lastText += text.charAt(i++);
                                }
                                while (i < numberIndex + numberCount / 3 + 4) {
                                    lastText += "*";
                                    i++;
                                }
                                while (i <= j) {
                                    lastText += text.charAt(i++);
                                }
                            } else {
                                while (i <= j) {
                                    lastText += text.charAt(i++);
                                }
                            }

                            i = j;
                            break;
                        }
                    } else {
                        if (numberCount >= 5) {
                            isBeReplace = true;
                            while (i < numberIndex + numberCount / 3) {
                                lastText += text.charAt(i++);
                            }
                            while (i < numberIndex + numberCount / 3 + 4) {
                                lastText += "*";
                                i++;
                            }
                            while (i < j) {
                                lastText += text.charAt(i++);
                            }
                        } else {
                            while (i < j) {
                                lastText += text.charAt(i++);
                            }
                        }

                        i = j - 1;
                        numberIndex = -1;
                        numberCount = 0;
                        break;
                    }
                }
            } else {
                lastText += text.charAt(i);
            }
        }
        if (isBeReplace) {
            sendText = lastText;
            callback.isBeReplace();
        } else {
            sendText = text;
            callback.notBeReplace();
        }
    }

    protected IMMessage createTextMessage(String text) {
        IMMessage msg = MessageBuilder.createTextMessage(container.account, container.sessionType, text);
        Map<String, Object> payload = new HashMap<>();
        fillHwPayload(payload, NimUIKit.getAccount(), container.sessionType.getValue());
        fillOppoPayload(payload, NimUIKit.getAccount(), container.sessionType.getValue());
        fillVivoPayload(payload, NimUIKit.getAccount(), container.sessionType.getValue());
        fillApnsPayload(payload, NimUIKit.getAccount(), container.sessionType.getValue());
        msg.setPushPayload(payload);
        return msg;
    }

    private void fillApnsPayload(Map<String, Object> pushPayload, String sessionId, int sessionType) {
        try {
            Map<String, Object> apns = new HashMap<>();
            apns.put("toUid", sessionId);
            apns.put("sessionType", sessionType);
            apns.put("chatType", 1);
            String json = JSON.toJSONString(apns);
            String encode = URLEncoder.encode(json, "UTF-8");
            String finalUrl = "ydl-user://chat/private?params=" + encode;
            pushPayload.put("route_ios", finalUrl);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
    private void fillHwPayload(Map<String, Object> pushPayload, String sessionId, int sessionType) {
        //华为
        Intent hwIntent = new Intent(Intent.ACTION_VIEW);
        String intentStr = String.format(
                "im://ydl.com/session?sessionId=%s&sessionType=%s",
                sessionId,  // 发送者的account 或  群聊id
                sessionType // 类型（单聊或群聊）
        );
        hwIntent.setData(Uri.parse(intentStr));
        hwIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        String intentUri = hwIntent.toUri(Intent.URI_INTENT_SCHEME);
//点击事件的内容
        JSONObject clickAction = new JSONObject();
//通知的内容
        JSONObject notification = new JSONObject();

        try {
            clickAction.fluentPut("type", 1)
                    .put("intent", intentUri);
            notification.put("click_action", clickAction);
            pushPayload.put("hwField", notification);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void fillVivoPayload(Map<String, Object> pushPayload, String sessionId, int sessionType) {
        Map<String, Object> vivoField = new HashMap<>();
        vivoField.put("classification", 1);
        vivoField.put("skipType", 3);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        String intentStr = String.format(
                "im://ydl.com/session?sessionId=%s&sessionType=%s",
                sessionId,  // 发送者的account 或  群聊id
                sessionType // 类型（单聊或群聊）
        );
        intent.setData(Uri.parse(intentStr));
        String intentUri = intent.toUri(Intent.URI_INTENT_SCHEME);
        vivoField.put("skipContent", intentUri);
        pushPayload.put("vivoField", vivoField);
    }

    private void fillOppoPayload(Map<String, Object> pushPayload, String sessionId, int sessionType) {
        Map<String, Object> oppoField = new HashMap<>();
        String intentStr = String.format(
                "im://ydl.com/session?sessionId=%s&sessionType=%s",
                sessionId,  // 发送者的account 或  群聊id
                sessionType // 类型（单聊或群聊）
        );
        oppoField.put("click_action_type", 5);
        oppoField.put("click_action_url", intentStr);
        oppoField.put("channel_id", "nim_message_channel_001");
        pushPayload.put("oppoField", oppoField);
    }

    /**
     * 切换成音频，收起键盘，按钮切换成键盘
     */
    private void switchToAudioLayout() {
        messageEditText.setVisibility(View.GONE);
        audioRecordBtn.setVisibility(View.VISIBLE);
        messageEditLL.setVisibility(View.GONE);
        hideInputMethod();
        hideEmojiLayout();
        hideFirstQuestionLayout();
        hideActionPanelLayout();

        switchToAudioButtonInInputBar.setVisibility(View.GONE);
        switchToTextButtonInInputBar.setVisibility(View.VISIBLE);
    }

    /**
     * 点击“+”号按钮，切换更多布局和键盘
     */
    private void toggleActionPanelLayout() {
        if (actionPanelBottomLayout == null || actionPanelBottomLayout.getVisibility() == View.GONE) {
            showActionPanelLayout();
        } else {
            hideActionPanelLayout();
        }
    }

    /**
     * 点击表情，切换到表情布局
     */
    private void toggleEmojiLayout() {
        if (emoticonPickerView == null || emoticonPickerView.getVisibility() == View.GONE) {
            showEmojiLayout();
        } else {
            hideEmojiLayout();
        }
    }

    /**
     * 隐藏表情布局
     */
    private void hideEmojiLayout() {
        uiHandler.removeCallbacks(showEmojiRunnable);
        if (emoticonPickerView != null) {
            emoticonPickerView.setVisibility(View.GONE);
        }
    }

    /**
     * 隐藏首问语布局
     */
    public void hideFirstQuestionLayout(){
        uiHandler.removeCallbacks(showFirstQuestionRunnable);
        if (clFirstQuestion != null) {
            clFirstQuestion.setVisibility(View.GONE);
        }
    }

    /**
     * 隐藏更多布局
     */
    private void hideActionPanelLayout() {
        uiHandler.removeCallbacks(showMoreFuncRunnable);
        if (actionPanelBottomLayout != null) {
            actionPanelBottomLayout.setVisibility(View.GONE);
        }
    }

    /**
     * 隐藏键盘布局
     */
    public void hideInputMethod() {
        isKeyboardShowed = false;
        uiHandler.removeCallbacks(showTextRunnable);
        InputMethodManager imm = (InputMethodManager) container.activity.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(messageEditText.getWindowToken(), 0);
        messageEditText.clearFocus();
    }
    /**
     * 灵犀-点击其他时候-只显示输入框，不显示其他选项
     */
    public void onlyShowTextStart() {
        hideAudioLayout();
        showInputMethod(messageEditText);
        onlyShowInputTest=true;
        //隐藏左边语音布局
        textAudioSwitchLayout.setVisibility(View.INVISIBLE);
        //隐藏右边表情和加号布局
        emojiButtonInInputBar.setVisibility(View.GONE);
        sendMessageButtonInInputBar.setVisibility(View.VISIBLE);
        messageEditText.setVisibility(View.VISIBLE);
    }
    /**
     * 灵犀-点击其他时候-只显示输入框，不显示其他选项
     */
    public void onlyShowTextEnd() {
        onlyShowInputTest=false;
        //隐藏左边语音布局
        textAudioSwitchLayout.setVisibility(View.VISIBLE);
        //隐藏右边表情和加号布局
        emojiButtonInInputBar.setVisibility(View.VISIBLE);
        moreFuntionButtonInInputBar.setVisibility(View.GONE);
    }

    /**
     * 隐藏语音布局
     */
    private void hideAudioLayout() {
        audioRecordBtn.setVisibility(View.GONE);
        messageEditText.setVisibility(View.VISIBLE);
        messageEditLL.setVisibility(View.VISIBLE);
        switchToTextButtonInInputBar.setVisibility(View.VISIBLE);
        switchToAudioButtonInInputBar.setVisibility(View.GONE);
    }

    /**
     * 显示表情布局
     */
    private void showEmojiLayout() {
        hideFirstQuestionLayout();
        hideInputMethod();
        hideActionPanelLayout();
        hideAudioLayout();

        messageEditText.requestFocus();
        uiHandler.postDelayed(showEmojiRunnable, 200);
        emoticonPickerView.setVisibility(View.VISIBLE);
        emoticonPickerView.show(this);
        container.proxy.onInputPanelExpand();
    }


    /**
     * 初始化更多布局
     */
    private void initActionPanel() {
        for (int i = 0; i < actions.size(); ++i) {
            actions.get(i).setIndex(i);
            actions.get(i).setContainer(container);
        }
        if (actionPanelBottomLayout == null) {
            View.inflate(container.activity, R.layout.im_nim_message_activity_actions_layout, messageActivityBottomLayout);
            actionPanelBottomLayout = view.findViewById(R.id.actionsLayout);
            ActionsPanel.init(view, actions);
        }
    }

    /**
     * 显示键盘布局
     */
    private void showInputMethod(EditText editTextMessage) {
        editTextMessage.requestFocus();
        //如果已经显示,则继续操作时不需要把光标定位到最后
        if (!isKeyboardShowed) {
            editTextMessage.setSelection(editTextMessage.getText().length());
            isKeyboardShowed = true;
        }

        InputMethodManager imm = (InputMethodManager) container.activity.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(editTextMessage, 0);

        container.proxy.onInputPanelExpand();
    }
    /**
     * 显示更多布局
     */
    private void showActionPanelLayout() {
        hideEmojiLayout();
        hideFirstQuestionLayout();
        hideInputMethod();

        uiHandler.postDelayed(showMoreFuncRunnable, SHOW_LAYOUT_DELAY);
        container.proxy.onInputPanelExpand();
    }

    private Runnable showEmojiRunnable = new Runnable() {
        @Override
        public void run() {
            emoticonPickerView.setVisibility(View.VISIBLE);
        }
    };

    private Runnable showFirstQuestionRunnable = new Runnable() {
        @Override
        public void run() {
            clFirstQuestion.setVisibility(View.VISIBLE);
        }
    };

    private Runnable showMoreFuncRunnable = new Runnable() {
        @Override
        public void run() {
            actionPanelBottomLayout.setVisibility(View.VISIBLE);
        }
    };

    private Runnable showTextRunnable = new Runnable() {
        @Override
        public void run() {
            showInputMethod(messageEditText);
        }
    };

    private void restoreText(boolean clearText) {
        if (clearText) {
            messageEditText.setText("");
        }

        checkSendButtonEnable(messageEditText);
    }

    /**
     * 显示发送或更多
     *
     * @param editText
     */
    protected void checkSendButtonEnable(EditText editText) {
        String textMessage = editText.getText().toString();
        if (!TextUtils.isEmpty(StringUtil.removeBlanks(textMessage)) && editText.hasFocus()) {
            moreFuntionButtonInInputBar.setVisibility(View.GONE);
            sendMessageButtonInInputBar.setVisibility(View.VISIBLE);
        } else {
            sendMessageButtonInInputBar.setVisibility(View.GONE);
            if (!onlyShowInputTest){
                moreFuntionButtonInInputBar.setVisibility(View.VISIBLE);
            }
        }
    }

    /**
     * *************** IEmojiSelectedListener ***************
     */
    @Override
    public void onEmojiSelected(String key) {
        Editable mEditable = messageEditText.getText();
        if ("/DEL".equals(key)) {
            messageEditText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));
        } else {
            int start = messageEditText.getSelectionStart();
            int end = messageEditText.getSelectionEnd();
            start = (start < 0 ? 0 : start);
            end = (start < 0 ? 0 : end);
            mEditable.replace(start, end, key);
        }
    }

    private Runnable hideAllInputLayoutRunnable;

    @Override
    public void onStickerSelected(String category, String item) {
        Log.i("InputPanel", "onStickerSelected, category =" + category + ", sticker =" + item);

        if (customization != null) {
            MsgAttachment attachment = customization.createStickerAttachment(category, item);
            IMMessage stickerMessage = MessageBuilder.createCustomMessage(container.account, container.sessionType, "贴图消息", attachment);
            container.proxy.sendMessage(stickerMessage);
        }
    }

    @Override
    public void onTextAdd(String content, int start, int length) {
        if (messageEditText.getVisibility() != View.VISIBLE ||
                (emoticonPickerView != null && emoticonPickerView.getVisibility() == View.VISIBLE)) {
            switchToTextLayout(true);
        } else {
            uiHandler.postDelayed(showTextRunnable, SHOW_LAYOUT_DELAY);
        }
        messageEditText.getEditableText().insert(start, content);
    }

    @Override
    public void onTextDelete(int start, int length) {
        if (messageEditText.getVisibility() != View.VISIBLE) {
            switchToTextLayout(true);
        } else {
            uiHandler.postDelayed(showTextRunnable, SHOW_LAYOUT_DELAY);
        }
        int end = start + length - 1;
        messageEditText.getEditableText().replace(start, end, "");
    }

    public int getEditSelectionStart() {
        return messageEditText.getSelectionStart();
    }


    /**
     * 隐藏所有输入布局
     */
    private void hideAllInputLayout(boolean immediately) {

        if (hideAllInputLayoutRunnable == null) {
            hideAllInputLayoutRunnable = new Runnable() {

                @Override
                public void run() {
                    hideInputMethod();
                    hideActionPanelLayout();
                    hideEmojiLayout();
                    hideFirstQuestionLayout();
                }
            };
        }
        long delay = immediately ? 0 : ViewConfiguration.getDoubleTapTimeout();
        uiHandler.postDelayed(hideAllInputLayoutRunnable, delay);
    }

    /**
     * ****************************** 语音 ***********************************
     */
    private void initAudioRecordButton() {
        audioRecordBtn.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    touched = true;
                    initAudioRecord();
                    onStartAudioRecord();
                } else if (event.getAction() == MotionEvent.ACTION_CANCEL
                        || event.getAction() == MotionEvent.ACTION_UP) {
                    touched = false;
                    onEndAudioRecord(isCancelled(v, event));
                } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                    touched = true;
                    cancelAudioRecord(isCancelled(v, event));
                }

                return false;
            }
        });
    }

    // 上滑取消录音判断
    private static boolean isCancelled(View view, MotionEvent event) {
        int[] location = new int[2];
        view.getLocationOnScreen(location);

        if (event.getRawX() < location[0] || event.getRawX() > location[0] + view.getWidth()
                || event.getRawY() < location[1] - 40) {
            return true;
        }

        return false;
    }

    /**
     * 初始化AudioRecord
     */
    private void initAudioRecord() {
        if (audioMessageHelper == null) {
            UIKitOptions options = NimUIKitImpl.getOptions();
            audioMessageHelper = new AudioRecorder(container.activity, options.audioRecordType, 60, this);
        }
    }

    /**
     * 开始语音录制
     */
    private void onStartAudioRecord() {
        container.activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        audioMessageHelper.startRecord();
        cancelled = false;
    }

    /**
     * 结束语音录制
     *
     * @param cancel
     */
    private void onEndAudioRecord(boolean cancel) {
        started = false;
        container.activity.getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        audioMessageHelper.completeRecord(cancel);
        audioRecordBtn.setText(R.string.im_record_audio);
        audioRecordBtn.setBackgroundResource(R.drawable.im_nim_chat_audio_record_button_background);
        stopAudioRecordAnim();
    }

    /**
     * 取消语音录制
     *
     * @param cancel
     */
    private void cancelAudioRecord(boolean cancel) {
        // reject
        if (!started) {
            return;
        }
        // no change
        if (cancelled == cancel) {
            return;
        }

        cancelled = cancel;
        updateTimerTip(cancel);
    }

    /**
     * 正在进行语音录制和取消语音录制，界面展示
     *
     * @param cancel
     */
    private void updateTimerTip(boolean cancel) {
        if (cancel) {
            micImage.setVisibility(View.GONE);
            mCancelImage.setVisibility(View.VISIBLE);
            timerTip.setText(R.string.im_recording_cancel_tip);
            timerTipContainer.setBackgroundResource(R.drawable.im_nim_cancel_record_red_bg);
        } else {
            micImage.setVisibility(View.VISIBLE);
            mCancelImage.setVisibility(View.GONE);
            timerTip.setText(R.string.im_recording_cancel);
            timerTipContainer.setBackgroundResource(0);
        }
    }

    /**
     * 开始语音录制动画
     */
    private void playAudioRecordAnim() {
        audioAnimLayout.setVisibility(View.VISIBLE);
        time.setBase(SystemClock.elapsedRealtime());
        time.start();
        updateMicStatus();
    }

    /**
     * 结束语音录制动画
     */
    private void stopAudioRecordAnim() {
        audioAnimLayout.setVisibility(View.GONE);
        time.stop();
        time.setBase(SystemClock.elapsedRealtime());
    }

    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(android.os.Message msg) {
            int what = msg.what;
            //根据mHandler发送what的大小决定话筒的图片是哪一张
            //说话声音越大,发送过来what值越大
            if (what >= micImages.length) {
                what = micImages.length - 1;
            }
            micImage.setImageDrawable(micImages[what]);
        }

        ;
    };

    private Runnable mUpdateMicStatusTimer = new Runnable() {
        @Override
        public void run() {
            updateMicStatus();
        }
    };

    /**
     * 更新录音声音大小状态
     */
    private void updateMicStatus() {
        if (audioMessageHelper != null) {
            if (touched) {
                int ratio = audioMessageHelper.getCurrentRecordMaxAmplitude() / BASE;
                int db = 0;// 分贝
                if (ratio > 1) {
                    db = (int) (20 * Math.log10(ratio));
                }
                Log.e("hzs", "分贝值：" + db + "     " + Math.log10(ratio));
                //对着手机说话声音最大的时候，db达到了35左右
                mHandler.postDelayed(mUpdateMicStatusTimer, SPACE);
                //
                if (db / 3 >= micImages.length) {
                    mHandler.sendEmptyMessage(micImages.length - 1);
                } else {
                    mHandler.sendEmptyMessage(db / 3);
                }
            }
        }
    }

    /**
     * 录音状态回调
     */
    @Override
    public void onRecordReady() {

    }

    @Override
    public void onRecordStart(File audioFile, RecordType recordType) {
        started = true;
        if (!touched) {
            return;
        }

        audioRecordBtn.setText(R.string.im_record_audio_end);
        audioRecordBtn.setBackgroundResource(R.drawable.im_nim_chat_audio_record_button_background);

        updateTimerTip(false); // 初始化语音动画状态
        playAudioRecordAnim();
    }

    @Override
    public void onRecordSuccess(File audioFile, long audioLength, RecordType recordType) {
        IMMessage audioMessage = MessageBuilder.createAudioMessage(container.account, container.sessionType, audioFile, audioLength);
        container.proxy.sendMessage(audioMessage);
    }

    @Override
    public void onRecordFail() {
        if (started) {
            ToastHelper.showToast(container.activity, R.string.im_recording_error);
        }
    }

    @Override
    public void onRecordCancel() {

    }

    @Override
    public void onRecordReachedMaxTime(final int maxTime) {
        stopAudioRecordAnim();
        EasyAlertDialogHelper.createOkCancelDiolag(container.activity, "", container.activity.getString(R.string.im_recording_max_time), false, new EasyAlertDialogHelper.OnDialogActionListener() {
            @Override
            public void doCancelAction() {
            }

            @Override
            public void doOkAction() {
                audioMessageHelper.handleEndRecord(true, maxTime);
            }
        }).show();
    }

    public boolean isRecording() {
        return audioMessageHelper != null && audioMessageHelper.isRecording();
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != Activity.RESULT_OK) {
            return;
        }
        int index = (requestCode << 16) >> 24;
        if (index != 0) {
            index--;
            if (index < 0 | index >= actions.size()) {
                LogUtil.d(TAG, "request code out of actions' range");
                return;
            }
            BaseAction action = actions.get(index);
            if (action != null) {
                action.onActivityResult(requestCode & 0xff, resultCode, data);
            }
        }
    }

    public void setVisible(boolean visible) {
        if (visible) {
            messageActivityBottomLayout.setVisibility(View.VISIBLE);
        } else {
            messageActivityBottomLayout.setVisibility(View.INVISIBLE);
        }
    }

    /**
     * 发送文本消息
     */
    public void onTextMessageSendButtonPressed(String text) {
        if (text.isEmpty()) {
            ToastUtil.toastShort(container.activity, "请输入后再发送");
            return;
        }
        IMMessage textMessage = createTextMessage(text);

        if (container.proxy.sendMessage(textMessage)) {
            restoreText(true);
        }
    }
}
