package com.yidianling.uikit.business.session.fragment;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.StateListDrawable;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.constraint.ConstraintLayout;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.alibaba.fastjson.JSON;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.Observer;
import com.netease.nimlib.sdk.RequestCallback;
import com.netease.nimlib.sdk.ResponseCode;
import com.netease.nimlib.sdk.msg.MessageBuilder;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.MsgServiceObserve;
import com.netease.nimlib.sdk.msg.constant.MsgStatusEnum;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.CustomMessageConfig;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.msg.model.MemberPushOption;
import com.netease.nimlib.sdk.msg.model.MessageReceipt;
import com.netease.nimlib.sdk.uinfo.model.NimUserInfo;
import com.ydl.ydl_image.module.GlideApp;
import com.ydl.ydlcommon.modular.ModularServiceManager;
import com.ydl.ydlcommon.utils.SharedPreferencesEditor;
import com.ydl.ydlcommon.utils.YdlBuryPointUtil;
import com.ydl.ydlcommon.utils.log.LogHelper;
import com.ydl.ydlcommon.view.CircleImageView;
import com.yidianling.common.tools.ToastUtil;
import com.yidianling.im.R;
import com.yidianling.im.router.ImIn;
import com.yidianling.nimbase.api.UIKitOptions;
import com.yidianling.nimbase.api.model.main.CustomPushContentProvider;
import com.yidianling.nimbase.api.model.session.ModuleProxy;
import com.yidianling.nimbase.api.model.session.SessionCustomization;
import com.yidianling.nimbase.business.session.actions.BaseAction;
import com.yidianling.nimbase.business.session.constant.Extras;
import com.yidianling.nimbase.business.session.module.Container;
import com.yidianling.nimbase.common.CommonUtil;
import com.yidianling.nimbase.common.fragment.TFragment;
import com.yidianling.nimbase.impl.cache.NimUserInfoCache;
import com.yidianling.uikit.api.NimUIKitImpl;
import com.yidianling.uikit.business.ait.AitManager;
import com.yidianling.uikit.business.session.helper.ChatStatusCacheHelper;
import com.yidianling.uikit.business.session.module.input.InputPanel;
import com.yidianling.uikit.business.session.module.list.MessageListPanelEx;
import com.yidianling.uikit.business.session.view.ChatPrivateTips;
import com.yidianling.uikit.business.session.view.CollectInfoPopupWindow;
import com.yidianling.uikit.business.session.view.CommonQuestionView;
import com.yidianling.uikit.custom.bridge.ActionHandlerStorage;
import com.yidianling.uikit.custom.bridge.IP2PCustomActionHandler;
import com.yidianling.uikit.custom.http.ServiceImpl;
import com.yidianling.uikit.custom.http.response.CommonQuestionBean;
import com.yidianling.uikit.custom.http.response.SubmitUserInfoBean;
import com.yidianling.uikit.custom.http.response.UserQuestInfoBean;
import com.yidianling.uikit.custom.widget.ConfideOrderInfoView;
import com.yidianling.uikit.custom.widget.HalfCircleDrawable;
import com.yidianling.user.api.service.IUserService;

import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;


/**
 * 聊天界面基类
 * <p/>
 * Created by huangjun on 2015/2/1.
 */
public class YDLMessageFragment extends TFragment implements ModuleProxy {

    private View rootView;

    private SessionCustomization customization;

    protected static final String TAG = "MessageActivity";

    // 聊天对象
    protected String sessionId; // p2p对方Account或者群id或聊天室id

    protected SessionTypeEnum sessionType;

    //快捷菜单
    protected RelativeLayout lin_actions;

    private LinearLayout ll_actions_yi;

    private FrameLayout fl_container;
    private ChatPrivateTips v_chattips;
    // modules
    protected InputPanel inputPanel;

    public InputPanel getInputPanel() {
        return inputPanel;
    }

    protected MessageListPanelEx messageListPanel;

    private boolean isFirst = true;

    public MessageListPanelEx getMessageListPanelEx() {
        return messageListPanel;
    }

    private int timeCount = 0;

    protected AitManager aitManager;
    private CollectInfoPopupWindow collectInfoPopupWindow;

    private CircleImageView small_head_img; //小头像
    private TextView help_num_tv; //帮助人数
    private TextView server_num_tv; //服务时长
    private TextView good_num_tv; //好评率

    private TextView qingshu; //即时倾诉
    private Boolean canConsultBtnClick = true; //即时倾诉按钮是否可点击

    private ImageView qingshuImg; //预约咨询

    private ConstraintLayout top_expert_info_cl;
    private RelativeLayout rl_common_question_enter;
    private FrameLayout fl_question_content;
    private List<CommonQuestionBean> commonQuestionBeanList;

    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (timeCount == 5) {
                v_chattips.setVisibility(View.GONE);
            } else {
                timeCount++;
                sendEmptyMessageDelayed(1, 1000);
            }
        }
    };

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        parseIntent();
        fl_container = rootView.findViewById(R.id.message_activity_list_view_container);
        v_chattips = rootView.findViewById(R.id.v_chattips);
        lin_actions = rootView.findViewById(R.id.lin_actions);
        ll_actions_yi = rootView.findViewById(R.id.ll_actions_yi);
        small_head_img = rootView.findViewById(R.id.small_head_img);
        help_num_tv = rootView.findViewById(R.id.help_num_tv);
        server_num_tv = rootView.findViewById(R.id.server_num_tv);
        good_num_tv = rootView.findViewById(R.id.good_num_tv);
        top_expert_info_cl = rootView.findViewById(R.id.top_expert_info_cl);
        qingshu = rootView.findViewById(R.id.action_qingshu);
        qingshuImg = rootView.findViewById(R.id.action_qingshu_img);

        //和助理私聊时的常用语逻辑
        rl_common_question_enter = rootView.findViewById(R.id.rl_common_question);
        fl_question_content = rootView.findViewById(R.id.fl_question_content);
        rl_common_question_enter.setVisibility(ActionHandlerStorage.getL(sessionId) != null && ActionHandlerStorage.getL(sessionId).getUserType() == 3 ? View.VISIBLE : View.GONE);

        if (ActionHandlerStorage.getL(sessionId) != null && ActionHandlerStorage.getL(sessionId).getUserType() == 3) {
            rl_common_question_enter.setOnClickListener(v -> {
                if (commonQuestionBeanList != null && commonQuestionBeanList.size() > 0) {
                    openOrCloseCommonQuestionLayout(true);
                } else {
                    getCommonQuestionListData();
                }
            });
            if (ChatStatusCacheHelper.getStatusCache("chatEvent")) {
                if (commonQuestionBeanList != null && commonQuestionBeanList.size() > 0) {
                    rl_common_question_enter.postDelayed(() -> openOrCloseCommonQuestionLayout(true), 300);
                } else {
                    getCommonQuestionListData();

                    try {
                        YdlBuryPointUtil.sendClick("快捷短语弹起");
                    }catch (Exception e){

                    }
                }
                ChatStatusCacheHelper.clearDataByKey("chatEvent");
            }

            if (ChatStatusCacheHelper.getStatusCache("collectEvent")) {
                String time = Calendar.getInstance().get(Calendar.YEAR) + "-" + Calendar.getInstance().get(Calendar.MONTH) + Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
//                if (!TextUtils.equals(time, SharedPreferencesEditor.getString("skip_time_" + YdlCommonRouterManager.INSTANCE.getYdlCommonRoute().getUid()))) {
                if (!TextUtils.equals(time, SharedPreferencesEditor.getString("skip_time_" + ImIn.INSTANCE.getUserInfo().getUid()))) {
                    collectInfoPopupWindow = new CollectInfoPopupWindow(getActivity(), (content, result) -> {
                        if (TextUtils.isEmpty(content)) {//点击跳过后当天不再显示此弹窗
                            SharedPreferencesEditor.putString("skip_time_" + ImIn.INSTANCE.getUserInfo().getUid()
                                    , time);
                        } else {
                            IMMessage textMessage = MessageBuilder.createTextMessage(sessionId, sessionType, content);
                            if (sendMessage(textMessage)) {
                                openOrCloseCommonQuestionLayout(false);
                            }
                            submitUserCollect(result);
                        }
                    });
                    getUserInfoCollect();
                    if (!getActivity().isFinishing()) {
                        collectInfoPopupWindow.show(top_expert_info_cl);
                    }

                    try {
                        YdlBuryPointUtil.sendClick("用户信息收集页面");
                    }catch (Exception e){

                    }

                }
                ChatStatusCacheHelper.clearDataByKey("collectEvent");
            }
        }

        // 初始化顶部专家信息栏
        if (ActionHandlerStorage.getL(sessionId) != null && ActionHandlerStorage.getL(sessionId).getUserType() == 2) {
            top_expert_info_cl.setVisibility(View.VISIBLE);
            initTopCustomBar();
        }

        if (ActionHandlerStorage.getL(sessionId) != null) {
            int type = ActionHandlerStorage.getL(sessionId).getUserType();
            int sType = ActionHandlerStorage.getL(sessionId).getSelfUserType();
            if (type == 2 && sType == 1) {
                lin_actions.setVisibility(View.VISIBLE);
                ll_actions_yi.setVisibility(View.GONE);
                initMenu();
            } else if (type == -1 && sType == 1) {
                ll_actions_yi.setVisibility(View.VISIBLE);
                lin_actions.setVisibility(View.GONE);
                initYiMenu();
            } else {
                ll_actions_yi.setVisibility(View.GONE);
                lin_actions.setVisibility(View.GONE);
            }
        }


        // 监听消息发送状态的变化通知
        NIMClient.getService(MsgServiceObserve.class).observeMsgStatus(
                new Observer<IMMessage>() {
                    @Override
                    public void onEvent(IMMessage imMessage) {
                        // 参数为有状态发生改变的消息对象，其 msgStatus 和 attachStatus 均为最新状态。
                        // 发送消息和接收消息的状态监听均可以通过此接口完成。
                        Log.e("hzs", "接收到消息状态变化-------MessageFragment");
                    }
                }, true);


        RelativeLayout rl_contain = rootView.findViewById(R.id.rl_contain);
        //有未完成订单或者有未评价订单时，显示订单布局
        if (ActionHandlerStorage.getL(sessionId) != null && ActionHandlerStorage.getL(sessionId).getInfo() != null) {
            if (ActionHandlerStorage.getL(sessionId).getInfo().hasAvailableListenOrder == 2 || ActionHandlerStorage.getL(sessionId).getInfo().listenOrderCommentStatus == 1) {
                ConfideOrderInfoView confideOrderInfoView = new ConfideOrderInfoView(getContext(), sessionId);
                confideOrderInfoView.setData(ActionHandlerStorage.getL(sessionId).getInfo());
                rl_contain.addView(confideOrderInfoView);
            }
        }

        //判断是否需要发送自定义消息
        if (isFirst && ActionHandlerStorage.getL(sessionId) != null) {
            isFirst = false;
            ActionHandlerStorage.getL(sessionId).isNeedSendMsg(true);
        }
    }

    /**
     * 初始化顶部专家信息栏
     */
    private void initTopCustomBar() {
        // 头像
        String headUrl = ActionHandlerStorage.getL(sessionId).getInfo().doctorBriefInfoSmallImage;
        if (!TextUtils.isEmpty(headUrl)) {
            GlideApp.with(getActivity()).load(headUrl).into(small_head_img);
        }
        // 帮助人数
        String help_num = String.valueOf(ActionHandlerStorage.getL(sessionId).getInfo().doctorBriefInfoOrderNum);
        if (TextUtils.isEmpty(help_num)) help_num = "0";
        help_num_tv.setText(help_num);
        // 服务时长
        String server_num = String.valueOf((int) Math.ceil((double) ActionHandlerStorage.getL(sessionId).getInfo().doctorBriefInfoHelpLong / 60.0));
        if (TextUtils.isEmpty(server_num)) server_num = "0";
        server_num_tv.setText(server_num);
        // 好评率
        String good_num = String.format("%.2f", ActionHandlerStorage.getL(sessionId).getInfo().doctorBriefInfoFeedbackRate * 20);
        if (TextUtils.isEmpty(good_num)) good_num = "0.00";
        good_num_tv.setText(good_num + "%");

        if (!TextUtils.isEmpty(headUrl)) {
            IP2PCustomActionHandler.DocInfo info = ActionHandlerStorage.getL(sessionId).getInfo();
            if (null != info) {
                NimUserInfo user = NimUserInfoCache.getInstance().getUserInfo(info.toUid);
                if (null != user && null != user.getAvatar() && headUrl.equals(user.getAvatar())) {
                    NimUserInfoCache.getInstance().getUserInfoFromRemote(info.toUid, null);
                }
            }
        }
    }

    private void showTips() {
        mHandler.sendEmptyMessageDelayed(1, 1000);
    }

    //初始化聊天顶部快捷菜单
    private void initMenu() {
        View rela_zixun = rootView.findViewById(R.id.rela_zixun);
        StateListDrawable consultDrawable = new StateListDrawable();
        consultDrawable.addState(new int[]{android.R.attr.state_pressed}, new HalfCircleDrawable(getContext(), false, ContextCompat.getColor(getContext(), R.color.platform_color_F7F7F7)));
        consultDrawable.addState(new int[]{}, new HalfCircleDrawable(getContext(), false, Color.WHITE));
        rela_zixun.setBackground(consultDrawable);

        TextView yuyue = (TextView) rootView.findViewById(R.id.action_yuyue);
        rela_zixun.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                LogHelper.Companion.getInstance().writeLogSync("聊天界面点击预约");
                if (ActionHandlerStorage.getL(sessionId) != null) {
                    try {
                        JSONObject jsb = new JSONObject();
                        jsb.put("button_name", "预约");
                        ActionHandlerStorage.getL(sessionId).buryPoint("messageClick", jsb);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    ActionHandlerStorage.getL(sessionId).showZhuanjPage();
                } else {
                    ToastUtil.toastShort("请退出聊天重试");
                }
            }
        });

        //倾诉
        RelativeLayout rela_qingsu = rootView.findViewById(R.id.rela_qingsu);
        StateListDrawable confideDrawable = new StateListDrawable();
        confideDrawable.addState(new int[]{android.R.attr.state_pressed}, new HalfCircleDrawable(getContext(), true, ContextCompat.getColor(getContext(), R.color.platform_color_F7F7F7)));
        confideDrawable.addState(new int[]{}, new HalfCircleDrawable(getContext(), true, Color.WHITE));
        rela_qingsu.setBackground(confideDrawable);

        if (ActionHandlerStorage.getL(sessionId) != null && ActionHandlerStorage.getL(sessionId).getInfo().listenerIsOpen == 1) {//开通倾诉
            int status = ActionHandlerStorage.getL(sessionId).getInfo().isChatOnline;
            if (status == 5) {
                qingshu.setText("倾诉通话中...");
                qingshu.setTextColor(Color.parseColor("#BFBFBF"));
                qingshuImg.setImageResource(R.mipmap.im_chat_ico_calling);
                canConsultBtnClick = false;
            } else if (status == 3 || status == 4 || status == 6) {
                qingshu.setText("即时倾诉");
                qingshu.setTextColor(Color.parseColor("#BFBFBF"));
                qingshuImg.setImageResource(R.mipmap.im_chat_ico_calling);
                canConsultBtnClick = false;
            } else {
                qingshu.setText("即时倾诉");
                qingshu.setTextColor(Color.parseColor("#242424"));
                qingshuImg.setImageResource(R.mipmap.im_chat_ico_can_call);
                canConsultBtnClick = true;
            }
            if (ActionHandlerStorage.getL(sessionId).getInfo().hasAvailableListenOrder == 2) {//有未完成订单
                qingshu.setText("继续倾诉");
                qingshu.setTextColor(Color.parseColor("#242424"));
                qingshuImg.setImageResource(R.mipmap.im_chat_ico_calling);
                canConsultBtnClick = true;
            }
        } else {
            qingshu.setText("即时倾诉");
            qingshu.setTextColor(Color.parseColor("#242424"));
            qingshuImg.setImageResource(R.mipmap.im_chat_ico_can_call);
            canConsultBtnClick = true;
        }


        rela_qingsu.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (canConsultBtnClick) {
                    LogHelper.Companion.getInstance().writeLogSync("聊天界面点击电话倾诉");
                    if (ActionHandlerStorage.getL(sessionId) != null) {
                        try {
                            JSONObject jsb = new JSONObject();
                            jsb.put("button_name", "电话倾诉");
                            ActionHandlerStorage.getL(sessionId).buryPoint("messageClick", jsb);

                            JSONObject jsonObject = new JSONObject();
                            jsonObject.put("expert_id", ActionHandlerStorage.getL(sessionId).getInfo().doctorId);
                            jsonObject.put("expert_name", ActionHandlerStorage.getL(sessionId).getInfo().name);
                            jsonObject.put("listen_entrance", "私聊窗口");
                            ActionHandlerStorage.getL(sessionId).buryPoint("Listen_expert", jsonObject);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                        ActionHandlerStorage.getL(sessionId).confide();
                    } else {
                        ToastUtil.toastShort("请退出聊天重试");
                    }
                }
            }
        });
    }

    private void initYiMenu() {
        rootView.findViewById(R.id.action_help).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LogHelper.Companion.getInstance().writeLogSync("聊天界面点击常见问题");
                if (null != ActionHandlerStorage.getL(sessionId)) {
                    ActionHandlerStorage.getL(sessionId).startHelp(getActivity());
                }
            }
        });
        rootView.findViewById(R.id.action_feedback).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LogHelper.Companion.getInstance().writeLogSync("聊天界面点击投诉与反馈");
                if (null != ActionHandlerStorage.getL(sessionId)) {
                    ActionHandlerStorage.getL(sessionId).startFeedback(getActivity());
                }
            }
        });
        ;
        rootView.findViewById(R.id.action_call).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LogHelper.Companion.getInstance().writeLogSync("聊天界面点击免费热线");
                if (null != ActionHandlerStorage.getL(sessionId)) {
                    ActionHandlerStorage.getL(sessionId).popCallDialog(getActivity());
                }
            }
        });
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.im_ydl_nim_message_fragment, container, false);
        return rootView;
    }


    /**
     * ***************************** life cycle *******************************
     */
    @Override
    public void onPause() {
        super.onPause();

        NIMClient.getService(MsgService.class).setChattingAccount(MsgService.MSG_CHATTING_ACCOUNT_NONE, SessionTypeEnum.None);
        inputPanel.onPause();
        messageListPanel.onPause();
    }

    @SuppressLint("SetTextI18n")
    @Override
    public void onResume() {
        super.onResume();
        messageListPanel.onResume();
        NIMClient.getService(MsgService.class).setChattingAccount(sessionId, sessionType);
        getActivity().setVolumeControlStream(AudioManager.STREAM_VOICE_CALL); // 默认使用听筒播放


        messageListPanel.scrollToBottom();

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        messageListPanel.onDestroy();
        registerObservers(false);
        if (inputPanel != null) {
            inputPanel.onDestroy();
        }
        if (aitManager != null) {
            aitManager.reset();
        }
    }

    public boolean onBackPressed() {
        return inputPanel.collapse(true) || messageListPanel.onBackPressed() || openOrCloseCommonQuestionLayout(false);
    }

    //刷新消息列表
    public void refreshMessageList() {
        messageListPanel.refreshMessageList();
    }

    //接收参数
    private void parseIntent() {
        sessionId = getArguments().getString(Extras.EXTRA_ACCOUNT);
        sessionType = (SessionTypeEnum) getArguments().getSerializable(Extras.EXTRA_TYPE);
        IMMessage anchor = (IMMessage) getArguments().getSerializable(Extras.EXTRA_ANCHOR);

        customization = (SessionCustomization) getArguments().getSerializable(Extras.EXTRA_CUSTOMIZATION);
        Container container = new Container(getActivity(), sessionId, sessionType, this);

        if (messageListPanel == null) {
            String chatStatusKey = container.account + ModularServiceManager.INSTANCE.provide(IUserService.class).getUserInfo().getUid();
            String userChatStatus = SharedPreferencesEditor.getString(chatStatusKey);

            if (TextUtils.equals(userChatStatus, "true")) {
                messageListPanel = new MessageListPanelEx(container, rootView, anchor, false, true);
                SharedPreferencesEditor.putString(chatStatusKey, "true");
            } else {
                messageListPanel = new MessageListPanelEx(container, rootView, anchor, false, false);
            }
        } else {
            messageListPanel.reload(container, anchor);
        }

        if (inputPanel == null) {
            inputPanel = new InputPanel(getActivity(), container, rootView, getActionList());
            inputPanel.setCustomization(customization);

        } else {
            inputPanel.reload(container, customization);
        }

        initAitManager();

        registerObservers(true);

        if (customization != null) {
            messageListPanel.setChattingBackground(customization.backgroundUri, customization.backgroundColor);
        }
    }

    private void initAitManager() {
        UIKitOptions options = NimUIKitImpl.getOptions();
        if (options.aitEnable) {
            aitManager = new AitManager(getContext(), options.aitTeamMember && sessionType == SessionTypeEnum.Team ? sessionId : null);
            inputPanel.addAitTextWatcher(aitManager);
            aitManager.setTextChangeListener(inputPanel);
        }
    }

    /**
     * ************************* 消息收发 **********************************
     */
    // 是否允许发送消息
    protected boolean isAllowSendMessage(final IMMessage message) {
        return customization.isAllowSendMessage(message);
    }


    private void registerObservers(boolean register) {
        MsgServiceObserve service = NIMClient.getService(MsgServiceObserve.class);
        service.observeReceiveMessage(incomingMessageObserver, register);
        // 已读回执监听
        if (NimUIKitImpl.getOptions().shouldHandleReceipt) {
            service.observeMessageReceipt(messageReceiptObserver, register);
        }
    }

    /**
     * 消息接收观察者
     */
    Observer<List<IMMessage>> incomingMessageObserver = new Observer<List<IMMessage>>() {
        @Override
        public void onEvent(List<IMMessage> messages) {
            onMessageIncoming(messages);
        }
    };

    private void onMessageIncoming(List<IMMessage> messages) {
        if (CommonUtil.isEmpty(messages)) {
            return;
        }
        messageListPanel.onIncomingMessage(messages);
        // 发送已读回执
        messageListPanel.sendReceipt();
    }

    /**
     * 已读回执观察者
     */
    private Observer<List<MessageReceipt>> messageReceiptObserver = new Observer<List<MessageReceipt>>() {
        @Override
        public void onEvent(List<MessageReceipt> messageReceipts) {
            messageListPanel.receiveReceipt();
        }
    };

    /**
     * ********************** implements ModuleProxy *********************
     */
    @Override
    public boolean sendMessage(IMMessage message) {
        if (isAllowSendMessage(message)) {
            //用户对用户第一次聊天发送安全提示消息
            if (ActionHandlerStorage.getL(sessionId) != null) {
                IP2PCustomActionHandler p2PMoreListener = ActionHandlerStorage.getL(sessionId);
                if (p2PMoreListener.getUserType() == 1 && p2PMoreListener.getSelfUserType() == 1 && null != p2PMoreListener.getInfo() && p2PMoreListener.getInfo().is_first == 1) {
                    p2PMoreListener.getInfo().is_first = 0;
                    ActionHandlerStorage.getL(sessionId).sendCustomMsg();
                }
            }
            appendTeamMemberPush(message);
            final IMMessage msg = message;
            appendPushConfig(message);
            // send message to server and save to db
            NIMClient.getService(MsgService.class).sendMessage(message, false).setCallback(new RequestCallback<Void>() {
                @Override
                public void onSuccess(Void param) {

                }

                @Override
                public void onFailed(int code) {
                    if (msg != null) {
                        sendFailWithBlackList(code, msg);
                    }
                }

                @Override
                public void onException(Throwable exception) {

                }
            });

        } else {
            // 替换成tip
            message = MessageBuilder.createTipMessage(message.getSessionId(), message.getSessionType());
            message.setContent("该消息无法发送");
            message.setStatus(MsgStatusEnum.success);
            NIMClient.getService(MsgService.class).saveMessageToLocal(message, false);
        }

        messageListPanel.onMsgSend(message);
        if (aitManager != null) {
            aitManager.reset();
        }
        return true;
    }

    // 被对方拉入黑名单后，发消息失败的交互处理
    private void sendFailWithBlackList(int code, IMMessage msg) {
        if (code == ResponseCode.RES_IN_BLACK_LIST) {
            // 如果被对方拉入黑名单，发送的消息前不显示重发红点
            msg.setStatus(MsgStatusEnum.success);
            NIMClient.getService(MsgService.class).updateIMMessageStatus(msg);
            messageListPanel.refreshMessageList();
            // 同时，本地插入被对方拒收的tip消息
            IMMessage tip = MessageBuilder.createTipMessage(msg.getSessionId(), msg.getSessionType());
            tip.setContent(getActivity().getString(R.string.im_black_list_send_tip));
            tip.setStatus(MsgStatusEnum.success);
            CustomMessageConfig config = new CustomMessageConfig();
            config.enableUnreadCount = false;
            tip.setConfig(config);
            NIMClient.getService(MsgService.class).saveMessageToLocal(tip, true);

            LogHelper.Companion.getInstance().writeLogSync("发送消息失败：已被对方拉黑");
            ToastUtil.toastLong(getActivity(), "您已被对方拉黑!");
        } else if (code == 404) {
            LogHelper.Companion.getInstance().writeLogSync("发送消息失败：对象不见了");
            ToastUtil.toastLong(getActivity(), "对象不见了!");
        } else {
            //上传至后台
            if (!TextUtils.isEmpty(sessionId) && ActionHandlerStorage.getL(sessionId) != null) {
                ActionHandlerStorage.getL(sessionId).uploadSendMessageError(code);
            }
        }
    }

    private void appendTeamMemberPush(IMMessage message) {
        if (aitManager == null) {
            return;
        }
        if (sessionType == SessionTypeEnum.Team) {
            List<String> pushList = aitManager.getAitTeamMember();
            if (pushList == null || pushList.isEmpty()) {
                return;
            }
            MemberPushOption memberPushOption = new MemberPushOption();
            memberPushOption.setForcePush(true);
            memberPushOption.setForcePushContent(message.getContent());
            memberPushOption.setForcePushList(pushList);
            message.setMemberPushOption(memberPushOption);
        }
    }


    private void appendPushConfig(IMMessage message) {
        CustomPushContentProvider customConfig = NimUIKitImpl.getCustomPushContentProvider();
        if (customConfig == null) {
            return;
        }
        String content = customConfig.getPushContent(message);
        Map<String, Object> payload = customConfig.getPushPayload(message);
        if (!TextUtils.isEmpty(content)) {
            message.setPushContent(content);
        }
        if (payload != null) {
            message.setPushPayload(payload);
        }

    }

    @Override
    public void onInputPanelExpand() {
        messageListPanel.scrollToBottom();

        openOrCloseCommonQuestionLayout(false);
    }

    @Override
    public void shouldCollapseInputPanel() {
        inputPanel.collapse(false);

        openOrCloseCommonQuestionLayout(false);
    }

    @Override
    public boolean isLongClickEnabled() {
        return !inputPanel.isRecording();
    }

    @Override
    public void onItemFooterClick(IMMessage message) {

    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (aitManager != null) {
            aitManager.onActivityResult(requestCode, resultCode, data);
        }
        inputPanel.onActivityResult(requestCode, resultCode, data);
        messageListPanel.onActivityResult(requestCode, resultCode, data);
    }

    // 操作面板集合
    protected List<BaseAction> getActionList() {
        List<BaseAction> actions = new ArrayList<>();

        if (customization != null && customization.actions != null) {
            actions.addAll(customization.actions);
        }
        return actions;
    }

    private boolean openOrCloseCommonQuestionLayout(boolean open) {
        boolean result = false;
        if (ActionHandlerStorage.getL(sessionId) != null && ActionHandlerStorage.getL(sessionId).getUserType() == 3) {
            if (open) {
                inputPanel.collapse(true);
                messageListPanel.scrollToBottom();
            }

            if (rl_common_question_enter != null) {
                rl_common_question_enter.setVisibility(open ? View.GONE : View.VISIBLE);
            }
            if (fl_question_content != null) {
                if (fl_question_content.getVisibility() == View.VISIBLE) {
                    result = true;
                }
                fl_question_content.setVisibility(open ? View.VISIBLE : View.GONE);
            }
        }
        return result;
    }


    @SuppressLint("CheckResult")
    private void getCommonQuestionListData() {
        ServiceImpl.Companion.getInstance().getCommonQuestionList()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(res -> {
                    if (res.data != null && res.data.size() > 0) {
                        if (commonQuestionBeanList == null) {
                            commonQuestionBeanList = new ArrayList<>();
                        } else {
                            commonQuestionBeanList.clear();
                        }
                        commonQuestionBeanList.addAll(res.data);
                        initCommonQuestionLayout();
                    }

                }, throwable -> {
                    ToastUtil.toastShort(throwable.toString());
                });
    }

    private void initCommonQuestionLayout() {
        CommonQuestionView commonQuestionView = new CommonQuestionView(getActivity());
        commonQuestionView.setData(commonQuestionBeanList);
        commonQuestionView.setListener(new CommonQuestionView.OnSelectItemListener() {
            @Override
            public void close() {
                openOrCloseCommonQuestionLayout(false);
            }

            @Override
            public void onSelect(@NotNull String title, String id) {
                IMMessage textMessage = MessageBuilder.createTextMessage(sessionId, sessionType, title);
                if (sendMessage(textMessage)) {
                    openOrCloseCommonQuestionLayout(false);
                }
                commonQuestionClickCount(id);
            }
        });
        fl_question_content.addView(commonQuestionView);
        openOrCloseCommonQuestionLayout(true);
    }

    @SuppressLint("CheckResult")
    private void commonQuestionClickCount(String id) {
        ServiceImpl.Companion.getInstance().sendCommonQuestionCount(id)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(objectBaseAPIResponse -> {

                }, throwable -> {

                });
    }


    @SuppressLint("CheckResult")
    private void getUserInfoCollect() {
        ServiceImpl.Companion.getInstance().userCollectList()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(resp -> {
                    if (resp.data != null && resp.data.size() > 0) {
                        collectInfoPopupWindow.setData(resp.data);
                    } else {
                        collectInfoPopupWindow.dismiss();
                    }
                }, throwable -> {
                    collectInfoPopupWindow.dismiss();
                });
    }

    @SuppressLint("CheckResult")
    private void submitUserCollect(List<UserQuestInfoBean> result) {
        SubmitUserInfoBean submitUserInfoBean = new SubmitUserInfoBean();
        submitUserInfoBean.userInfoList = result;
        ServiceImpl.Companion.getInstance().submitUserCollect(JSON.toJSONString(submitUserInfoBean))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(resp -> {
                }, throwable -> {
                });
    }
}
