package org.yameida.worktool.service

import android.content.Intent
import android.graphics.Bitmap
import android.view.accessibility.AccessibilityNodeInfo
import com.blankj.utilcode.util.*
import com.github.yoojia.qrcode.qrcode.QRCodeDecoder
import com.lzy.okgo.OkGo
import com.xuexiang.xupdate.utils.UpdateUtils.startActivity
import kotlinx.android.synthetic.main.activity_listen.*
import org.yameida.worktool.Constant
import org.yameida.worktool.model.ExecCallbackBean
import org.yameida.worktool.model.WeworkMessageBean
import org.yameida.worktool.model.operation.SelectResult
import org.yameida.worktool.utils.*
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.LinkedHashSet


/**
 * 全局操作类型 200 实现类
 */
object WeworkOperationImpl {

    /**
     * 在房间内发送消息
     * @param titleList 房间名称
     * @param receivedContent 回复内容
     * @param at 要at的昵称
     * @see WeworkMessageBean.TEXT_TYPE
     */
    fun sendMessage(
        message: WeworkMessageBean,
        titleList: List<String>,
        receivedContent: String?,
        at: String? = null,
        atList: List<String>? = null
    ): Boolean {
        val startTime = System.currentTimeMillis()
        if (receivedContent.isNullOrEmpty()) {
            LogUtils.d("未发现发送内容")
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_ILLEGAL_DATA,
                "发送内容为空",
                startTime,
                listOf(),
                titleList
            )
            goHome()
            return false
        }
        val successList = arrayListOf<String>()
        val failList = arrayListOf<String>()
        for (title in LinkedHashSet(titleList)) {
            var successFlag = true
            if (WeworkRoomUtil.intoRoom(title) || WeworkRoomUtil.intoRoom(title, fastIn = false)) {
                if (sendChatMessage(receivedContent, at = at, atList = atList, title = title)) {
                    successList.add(title)
                    LogUtils.d("$title: 发送成功")
                } else {
                    successFlag = false
                }
            } else {
                successFlag = false
            }
            if (!successFlag) {
                if (WeworkRoomUtil.intoRoom(title, fastIn = false)) {
                    if (sendChatMessage(receivedContent, at = at, atList = atList, title = title)) {
                        successList.add(title)
                        LogUtils.d("$title: 发送成功")
                    } else {
                        LogUtils.d("$title: 发送失败")
                        failList.add(title)
                        error("$title: 发送失败 $receivedContent")
                    }
                } else {
                    LogUtils.d("$title: 发送失败 进入房间失败")
                    failList.add(title)
                    error("$title: 发送失败 进入房间失败 $receivedContent")
                }
            }
        }
        if (failList.isNotEmpty()) {
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_SEND_MESSAGE,
                "发送成功: ${successList.joinToString()} 发送失败: ${failList.joinToString()}",
                startTime,
                successList,
                failList
            )
            return false
        }
        uploadCommandResult(message, ExecCallbackBean.SUCCESS, "", startTime, successList, failList)
        return true
    }

    /**
     * 在房间内指定回复消息
     * @param titleList 房间名称
     * @param receivedName 原始消息的发送者姓名
     * @param originalContent 原始消息的内容
     * @param textType 原始消息的消息类型
     * @param receivedContent 回复内容
     * @see WeworkMessageBean.TEXT_TYPE
     */
    fun replyMessage(
        message: WeworkMessageBean,
        titleList: List<String>,
        receivedName: String?,
        originalContent: String,
        textType: Int,
        receivedContent: String?
    ): Boolean {
        val startTime = System.currentTimeMillis()
        if (receivedContent.isNullOrEmpty()) {
            LogUtils.d("未发现回复内容")
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_ILLEGAL_DATA,
                "回复内容为空",
                startTime,
                listOf(),
                titleList
            )
            goHome()
            return false
        }
        val successList = arrayListOf<String>()
        val failList = arrayListOf<String>()
        for (title in LinkedHashSet(titleList)) {
            if (WeworkRoomUtil.intoRoom(title) || WeworkRoomUtil.intoRoom(title, fastIn = false)) {
                if (WeworkTextUtil.longClickMessageItem(
                        //聊天消息列表 1ListView 0RecycleView xViewGroup
                        AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView),
                        textType,
                        receivedName,
                        originalContent,
                        "回复", "引用"
                    )
                ) {
                    LogUtils.v("开始回复")
                    if (sendChatMessage(receivedContent, reply = true, title = title)) {
                        LogUtils.d("$title: 回复成功")
                        successList.add(title)
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.SUCCESS,
                            "",
                            startTime,
                            successList,
                            failList
                        )
                        return true
                    } else {
                        LogUtils.d("$title: 回复发送失败")
                        failList.add(title)
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_SEND_MESSAGE,
                            "回复发送失败",
                            startTime,
                            successList,
                            failList
                        )
                        return false
                    }
                } else {
                    LogUtils.d("$title: 回复失败 直接发送答案")
                    error("$title: 回复失败 直接发送答案 $receivedContent")
                    val text =
                        if (originalContent.isNotEmpty()) "【$originalContent】\n$receivedContent" else receivedContent
                    if (sendChatMessage(text, receivedName, title = title)) {
                        LogUtils.d("$title: 直接发送答案成功")
                        successList.add(title)
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.SUCCESS,
                            "",
                            startTime,
                            successList,
                            failList
                        )
                        return true
                    } else {
                        LogUtils.d("$title: 直接发送答案失败")
                        failList.add(title)
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_SEND_MESSAGE,
                            "直接发送答案失败",
                            startTime,
                            successList,
                            failList
                        )
                        return false
                    }
                }
            } else {
                error("$title: 回复失败 $receivedContent")
                LogUtils.d("进入房间失败 $title")
                failList.add(title)
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_INTO_ROOM,
                    "进入房间失败 $title",
                    startTime,
                    successList,
                    failList
                )
                return false
            }
        }
        LogUtils.d("房间名为空")
        uploadCommandResult(
            message,
            ExecCallbackBean.ERROR_ILLEGAL_DATA,
            "房间名为空",
            startTime,
            listOf(),
            titleList
        )
        return false
    }

    /**
     * 在房间内转发消息
     * @see WeworkMessageBean.RELAY_MESSAGE
     * @param titleList 房间名称
     * @param receivedName 原始消息的发送者姓名
     * @param originalContent 原始消息的内容
     * @param textType 原始消息的消息类型
     * @param nameList 待转发姓名列表
     * @param extraText 附加留言 选填
     * @see WeworkMessageBean.TEXT_TYPE
     */
    fun relayMessage(
        message: WeworkMessageBean,
        titleList: List<String>,
        receivedName: String?,
        originalContent: String,
        textType: Int,
        nameList: List<String>,
        extraText: String? = null
    ): Boolean {
        val startTime = System.currentTimeMillis()
        for (title in LinkedHashSet(titleList)) {
            if (WeworkRoomUtil.intoRoom(title) || WeworkRoomUtil.intoRoom(title, fastIn = false)) {
                if (!receivedName.isNullOrEmpty()) {
                    if (WeworkTextUtil.longClickMessageItem(
                            //聊天消息列表 1ListView 0RecycleView xViewGroup
                            AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView),
                            textType,
                            receivedName,
                            originalContent,
                            "转发"
                        )
                    ) {
                        LogUtils.d("开始转发")
                        val relaySelectResult = relaySelectTarget(nameList, extraText)
                        if (relaySelectResult.result) {
                            AccessibilityExtraUtil.loadingPage(
                                "CommonSelectActivity",
                                "ExternalGroupMessageListActivity",
                                "ExternalWechatUserMessageListActivity",
                                "MessageListActivity"
                            )
                            AccessibilityUtil.waitForPageMissing("CommonSelectActivity")
                            LogUtils.d("$title: 转发成功")
                            uploadCommandResult(
                                message,
                                ExecCallbackBean.SUCCESS,
                                "$title: 转发成功",
                                startTime,
                                relaySelectResult.successList,
                                relaySelectResult.failList
                            )
                            goHome()
                            return true
                        } else {
                            LogUtils.d("$title: 转发失败 $originalContent")
                            uploadCommandResult(
                                message,
                                ExecCallbackBean.ERROR_RELAY,
                                "$title: 转发失败 $originalContent",
                                startTime,
                                listOf(),
                                titleList
                            )
                            goHome()
                            return false
                        }
                    } else {
                        LogUtils.e("$title: 长按条目失败 $originalContent")
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_BUTTON,
                            "$title: 长按条目失败 $originalContent",
                            startTime,
                            listOf(),
                            titleList
                        )
                        return false
                    }
                } else {
                    if (WeworkTextUtil.longClickMyMessageItem(
                            //聊天消息列表 1ListView 0RecycleView xViewGroup
                            AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView),
                            textType,
                            originalContent,
                            "转发"
                        )
                    ) {
                        LogUtils.d("开始转发")
                        val relaySelectResult = relaySelectTarget(nameList, extraText)
                        if (relaySelectResult.result) {
                            AccessibilityExtraUtil.loadingPage(
                                "CommonSelectActivity",
                                "ExternalGroupMessageListActivity",
                                "ExternalWechatUserMessageListActivity",
                                "MessageListActivity"
                            )
                            AccessibilityUtil.waitForPageMissing("CommonSelectActivity")
                            LogUtils.d("$title: 转发成功")
                            uploadCommandResult(
                                message,
                                ExecCallbackBean.SUCCESS,
                                "$title: 转发成功",
                                startTime,
                                relaySelectResult.successList,
                                relaySelectResult.failList
                            )
                            goHome()
                            return true
                        } else {
                            LogUtils.d("$title: 转发失败 $originalContent")
                            uploadCommandResult(
                                message,
                                ExecCallbackBean.ERROR_RELAY,
                                "$title: 转发失败 $originalContent",
                                startTime,
                                listOf(),
                                titleList
                            )
                            goHome()
                            return false
                        }
                    } else {
                        LogUtils.e("$title: 长按条目失败 $originalContent")
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_BUTTON,
                            "$title: 长按条目失败 $originalContent",
                            startTime,
                            listOf(),
                            titleList
                        )
                        return false
                    }
                }
            } else {
                LogUtils.d("$title: 转发失败 未找到房间")
                error("$title: 转发失败 $originalContent")
            }
        }
        LogUtils.d("转发失败 未找到房间名")
        uploadCommandResult(
            message,
            ExecCallbackBean.ERROR_ILLEGAL_DATA,
            "转发失败 未找到房间名",
            startTime,
            listOf(),
            titleList
        )
        return false
    }

    /**
     * 初始化群设置
     * 群名称、群公告、拉人、踢人、群备注、群模板
     * 注：群配置模板 1.群名称 2.禁群改名(使用) 3.设置管理员 4.入群欢迎语(使用) 5.自动回复 6.防骚扰规则(使用)
     * @see WeworkMessageBean.INIT_GROUP
     * @param groupName 修改群名称
     * @param selectList 添加群成员名称列表 选填
     * @param groupAnnouncement 修改群公告 选填
     * @param groupRemark 修改群备注 选填
     * @param groupTemplate 修改群模板 选填
     */
    fun initGroup(
        message: WeworkMessageBean,
        groupName: String,
        selectList: List<String>?,
        groupAnnouncement: String?,
        groupRemark: String?,
        groupTemplate: String?
    ): Boolean {
        val startTime = System.currentTimeMillis()
        val metaJson = hashMapOf<String, ArrayList<String>>()
        if (!WeworkRoomUtil.isGroupExists(groupName)) {
            if (!beforeCreateGroupCheck()) {
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_CREATE_GROUP_LIMIT,
                    "建群达到上限",
                    startTime,
                    listOf(),
                    listOf(groupName),
                    metaJson = GsonUtils.toJson(metaJson)
                )
                return false
            }
            if (!createGroup()) {
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_CREATE_GROUP,
                    "创建群失败",
                    startTime,
                    listOf(),
                    listOf(groupName),
                    metaJson = GsonUtils.toJson(metaJson)
                )
                return false
            }
            if (createGroupError()) {
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_CREATE_GROUP_LIMIT,
                    "建群功能被限制",
                    startTime,
                    listOf(),
                    listOf(groupName),
                    metaJson = GsonUtils.toJson(metaJson)
                )
                return false
            }
            if (createGroupLimit()) {
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_CREATE_GROUP_LIMIT,
                    "建群达到上限",
                    startTime,
                    listOf(),
                    listOf(groupName),
                    metaJson = GsonUtils.toJson(metaJson)
                )
                return false
            } else {
                LogUtils.v("未发现建群达到上限")
            }
        }
        if (!groupRename(groupName)) {
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_GROUP_RENAME,
                "创建群成功 群改名失败",
                startTime,
                listOf(),
                listOf(groupName),
                metaJson = GsonUtils.toJson(metaJson)
            )
            return false
        }
        val addSelectResult = groupAddMember(selectList)
        metaJson["addSelectSuccessList"] = addSelectResult.successList
        metaJson["addSelectFailList"] = addSelectResult.failList
        if (!addSelectResult.result) {
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_GROUP_ADD_MEMBER,
                "创建群成功 群改名成功 群拉人失败: ${selectList?.joinToString()}",
                startTime,
                listOf(),
                listOf(groupName),
                metaJson = GsonUtils.toJson(metaJson)
            )
            return false
        }
        if (!groupChangeAnnouncement(groupAnnouncement)) {
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_GROUP_CHANGE_ANNOUNCEMENT,
                "创建群成功 群改名成功 群拉人成功 群公告失败",
                startTime,
                listOf(),
                listOf(groupName),
                metaJson = GsonUtils.toJson(metaJson)
            )
            return false
        }
        if (!groupChangeRemark(groupRemark)) {
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_GROUP_CHANGE_REMARK,
                "创建群成功 群改名成功 群拉人成功 群公告成功 群备注失败",
                startTime,
                listOf(),
                listOf(groupName),
                metaJson = GsonUtils.toJson(metaJson)
            )
            return false
        }
        if (!groupTemplate(groupTemplate)) {
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_GROUP_TEMPLATE,
                "创建群成功 群改名成功 群拉人成功 群公告成功 群备注成功 群模板失败",
                startTime,
                listOf(),
                listOf(groupName),
                metaJson = GsonUtils.toJson(metaJson)
            )
            return false
        }
        saveToContract()
        getGroupQrcode(groupName, groupRemark)
        uploadCommandResult(
            message,
            ExecCallbackBean.SUCCESS,
            "",
            startTime,
            listOf(groupName),
            listOf(),
            metaJson = GsonUtils.toJson(metaJson)
        )
        return true
    }

    /**
     * 进入群聊并修改群配置
     * 群名称、群公告、拉人、踢人、群备注、群模板
     * @see WeworkMessageBean.UPDATE_GROUP
     * @param groupName 待修改的群
     * @param newGroupName 修改群名 选填
     * @param newGroupAnnouncement 修改群公告 选填
     * @param groupRemark 修改群备注 选填
     * @param groupTemplate 修改群模板 选填
     * @param selectList 添加群成员名称列表/拉人 选填
     * @param showMessageHistory 拉人是否附带历史记录 选填
     * @param removeList 移除群成员名称列表/踢人 选填
     */
    fun updateGroup(
        message: WeworkMessageBean,
        groupName: String,
        newGroupName: String?,
        newGroupAnnouncement: String?,
        groupRemark: String?,
        groupTemplate: String?,
        selectList: List<String>?,
        showMessageHistory: Boolean?,
        removeList: List<String>?,
        stopGroupName: String?
    ): Boolean {
        val startTime = System.currentTimeMillis()
        val metaJson = hashMapOf<String, ArrayList<String>>()
        if (!WeworkRoomUtil.intoRoom(groupName, fastIn = false)) {
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_INTO_ROOM,
                "进入房间失败 $groupName",
                startTime,
                listOf(),
                listOf(groupName),
                metaJson = GsonUtils.toJson(metaJson)
            )
            return false
        }
        if (!groupRename(newGroupName)) {
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_GROUP_RENAME,
                "进入房间成功 群改名失败",
                startTime,
                listOf(),
                listOf(groupName),
                metaJson = GsonUtils.toJson(metaJson)
            )
            return false
        }
        val addSelectResult = groupAddMember(selectList, showMessageHistory == true)
        metaJson["addSelectSuccessList"] = addSelectResult.successList
        metaJson["addSelectFailList"] = addSelectResult.failList
        if (!addSelectResult.result) {
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_GROUP_ADD_MEMBER,
                "进入房间成功 群改名成功 群拉人失败: ${selectList?.joinToString()}",
                startTime,
                listOf(),
                listOf(groupName),
                metaJson = GsonUtils.toJson(metaJson)
            )
            return false
        }
        val removeSelectResult = groupRemoveMember(removeList)
        metaJson["removeSelectSuccessList"] = removeSelectResult.successList
        metaJson["removeSelectFailList"] = removeSelectResult.failList
        if (!removeSelectResult.result) {
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_GROUP_REMOVE_MEMBER,
                "进入房间成功 群改名成功 群拉人成功 群踢人失败: ${removeList?.joinToString()}",
                startTime,
                listOf(),
                listOf(groupName),
                metaJson = GsonUtils.toJson(metaJson)
            )
            return false
        }
        if (!groupChangeAnnouncement(newGroupAnnouncement)) {
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_GROUP_CHANGE_ANNOUNCEMENT,
                "进入房间成功 群改名成功 群拉人成功 群公告失败",
                startTime,
                listOf(),
                listOf(groupName),
                metaJson = GsonUtils.toJson(metaJson)
            )
            return false
        }
        if (!groupChangeRemark(groupRemark)) {
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_GROUP_CHANGE_REMARK,
                "进入房间成功 群改名成功 群拉人成功 群公告成功 群备注失败",
                startTime,
                listOf(),
                listOf(groupName),
                metaJson = GsonUtils.toJson(metaJson)
            )
            return false
        }
        if (!prohibitGroupName(stopGroupName)) {
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_GROUP_CHANGE_REMARK,
                "进入房间成功 群改名成功 群拉人成功 群公告成功 群备注成功 禁止改群名失败",
                startTime,
                listOf(),
                listOf(groupName),
                metaJson = GsonUtils.toJson(metaJson)
            )
            return false
        }
        if (!groupTemplate(groupTemplate)) {
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_GROUP_TEMPLATE,
                "进入房间成功 群改名成功 群拉人成功 群公告成功 群备注成功 禁止改群名成功 群模板失败",
                startTime,
                listOf(),
                listOf(groupName),
                metaJson = GsonUtils.toJson(metaJson)
            )
            return false
        }
        saveToContract()
//        getGroupQrcode(groupName, groupRemark)
        uploadCommandResult(
            message,
            ExecCallbackBean.SUCCESS,
            "",
            startTime,
            listOf(groupName),
            listOf(),
            metaJson = GsonUtils.toJson(metaJson)
        )
        return true
    }

    /**
     * 解散群聊
     * @see WeworkMessageBean.DISMISS_GROUP
     * @param groupName 待解散的群
     */
    fun dismissGroup(
        message: WeworkMessageBean,
        groupName: String
    ): Boolean {
        val startTime = System.currentTimeMillis()
        if ((WeworkRoomUtil.intoRoom(groupName) || WeworkRoomUtil.intoRoom(
                groupName,
                fastIn = false
            )) && WeworkRoomUtil.intoGroupManager()
        ) {
            val groupManagerTv =
                AccessibilityUtil.findOneByText(getRoot(), "群管理", exact = true, timeout = 2000)
            if (groupManagerTv != null) {
                AccessibilityUtil.performClick(groupManagerTv)
                val dismissTv =
                    AccessibilityUtil.findOneByText(getRoot(), "解散群聊", exact = true, timeout = 2000)
                AccessibilityUtil.performClick(dismissTv)
                if (dismissTv != null) {
                    val confirmTv = AccessibilityUtil.findOneByText(
                        getRoot(),
                        "解散",
                        "确定",
                        exact = true,
                        timeout = 2000
                    )
                    if (confirmTv != null) {
                        AccessibilityUtil.performClick(confirmTv)
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.SUCCESS,
                            "",
                            startTime,
                            listOf(groupName),
                            listOf()
                        )
                        return true
                    } else {
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_BUTTON,
                            "未找到解散按钮 $groupName",
                            startTime,
                            listOf(),
                            listOf(groupName)
                        )
                        return false
                    }
                } else {
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.ERROR_BUTTON,
                        "未找到解散群聊按钮 $groupName",
                        startTime,
                        listOf(),
                        listOf(groupName)
                    )
                    return false
                }
            } else {
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_BUTTON,
                    "未找到群管理按钮 $groupName",
                    startTime,
                    listOf(),
                    listOf(groupName)
                )
                return false
            }
        } else {
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_INTO_ROOM,
                "进入房间失败 $groupName",
                startTime,
                listOf(),
                listOf(groupName)
            )
            return false
        }
    }

    /**
     * 推送微盘图片(不推荐)
     * @see pushFile
     * @param titleList 待发送姓名列表
     * @param objectName 图片名称
     * @param extraText  附加留言 可选
     */
    fun pushMicroDiskImage(
        message: WeworkMessageBean,
        titleList: List<String>,
        objectName: String,
        extraText: String? = null,
        maxRetryCount: Int? = null
    ): Boolean {
        val retryCount = maxRetryCount ?: 2
        val startTime = System.currentTimeMillis()
        if (!PermissionUtils.isGrantedDrawOverlays()) {
            LogUtils.e("未打开悬浮窗权限")
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_ILLEGAL_PERMISSION,
                "未打开悬浮窗权限",
                startTime,
                listOf(),
                titleList
            )
            return false
        }
        goHomeTab("工作台")
        val node = AccessibilityUtil.scrollAndFindByText(
            WeworkController.weworkService,
            getRoot(),
            "微盘",
            exact = true
        )
        if (node != null) {
            AccessibilityUtil.performClick(node)
            sleep(Constant.POP_WINDOW_INTERVAL)
            val buttonList = AccessibilityUtil.findAllByClazz(getRoot(), Views.Button)
            if (buttonList.size >= 4) {
                AccessibilityUtil.performClick(buttonList[2])
                AccessibilityUtil.findTextInput(getRoot(), objectName)
                val imageViewList = AccessibilityUtil.findAllByClazz(getRoot(), Views.ImageView)
                if (imageViewList.size >= 2) {
                    AccessibilityUtil.performClick(imageViewList[1])
                    val shareFileButton =
                        AccessibilityUtil.findOneByDesc(getRoot(), "以原文件分享", "用其他应用打开")
                    AccessibilityUtil.performClick(shareFileButton)
                    val tvFlag = AccessibilityUtil.findOneByText(
                        getRoot(true, share = true),
                        "发送给同事",
                        "选择联系人",
                        "选择参与人"
                    )
                    val flagText = tvFlag?.text?.toString() ?: ""
                    if (flagText.contains("发送给同事")) {
                        var shareToWorkButton = tvFlag
                        sleep(Constant.POP_WINDOW_INTERVAL)
                        if (shareToWorkButton == null) {
                            LogUtils.e("未找到发送给同事: $objectName")
                            if (retryCount > 0) {
                                return pushMicroDiskImage(
                                    message,
                                    titleList,
                                    objectName,
                                    extraText,
                                    retryCount - 1
                                )
                            }
                            uploadCommandResult(
                                message,
                                ExecCallbackBean.ERROR_RELAY,
                                "未找到发送给同事: $objectName",
                                startTime,
                                listOf(),
                                titleList
                            )
                            return false
                        }
                        AccessibilityUtil.performClick(shareToWorkButton)
                        sleep(Constant.POP_WINDOW_INTERVAL)
                        shareToWorkButton =
                            AccessibilityUtil.findOnceByText(getRoot(true, share = true), "发送给同事")
                        LogUtils.v(
                            "尝试发送给同事",
                            shareToWorkButton == null,
                            WeworkController.weworkService.currentPackage
                        )
                        val time = System.currentTimeMillis()
                        var currentTime = time
                        while (currentTime - time < 5000) {
                            if (shareToWorkButton != null
                                && WeworkController.weworkService.currentPackage != Constant.PACKAGE_NAMES
                            ) {
                                LogUtils.e("尝试手势点击！！！！！")
                                AccessibilityUtil.clickByNode(
                                    WeworkController.weworkService,
                                    shareToWorkButton
                                )
                                sleep(Constant.CHANGE_PAGE_INTERVAL)
                                shareToWorkButton = AccessibilityUtil.findOnceByText(
                                    getRoot(true, share = true),
                                    "发送给同事"
                                )
                            } else {
                                break
                            }
                            currentTime = System.currentTimeMillis()
                        }
                    } else if (flagText !in arrayOf("选择联系人", "选择参与人")) {
                        LogUtils.e("未找到发送给同事: $objectName")
                        if (retryCount > 0) {
                            return pushMicroDiskImage(
                                message,
                                titleList,
                                objectName,
                                extraText,
                                retryCount - 1
                            )
                        }
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_RELAY,
                            "未找到发送给同事: $objectName",
                            startTime,
                            listOf(),
                            titleList
                        )
                        return false
                    }
                    val relaySelectResult = relaySelectTarget(titleList, extraText, timeout = 10000)
                    if (relaySelectResult.result) {
                        AccessibilityExtraUtil.loadingPage(
                            "CommonSelectActivity",
                            "ExternalGroupMessageListActivity",
                            "ExternalWechatUserMessageListActivity",
                            "MessageListActivity"
                        )
                        AccessibilityUtil.waitForPageMissing("CommonSelectActivity")
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.SUCCESS,
                            "",
                            startTime,
                            relaySelectResult.successList,
                            relaySelectResult.failList
                        )
                        goHome()
                        return true
                    } else {
                        LogUtils.e("微盘文件转发失败: $objectName")
                        if (retryCount > 0) {
                            goHome()
                            return pushMicroDiskImage(
                                message,
                                titleList,
                                objectName,
                                extraText,
                                retryCount - 1
                            )
                        }
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_RELAY,
                            "微盘文件转发失败: $objectName",
                            startTime,
                            listOf(),
                            titleList
                        )
                        goHome()
                        return false
                    }
                } else {
                    LogUtils.e("微盘未搜索到相关图片: $objectName")
                    if (retryCount > 0) {
                        return pushMicroDiskImage(
                            message,
                            titleList,
                            objectName,
                            extraText,
                            retryCount - 1
                        )
                    }
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.ERROR_TARGET,
                        "微盘未搜索到相关图片: $objectName",
                        startTime,
                        listOf(),
                        titleList
                    )
                    return false
                }
            } else {
                LogUtils.e("未找到微盘内搜索")
                if (retryCount > 0) {
                    return pushMicroDiskImage(
                        message,
                        titleList,
                        objectName,
                        extraText,
                        retryCount - 1
                    )
                }
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_BUTTON,
                    "未找到微盘内搜索",
                    startTime,
                    listOf(),
                    titleList
                )
                return false
            }
        } else {
            LogUtils.e("未找到微盘")
            if (retryCount > 0) {
                return pushMicroDiskImage(message, titleList, objectName, extraText, retryCount - 1)
            }
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_BUTTON,
                "未找到微盘",
                startTime,
                listOf(),
                titleList
            )
            return false
        }
    }

    /**
     * 推送微盘文件(不推荐)
     * @see pushFile
     * @param titleList 待发送姓名列表
     * @param objectName 文件名称
     * @param extraText  附加留言 可选
     */
    fun pushMicroDiskFile(
        message: WeworkMessageBean,
        titleList: List<String>,
        objectName: String,
        extraText: String? = null
    ): Boolean {
        val startTime = System.currentTimeMillis()
        goHomeTab("工作台")
        val node = AccessibilityUtil.scrollAndFindByText(
            WeworkController.weworkService,
            getRoot(),
            "微盘",
            exact = true
        )
        if (node != null) {
            AccessibilityUtil.performClick(node)
            sleep(Constant.POP_WINDOW_INTERVAL)
            val buttonList = AccessibilityUtil.findAllByClazz(getRoot(), Views.Button)
            if (buttonList.size >= 4) {
                AccessibilityUtil.performClick(buttonList[2])
                AccessibilityUtil.findTextInput(getRoot(), objectName)
                val imageViewList = AccessibilityUtil.findAllByClazz(getRoot(), Views.ImageView)
                if (imageViewList.size >= 2) {
                    AccessibilityUtil.performClick(imageViewList[1])
                    val shareFileButton = AccessibilityUtil.findOneByDesc(getRoot(), "转发")
                    AccessibilityUtil.performClick(shareFileButton)
                    val relaySelectResult = relaySelectTarget(titleList, extraText)
                    if (relaySelectResult.result) {
                        AccessibilityExtraUtil.loadingPage(
                            "CommonSelectActivity",
                            "ExternalGroupMessageListActivity",
                            "ExternalWechatUserMessageListActivity",
                            "MessageListActivity"
                        )
                        AccessibilityUtil.waitForPageMissing("CommonSelectActivity")
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.SUCCESS,
                            "",
                            startTime,
                            relaySelectResult.successList,
                            relaySelectResult.failList
                        )
                        goHome()
                        return true
                    } else {
                        LogUtils.e("微盘文件转发失败: $objectName")
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_RELAY,
                            "微盘文件转发失败: $objectName",
                            startTime,
                            listOf(),
                            titleList
                        )
                        goHome()
                        return false
                    }
                } else {
                    LogUtils.e("微盘未搜索到相关文件: $objectName")
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.ERROR_TARGET,
                        "微盘未搜索到相关文件: $objectName",
                        startTime,
                        listOf(),
                        titleList
                    )
                    return false
                }
            } else {
                LogUtils.e("未找到微盘内搜索")
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_BUTTON,
                    "未找到微盘内搜索",
                    startTime,
                    listOf(),
                    titleList
                )
                return false
            }
        } else {
            LogUtils.e("未找到微盘")
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_BUTTON,
                "未找到微盘",
                startTime,
                listOf(),
                titleList
            )
            return false
        }
    }

    fun pushPicture(
        message: WeworkMessageBean,
        titleList: List<String>,
        fileUrl: String,
        appId: String,
        agentId: String,
        fileName: String,
        extraText: String? = null,
        maxRetryCount: Int? = null
    ): Boolean {
        val retryCount = maxRetryCount ?: 2
        val startTime = System.currentTimeMillis()
        if (IWWAPIUtil.sendPicture(fileUrl, appId, agentId, fileName)) {
            val relaySelectResult = relaySelectTarget(titleList, extraText)
            if (relaySelectResult.result) {
                AccessibilityExtraUtil.loadingPage(
                    "CommonSelectActivity",
                    "ExternalGroupMessageListActivity",
                    "ExternalWechatUserMessageListActivity",
                    "MessageListActivity"
                )
                AccessibilityUtil.waitForPageMissing("CommonSelectActivity")
                uploadCommandResult(
                    message,
                    ExecCallbackBean.SUCCESS,
                    "",
                    startTime,
                    relaySelectResult.successList,
                    relaySelectResult.failList
                )
                goHome()
                return true
            } else {
                LogUtils.e("转发失败")
                if (retryCount > 0) {
                    goHome()
                    return pushPicture(
                        message,
                        titleList,
                        fileUrl,
                        appId,
                        agentId,
                        fileName,
                        extraText,
                        retryCount - 1
                    )
                }
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_RELAY,
                    "转发失败: ",
                    startTime,
                    listOf(),
                    titleList
                )
                goHome()
                return false
            }
        } else {
            LogUtils.e("非法操作")
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_ILLEGAL_OPERATION,
                "非法操作",
                startTime,
                listOf(),
                titleList
            )
            return false
        }
    }

    /**
     * 推送小程序
     * @see WeworkMessageBean.PUSH_MICROPROGRAM
     * @param titleList 待发送姓名列表
     * @param objectName 小程序名称
     * @param receivedContent 小程序描述
     * @param originalContent 小程序链接地址
     * @param fileUrl 图片地址
     * @param extraText 附加留言 可选
     */
    fun pushMicroprogram(
        message: WeworkMessageBean,
        titleList: List<String>,
        appId: String?,
        agentId: String?,
        objectName: String?,
        imageUrl: String?,
        username: String?,
        path: String?,
        schema: String?,
        description: String?,
        extraText: String? = null,
        maxRetryCount: Int? = null
    ): Boolean {
        val retryCount = maxRetryCount ?: 2
        val startTime = System.currentTimeMillis()
        if (IWWAPIUtil.sendMicroProgram(
                appId,
                agentId,
                objectName,
                imageUrl,
                username,
                path,
                schema,
                description
            )
        ) {
            val relaySelectResult = relaySelectTarget(titleList, extraText)
            if (relaySelectResult.result) {
                AccessibilityExtraUtil.loadingPage(
                    "CommonSelectActivity",
                    "ExternalGroupMessageListActivity",
                    "ExternalWechatUserMessageListActivity",
                    "MessageListActivity"
                )
                AccessibilityUtil.waitForPageMissing("CommonSelectActivity")
                uploadCommandResult(
                    message,
                    ExecCallbackBean.SUCCESS,
                    "",
                    startTime,
                    relaySelectResult.successList,
                    relaySelectResult.failList
                )
                goHome()
                return true
            } else {
                LogUtils.e("转发失败")
                if (retryCount > 0) {
                    goHome()
                    return pushMicroprogram(
                        message,
                        titleList,
                        appId, agentId, objectName, imageUrl, username, path, schema, description,
                        extraText,
                        retryCount - 1
                    )
                }
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_RELAY,
                    "转发失败: $objectName",
                    startTime,
                    listOf(),
                    titleList
                )
                goHome()
                return false
            }
        } else {
            LogUtils.e("非法操作")
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_ILLEGAL_OPERATION,
                "非法操作",
                startTime,
                listOf(),
                titleList
            )
            return false
        }
    }

    /**
     * 推送腾讯文档
     * @param titleList 待发送姓名列表
     * @param objectName 小程序名称
     * @param extraText  附加留言 可选
     */
    fun pushOffice(
        message: WeworkMessageBean,
        titleList: List<String>,
        objectName: String,
        extraText: String? = null
    ): Boolean {
        val startTime = System.currentTimeMillis()
        goHomeTab("文档")
        val allButton = AccessibilityUtil.findOneByText(getRoot(), "全部")
        if (allButton == null) {
            LogUtils.e("未找到全部按钮")
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_BUTTON,
                "未找到全部按钮",
                startTime,
                listOf(),
                titleList
            )
            return false
        }
        AccessibilityUtil.performClick(allButton)
        val myFileButton = AccessibilityUtil.findOneByText(getRoot(), "共享空间")
        if (myFileButton == null) {
            LogUtils.e("未找到共享空间按钮")
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_BUTTON,
                "未找到共享空间按钮",
                startTime,
                listOf(),
                titleList
            )
            return false
        }
        AccessibilityUtil.performClick(myFileButton)
        val buttonList = AccessibilityUtil.findAllByClazz(getRoot(), Views.Button)
        if (buttonList.size >= 4) {
            AccessibilityUtil.performClick(buttonList[3])
            AccessibilityUtil.findTextInput(getRoot(), objectName)
            val imageViewList = AccessibilityUtil.findAllByClazz(getRoot(), Views.ImageView)
            if (imageViewList.size >= 2) {
                AccessibilityUtil.performClick(imageViewList[1])
                val shareFileButton = AccessibilityUtil.findOneByDesc(getRoot(), "转发")
                AccessibilityUtil.performClick(shareFileButton)
                val relaySelectResult = relaySelectTarget(titleList, extraText)
                if (relaySelectResult.result) {
                    AccessibilityExtraUtil.loadingPage(
                        "CommonSelectActivity",
                        "ExternalGroupMessageListActivity",
                        "ExternalWechatUserMessageListActivity",
                        "MessageListActivity"
                    )
                    AccessibilityUtil.waitForPageMissing("CommonSelectActivity")
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.SUCCESS,
                        "",
                        startTime,
                        relaySelectResult.successList,
                        relaySelectResult.failList
                    )
                    goHome()
                    return true
                } else {
                    LogUtils.e("微盘文件转发失败: $objectName")
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.ERROR_RELAY,
                        "微盘文件转发失败: $objectName",
                        startTime,
                        listOf(),
                        titleList
                    )
                    goHome()
                    return false
                }
            } else {
                LogUtils.e("文档未搜索到相关文件: $objectName")
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_TARGET,
                    "文档未搜索到相关文件: $objectName",
                    startTime,
                    listOf(),
                    titleList
                )
                return false
            }
        } else {
            LogUtils.e("未找到文档搜索按钮")
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_BUTTON,
                "未找到文档搜索按钮",
                startTime,
                listOf(),
                titleList
            )
            return false
        }
    }

    /**
     * 推送文件(网络图片视频和文件等)
     * @see WeworkMessageBean.PUSH_FILE
     * @param titleList 待发送姓名列表
     * @param objectName 文件名称
     * @param fileUrl 文件网络地址
     * @param fileBase64 文件Base64
     * @param fileType 文件类型
     * @param extraText 附加留言 可选
     */
    fun pushFile(
        message: WeworkMessageBean,
        titleList: List<String>,
        objectName: String,
        fileUrl: String?,
        fileBase64: String?,
        fileType: String,
        extraText: String? = null,
        maxRetryCount: Int? = null
    ): Boolean {
        val retryCount = maxRetryCount ?: 2
        val startTime = System.currentTimeMillis()
        if (!PermissionUtils.isGrantedDrawOverlays()) {
            LogUtils.e("未打开悬浮窗权限")
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_ILLEGAL_PERMISSION,
                "未打开悬浮窗权限",
                startTime,
                listOf(),
                titleList
            )
            return false
        }
        if (fileUrl != null) {
            LogUtils.i("下载开始 $fileUrl")
            val execute = OkGo.get<File>(fileUrl).execute()
            LogUtils.i("下载完成 $fileUrl")
            val body = execute.body()
            if (body != null) {
                val df = SimpleDateFormat("yyyy-MM-dd")
                val filePath = "${
                    Utils.getApp().getExternalFilesDir("share")
                }/${df.format(Date())}/$objectName"
                val newFile = File(filePath)
                val create = FileUtils.createFileByDeleteOldFile(newFile)
                if (create && newFile.canWrite()) {
                    newFile.writeBytes(body.bytes())
                    LogUtils.i("文件存储本地成功 $filePath")
                    ShareUtil.share("${if (fileType.isBlank()) "*" else fileType}/*", newFile)
                    val tvFlag = AccessibilityUtil.findOneByText(
                        getRoot(true, share = true),
                        "发送给同事",
                        "选择联系人",
                        "选择参与人"
                    )
                    val flagText = tvFlag?.text?.toString() ?: ""
                    if (flagText.contains("发送给同事")) {
                        var shareToWorkButton = tvFlag
                        sleep(Constant.POP_WINDOW_INTERVAL)
                        if (shareToWorkButton == null) {
                            LogUtils.e("未找到发送给同事: $objectName")
                            if (retryCount > 0) {
                                return pushFile(
                                    message,
                                    titleList,
                                    objectName,
                                    fileUrl,
                                    fileBase64,
                                    fileType,
                                    extraText,
                                    retryCount - 1
                                )
                            }
                            uploadCommandResult(
                                message,
                                ExecCallbackBean.ERROR_RELAY,
                                "未找到发送给同事: $objectName",
                                startTime,
                                listOf(),
                                titleList
                            )
                            return false
                        }
                        AccessibilityUtil.performClick(shareToWorkButton)
                        sleep(Constant.POP_WINDOW_INTERVAL)
                        shareToWorkButton =
                            AccessibilityUtil.findOnceByText(getRoot(true, share = true), "发送给同事")
                        LogUtils.v(
                            "尝试发送给同事",
                            shareToWorkButton == null,
                            WeworkController.weworkService.currentPackage
                        )
                        val time = System.currentTimeMillis()
                        var currentTime = time
                        while (currentTime - time < 5000) {
                            if (shareToWorkButton != null
                                && WeworkController.weworkService.currentPackage != Constant.PACKAGE_NAMES
                            ) {
                                LogUtils.e("尝试手势点击！！！！！")
                                AccessibilityUtil.clickByNode(
                                    WeworkController.weworkService,
                                    shareToWorkButton
                                )
                                sleep(Constant.CHANGE_PAGE_INTERVAL)
                                shareToWorkButton = AccessibilityUtil.findOnceByText(
                                    getRoot(true, share = true),
                                    "发送给同事"
                                )
                            } else {
                                break
                            }
                            currentTime = System.currentTimeMillis()
                        }
                    } else if (flagText !in arrayOf("选择联系人", "选择参与人")) {
                        LogUtils.e("未找到发送给同事: $objectName")
                        if (retryCount > 0) {
                            return pushFile(
                                message,
                                titleList,
                                objectName,
                                fileUrl,
                                fileBase64,
                                fileType,
                                extraText,
                                retryCount - 1
                            )
                        }
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_RELAY,
                            "未找到发送给同事: $objectName",
                            startTime,
                            listOf(),
                            titleList
                        )
                        return false
                    }
                    val relaySelectResult = relaySelectTarget(titleList, extraText, timeout = 10000)
                    if (relaySelectResult.result) {
                        AccessibilityExtraUtil.loadingPage(
                            "CommonSelectActivity",
                            "ExternalGroupMessageListActivity",
                            "ExternalWechatUserMessageListActivity",
                            "MessageListActivity"
                        )
                        AccessibilityUtil.waitForPageMissing("CommonSelectActivity")
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.SUCCESS,
                            "",
                            startTime,
                            relaySelectResult.successList,
                            relaySelectResult.failList
                        )
                        goHome()
                        return true
                    } else {
                        LogUtils.e("文件转发失败: $objectName")
                        if (retryCount > 0) {
                            goHome()
                            return pushFile(
                                message,
                                titleList,
                                objectName,
                                fileUrl,
                                fileBase64,
                                fileType,
                                extraText,
                                retryCount - 1
                            )
                        }
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_RELAY,
                            "文件转发失败: $objectName",
                            startTime,
                            listOf(),
                            titleList
                        )
                        goHome()
                        return false
                    }
                } else {
                    LogUtils.e("文件存储本地失败 $filePath")
                    if (retryCount > 0) {
                        return pushFile(
                            message,
                            titleList,
                            objectName,
                            fileUrl,
                            fileBase64,
                            fileType,
                            extraText,
                            retryCount - 1
                        )
                    }
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.ERROR_FILE_STORAGE,
                        "文件存储本地失败 $filePath",
                        startTime,
                        listOf(),
                        titleList
                    )
                    return false
                }
            } else {
                LogUtils.e("文件下载失败")
                if (retryCount > 0) {
                    return pushFile(
                        message,
                        titleList,
                        objectName,
                        fileUrl,
                        fileBase64,
                        fileType,
                        extraText,
                        retryCount - 1
                    )
                }
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_FILE_DOWNLOAD,
                    "文件下载失败 $fileUrl",
                    startTime,
                    listOf(),
                    titleList
                )
                return false
            }
        } else if (fileBase64 != null) {
            val df = SimpleDateFormat("yyyy-MM-dd")
            val filePath = "${
                Utils.getApp().getExternalFilesDir("share")
            }/${df.format(Date())}/$objectName"
            val newFile = File(filePath)
            val create = FileUtils.createFileByDeleteOldFile(newFile)
            if (create && newFile.canWrite()) {
                newFile.writeBytes(EncodeUtils.base64Decode(fileBase64))
                LogUtils.i("文件存储本地成功 $filePath")
                ShareUtil.share("${if (fileType.isBlank()) "*" else fileType}/*", newFile)
                val tvFlag = AccessibilityUtil.findOneByText(
                    getRoot(true, share = true),
                    "发送给同事",
                    "选择联系人",
                    "选择参与人"
                )
                val flagText = tvFlag?.text?.toString() ?: ""
                if (flagText.contains("发送给同事")) {
                    var shareToWorkButton = tvFlag
                    sleep(Constant.POP_WINDOW_INTERVAL)
                    if (shareToWorkButton == null) {
                        LogUtils.e("未找到发送给同事: $objectName")
                        if (retryCount > 0) {
                            return pushFile(
                                message,
                                titleList,
                                objectName,
                                fileUrl,
                                fileBase64,
                                fileType,
                                extraText,
                                retryCount - 1
                            )
                        }
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_RELAY,
                            "未找到发送给同事: $objectName",
                            startTime,
                            listOf(),
                            titleList
                        )
                        return false
                    }
                    AccessibilityUtil.performClick(shareToWorkButton)
                    sleep(Constant.POP_WINDOW_INTERVAL)
                    shareToWorkButton =
                        AccessibilityUtil.findOnceByText(getRoot(true, share = true), "发送给同事")
                    LogUtils.v(
                        "尝试发送给同事",
                        shareToWorkButton == null,
                        WeworkController.weworkService.currentPackage
                    )
                    val time = System.currentTimeMillis()
                    var currentTime = time
                    while (currentTime - time < 5000) {
                        if (shareToWorkButton != null
                            && WeworkController.weworkService.currentPackage != Constant.PACKAGE_NAMES
                        ) {
                            LogUtils.e("尝试手势点击！！！！！")
                            AccessibilityUtil.clickByNode(
                                WeworkController.weworkService,
                                shareToWorkButton
                            )
                            sleep(Constant.CHANGE_PAGE_INTERVAL)
                            shareToWorkButton = AccessibilityUtil.findOnceByText(
                                getRoot(true, share = true),
                                "发送给同事"
                            )
                        } else {
                            break
                        }
                        currentTime = System.currentTimeMillis()
                    }
                } else if (flagText !in arrayOf("选择联系人", "选择参与人")) {
                    LogUtils.e("未找到发送给同事: $objectName")
                    if (retryCount > 0) {
                        return pushFile(
                            message,
                            titleList,
                            objectName,
                            fileUrl,
                            fileBase64,
                            fileType,
                            extraText,
                            retryCount - 1
                        )
                    }
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.ERROR_RELAY,
                        "未找到发送给同事: $objectName",
                        startTime,
                        listOf(),
                        titleList
                    )
                    return false
                }
                val relaySelectResult = relaySelectTarget(titleList, extraText, timeout = 10000)
                if (relaySelectResult.result) {
                    AccessibilityExtraUtil.loadingPage(
                        "CommonSelectActivity",
                        "ExternalGroupMessageListActivity",
                        "ExternalWechatUserMessageListActivity",
                        "MessageListActivity"
                    )
                    AccessibilityUtil.waitForPageMissing("CommonSelectActivity")
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.SUCCESS,
                        "",
                        startTime,
                        relaySelectResult.successList,
                        relaySelectResult.failList
                    )
                    goHome()
                    return true
                } else {
                    LogUtils.e("文件转发失败: $objectName")
                    if (retryCount > 0) {
                        goHome()
                        return pushFile(
                            message,
                            titleList,
                            objectName,
                            fileUrl,
                            fileBase64,
                            fileType,
                            extraText,
                            retryCount - 1
                        )
                    }
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.ERROR_RELAY,
                        "文件转发失败: $objectName",
                        startTime,
                        listOf(),
                        titleList
                    )
                    goHome()
                    return false
                }
            } else {
                LogUtils.e("文件存储本地失败 $filePath")
                if (retryCount > 0) {
                    return pushFile(
                        message,
                        titleList,
                        objectName,
                        fileUrl,
                        fileBase64,
                        fileType,
                        extraText,
                        retryCount - 1
                    )
                }
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_FILE_STORAGE,
                    "文件存储本地失败 $filePath",
                    startTime,
                    listOf(),
                    titleList
                )
                return false
            }
        } else {
            LogUtils.e("未找到文件资源参数")
            if (retryCount > 0) {
                return pushFile(
                    message,
                    titleList,
                    objectName,
                    fileUrl,
                    fileBase64,
                    fileType,
                    extraText,
                    retryCount - 1
                )
            }
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_ILLEGAL_DATA,
                "未找到文件资源参数",
                startTime,
                listOf(),
                titleList
            )
            return false
        }
    }

    /**
     * 推送链接
     * @see WeworkMessageBean.PUSH_LINK
     * @param titleList 待发送姓名列表
     * @param objectName 文章标题
     * @param receivedContent 文章副标题
     * @param originalContent 文章链接地址
     * @param fileUrl 图片地址
     * @param extraText 附加留言 可选
     */
    fun pushLink(
        message: WeworkMessageBean,
        titleList: List<String>,
        objectName: String,
        receivedContent: String,
        originalContent: String,
        fileUrl: String,
        appId: String?,
        agentId: String?,
        extraText: String? = null,
        maxRetryCount: Int? = null
    ): Boolean {
        val retryCount = maxRetryCount ?: 2
        val startTime = System.currentTimeMillis()
        if (IWWAPIUtil.sendLink(
                appId,
                agentId,
                fileUrl,
                originalContent,
                objectName,
                receivedContent
            )
        ) {
            val relaySelectResult = relaySelectTarget(titleList, extraText)
            if (relaySelectResult.result) {
                AccessibilityExtraUtil.loadingPage(
                    "CommonSelectActivity",
                    "ExternalGroupMessageListActivity",
                    "ExternalWechatUserMessageListActivity",
                    "MessageListActivity"
                )
                AccessibilityUtil.waitForPageMissing("CommonSelectActivity")
                uploadCommandResult(
                    message,
                    ExecCallbackBean.SUCCESS,
                    "",
                    startTime,
                    relaySelectResult.successList,
                    relaySelectResult.failList
                )
                goHome()
                return true
            } else {
                LogUtils.e("转发失败")
                if (retryCount > 0) {
                    goHome()
                    return pushLink(
                        message,
                        titleList,
                        objectName,
                        receivedContent,
                        originalContent,
                        fileUrl,
                        appId,
                        agentId,
                        extraText,
                        retryCount - 1
                    )
                }
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_RELAY,
                    "转发失败: $objectName",
                    startTime,
                    listOf(),
                    titleList
                )
                goHome()
                return false
            }
        } else {
            LogUtils.e("非法操作")
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_ILLEGAL_OPERATION,
                "非法操作",
                startTime,
                listOf(),
                titleList
            )
            return false
        }
    }

    /**
     * 撤回消息
     * @see WeworkMessageBean.RECALL_MESSAGE
     * @param titleList 房间名称
     * @param originalContent 原始消息的内容
     * @param textType 原始消息的消息类型
     * @see WeworkMessageBean.TEXT_TYPE
     */
    fun recallMessage(
        message: WeworkMessageBean,
        titleList: List<String>,
        originalContent: String,
        textType: Int
    ): Boolean {
        val startTime = System.currentTimeMillis()
        for (title in LinkedHashSet(titleList)) {
            if (WeworkRoomUtil.intoRoom(title) || WeworkRoomUtil.intoRoom(title, fastIn = false)) {
                if (WeworkTextUtil.longClickMyMessageItem(
                        //聊天消息列表 1ListView 0RecycleView xViewGroup
                        AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView),
                        textType,
                        originalContent,
                        "撤回"
                    )
                ) {
                    LogUtils.d("撤回成功")
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.SUCCESS,
                        "",
                        startTime,
                        titleList,
                        listOf()
                    )
                    return true
                } else {
                    LogUtils.e("撤回失败 未找到目标消息")
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.ERROR_TARGET,
                        "撤回失败 未找到目标消息",
                        startTime,
                        listOf(),
                        titleList
                    )
                    return false
                }
            }
        }
        LogUtils.e("撤回失败 未找到房间")
        uploadCommandResult(
            message,
            ExecCallbackBean.ERROR_TARGET,
            "撤回失败 未找到房间",
            startTime,
            listOf(),
            titleList
        )
        return false
    }

    /**
     * 批量转发
     * @see WeworkMessageBean.RELAY_MULTI_MESSAGE
     * @param titleList 房间名称
     * @param messageList 消息列表
     * @param nameList 待转发姓名列表
     * @param extraText 附加留言 选填
     * @see WeworkMessageBean.TEXT_TYPE
     */
    fun relayMultiMessage(
        message: WeworkMessageBean,
        titleList: List<String>,
        messageList: List<WeworkMessageBean.SubMessageBean>,
        nameList: List<String>,
        extraText: String? = null
    ): Boolean {
        return relayMultiMessage(message, titleList, messageList, nameList, extraText, "逐条转发")
    }

    /**
     * 合并转发
     * @see WeworkMessageBean.RELAY_MERGE_MESSAGE
     * @param titleList 房间名称
     * @param messageList 消息列表
     * @param nameList 待转发姓名列表
     * @param extraText 附加留言 选填
     * @see WeworkMessageBean.TEXT_TYPE
     */
    fun relayMergeMessage(
        message: WeworkMessageBean,
        titleList: List<String>,
        messageList: List<WeworkMessageBean.SubMessageBean>,
        nameList: List<String>,
        extraText: String? = null
    ): Boolean {
        return relayMultiMessage(message, titleList, messageList, nameList, extraText, "合并转发")
    }

    /**
     * 批量发送
     * @see WeworkMessageBean.SEND_MULTI_MESSAGE
     * @param weworkMessageList 消息列表
     * @param nameList 待转发姓名列表
     * @param extraText 附加留言 选填
     * @see WeworkMessageBean.TEXT_TYPE
     */
    fun sendMultiMessage(
        message: WeworkMessageBean,
        weworkMessageList: List<WeworkMessageBean>,
        nameList: List<String>,
        extraText: String? = null
    ): Boolean {
        return sendMultiMessage(message, weworkMessageList, nameList, extraText, "逐条转发")
    }

    /**
     * 合并发送
     * @see WeworkMessageBean.SEND_MERGE_MESSAGE
     * @param weworkMessageList 消息列表
     * @param nameList 待转发姓名列表
     * @param extraText 附加留言 选填
     * @see WeworkMessageBean.TEXT_TYPE
     */
    fun sendMergeMessage(
        message: WeworkMessageBean,
        weworkMessageList: List<WeworkMessageBean>,
        nameList: List<String>,
        extraText: String? = null
    ): Boolean {
        return sendMultiMessage(message, weworkMessageList, nameList, extraText, "合并转发")
    }

    /**
     * 批量发送 合并发送
     */
    private fun sendMultiMessage(
        message: WeworkMessageBean,
        weworkMessageList: List<WeworkMessageBean>,
        nameList: List<String>,
        extraText: String? = null,
        key: String,
        maxRetryCount: Int? = null
    ): Boolean {
        val retryCount = maxRetryCount ?: 2
        val startTime = System.currentTimeMillis()
        if (extraText == "单点发送") {
            LogUtils.d("单点发送")
            for (title in nameList) {
                singleSendMultiMessage(message, weworkMessageList, startTime, title)
            }
            return true
        }
        val groupName = "消息转发专用群"
        val titleList = arrayListOf(groupName)
        message.titleList = titleList
        if (!WeworkRoomUtil.isGroupExists(groupName)) {
            if (!createGroup()) {
                LogUtils.e("创建群失败")
                if (retryCount > 0) {
                    return sendMultiMessage(
                        message,
                        weworkMessageList,
                        nameList,
                        extraText,
                        key,
                        retryCount - 1
                    )
                }
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_CREATE_GROUP,
                    "创建群失败",
                    startTime,
                    listOf(),
                    nameList
                )
                return false
            }
            if (!groupRename(groupName)) {
                LogUtils.e("创建群成功 群改名失败")
                if (retryCount > 0) {
                    return sendMultiMessage(
                        message,
                        weworkMessageList,
                        nameList,
                        extraText,
                        key,
                        retryCount - 1
                    )
                }
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_GROUP_RENAME,
                    "创建群成功 群改名失败",
                    startTime,
                    listOf(),
                    nameList
                )
                return false
            }
        }
        LogUtils.d("进入转发专用群")
        sendMessage(message, message.titleList, startTime.toString())
        for (weworkMessage in weworkMessageList) {
            weworkMessage.titleList = message.titleList
            weworkMessage.messageId = message.messageId
            weworkMessage.meta = message.meta
            when (weworkMessage.type) {
                WeworkMessageBean.SEND_MESSAGE -> {
                    WeworkController.sendMessage(weworkMessage)
                }
                WeworkMessageBean.PUSH_MICRO_DISK_IMAGE -> {
                    WeworkController.pushMicroDiskImage(weworkMessage)
                }
                WeworkMessageBean.PUSH_MICRO_DISK_FILE -> {
                    WeworkController.pushMicroDiskFile(weworkMessage)
                }
                WeworkMessageBean.PUSH_MICROPROGRAM -> {
                    WeworkController.pushMicroprogram(weworkMessage)
                }
                WeworkMessageBean.PUSH_OFFICE -> {
                    WeworkController.pushOffice(weworkMessage)
                }
                WeworkMessageBean.PUSH_FILE -> {
                    WeworkController.pushFile(weworkMessage)
                }
                WeworkMessageBean.PUSH_LINK -> {
                    WeworkController.pushLink(weworkMessage)
                }
            }
        }
        val maxLength = 9
        for (chunkedNameList in nameList.chunked(maxLength)) {
            subSendMultiMessage(message, startTime, groupName, chunkedNameList, extraText, key)
        }
        return true
    }

    /**
     * 批量发送 合并发送 子任务-单点发送
     */
    private fun singleSendMultiMessage(
        message: WeworkMessageBean,
        weworkMessageList: List<WeworkMessageBean>,
        startTime: Long,
        title: String
    ): Boolean {
        val titleList = arrayListOf(title)
        if (WeworkRoomUtil.intoRoom(title) || WeworkRoomUtil.intoRoom(title, fastIn = false)) {
            for (weworkMessage in weworkMessageList) {
                weworkMessage.titleList = titleList
                weworkMessage.messageId = message.messageId
                weworkMessage.meta = message.meta
                when (weworkMessage.type) {
                    WeworkMessageBean.SEND_MESSAGE -> {
                        WeworkController.sendMessage(weworkMessage)
                    }
                    WeworkMessageBean.PUSH_MICRO_DISK_IMAGE -> {
                        WeworkController.pushMicroDiskImage(weworkMessage)
                    }
                    WeworkMessageBean.PUSH_MICRO_DISK_FILE -> {
                        WeworkController.pushMicroDiskFile(weworkMessage)
                    }
                    WeworkMessageBean.PUSH_MICROPROGRAM -> {
                        WeworkController.pushMicroprogram(weworkMessage)
                    }
                    WeworkMessageBean.PUSH_OFFICE -> {
                        WeworkController.pushOffice(weworkMessage)
                    }
                    WeworkMessageBean.PUSH_FILE -> {
                        WeworkController.pushFile(weworkMessage)
                    }
                    WeworkMessageBean.PUSH_LINK -> {
                        WeworkController.pushLink(weworkMessage)
                    }
                }
            }
            return true
        }
        uploadCommandResult(
            message,
            ExecCallbackBean.ERROR_INTO_ROOM,
            "$title: 单点发送失败 未找到房间",
            startTime,
            listOf(),
            titleList
        )
        return false
    }

    /**
     * 批量发送 合并发送 子任务-转发
     */
    private fun subSendMultiMessage(
        message: WeworkMessageBean,
        startTime: Long,
        groupName: String,
        nameList: List<String>,
        extraText: String? = null,
        key: String,
        maxRetryCount: Int? = null
    ): Boolean {
        val retryCount = maxRetryCount ?: 2
        val titleList = arrayListOf(groupName)
        if (WeworkRoomUtil.intoRoom(groupName) || WeworkRoomUtil.intoRoom(
                groupName,
                fastIn = false
            )
        ) {
            if (WeworkTextUtil.longClickMyMessageItem(
                    //聊天消息列表 1ListView 0RecycleView xViewGroup
                    AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView),
                    WeworkMessageBean.TEXT_TYPE_PLAIN,
                    startTime.toString(),
                    "多选"
                )
            ) {
                LogUtils.d("多选成功")
            } else {
                LogUtils.e("$groupName: 多选失败")
                if (retryCount > 0) {
                    return subSendMultiMessage(
                        message,
                        startTime,
                        groupName,
                        nameList,
                        extraText,
                        key,
                        retryCount - 1
                    )
                }
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_BUTTON,
                    "多选失败 $startTime",
                    startTime,
                    listOf(),
                    nameList
                )
                return false
            }
            //聊天消息列表 1ListView 0RecycleView xViewGroup
            val list = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
            if (list != null) {
                var childCount = list.childCount
                LogUtils.v("消息条数: $childCount")
                var start = false
                var first = true
                for (i in 0 until list.childCount) {
                    val item = list.getChild(i)
                    if (item != null && item.childCount > 0) {
                        if (!start) {
                            val parseChatMessageItem = WeworkLoopImpl.parseChatMessageItem(
                                item,
                                titleList,
                                WeworkMessageBean.ROOM_TYPE_EXTERNAL_GROUP
                            )
                            if (parseChatMessageItem.itemMessageList.find { it.feature == 2 && it.text?.toString() == startTime.toString() } != null) {
                                start = true
                            }
                        }
                        if (start) {
                            if (Constant.version >= 40108) {
                                if (AccessibilityUtil.findOnceByClazz(
                                        item,
                                        Views.CheckBox
                                    )?.isChecked == first
                                ) {
                                    AccessibilityUtil.clickByNode(
                                        WeworkController.weworkService,
                                        item
                                    )
                                    LogUtils.d("单击成功")
                                    sleep(Constant.POP_WINDOW_INTERVAL / 2)
                                }
                                first = false
                            } else {
                                AccessibilityUtil.clickByNode(WeworkController.weworkService, item)
                                LogUtils.d("单击成功")
                                sleep(Constant.POP_WINDOW_INTERVAL / 2)
                            }
                        }
                    }
                }
                list.refresh()
                childCount = list.childCount
                LogUtils.d("开始二次校验转发条目")
                LogUtils.v("消息条数: $childCount")
                start = false
                first = true
                for (i in 0 until list.childCount) {
                    val item = list.getChild(i)
                    if (item != null && item.childCount > 0) {
                        if (!start) {
                            val parseChatMessageItem = WeworkLoopImpl.parseChatMessageItem(
                                item,
                                titleList,
                                WeworkMessageBean.ROOM_TYPE_EXTERNAL_GROUP
                            )
                            if (parseChatMessageItem.itemMessageList.find { it.feature == 2 && it.text?.toString() == startTime.toString() } != null) {
                                start = true
                            }
                        }
                        if (start) {
                            if (Constant.version >= 40108) {
                                if (AccessibilityUtil.findOnceByClazz(
                                        item,
                                        Views.CheckBox
                                    )?.isChecked == first
                                ) {
                                    AccessibilityUtil.clickByNode(
                                        WeworkController.weworkService,
                                        item
                                    )
                                    LogUtils.d("单击成功")
                                    sleep(Constant.POP_WINDOW_INTERVAL / 2)
                                }
                                first = false
                            } else {
                                AccessibilityUtil.clickByNode(WeworkController.weworkService, item)
                                LogUtils.d("单击成功")
                                sleep(Constant.POP_WINDOW_INTERVAL / 2)
                            }
                        }
                    }
                }
                LogUtils.d("完成二次校验转发条目")
            }
            val bottomList =
                AccessibilityUtil.findOnceByClazz(getRoot(), Views.ViewGroup, minChildCount = 4)
            if (AccessibilityUtil.performClickWithSon(bottomList)) {
                if (AccessibilityUtil.findTextAndClick(getRoot(), key)) {
                    val relaySelectResult = relaySelectTarget(nameList, extraText)
                    if (relaySelectResult.result) {
                        AccessibilityExtraUtil.loadingPage(
                            "CommonSelectActivity",
                            "ExternalGroupMessageListActivity",
                            "ExternalWechatUserMessageListActivity",
                            "MessageListActivity"
                        )
                        AccessibilityUtil.waitForPageMissing("CommonSelectActivity")
                        LogUtils.d("$groupName: 转发成功")
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.SUCCESS,
                            "$groupName: 转发成功",
                            startTime,
                            relaySelectResult.successList,
                            relaySelectResult.failList
                        )
                        goHome()
                        return true
                    } else {
                        LogUtils.e("$groupName: 转发失败")
                        if (retryCount > 0) {
                            goHome()
                            return subSendMultiMessage(
                                message,
                                startTime,
                                groupName,
                                nameList,
                                extraText,
                                key,
                                retryCount - 1
                            )
                        }
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_RELAY,
                            "$groupName: 转发失败",
                            startTime,
                            listOf(),
                            nameList
                        )
                        goHome()
                        return false
                    }
                } else {
                    LogUtils.e("未找到逐条转发按钮")
                    if (retryCount > 0) {
                        return subSendMultiMessage(
                            message,
                            startTime,
                            groupName,
                            nameList,
                            extraText,
                            key,
                            retryCount - 1
                        )
                    }
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.ERROR_BUTTON,
                        "未找到逐条转发按钮",
                        startTime,
                        listOf(),
                        nameList
                    )
                    return false
                }
            } else {
                LogUtils.e("未找到转发按钮")
                if (retryCount > 0) {
                    return subSendMultiMessage(
                        message,
                        startTime,
                        groupName,
                        nameList,
                        extraText,
                        key,
                        retryCount - 1
                    )
                }
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_BUTTON,
                    "未找到转发按钮",
                    startTime,
                    listOf(),
                    nameList
                )
                return false
            }
        } else {
            LogUtils.d("$groupName: 转发失败 未找到房间")
            if (retryCount > 0) {
                return subSendMultiMessage(
                    message,
                    startTime,
                    groupName,
                    nameList,
                    extraText,
                    key,
                    retryCount - 1
                )
            }
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_INTO_ROOM,
                "$groupName: 转发失败 未找到房间",
                startTime,
                listOf(),
                nameList
            )
            return false
        }
    }

    /**
     * 批量转发 合并转发
     */
    private fun relayMultiMessage(
        message: WeworkMessageBean,
        titleList: List<String>,
        messageList: List<WeworkMessageBean.SubMessageBean>,
        nameList: List<String>,
        extraText: String? = null,
        key: String,
        maxRetryCount: Int? = null
    ): Boolean {
        val retryCount = maxRetryCount ?: 2
        val startTime = System.currentTimeMillis()
        if (messageList.isEmpty()) {
            LogUtils.e("转发内容为空")
            if (retryCount > 0) {
                return relayMultiMessage(
                    message,
                    titleList,
                    messageList,
                    nameList,
                    extraText,
                    key,
                    retryCount - 1
                )
            }
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_ILLEGAL_DATA,
                "转发内容为空",
                startTime,
                listOf(),
                nameList
            )
            return false
        } else if (messageList.size == 1) {
            val subMessageBean = messageList.first()
            val receivedName = subMessageBean.nameList?.firstOrNull()
            val textType = subMessageBean.textType
            val originalContent = subMessageBean.itemMessageList?.firstOrNull()?.text ?: ""
            LogUtils.d("receivedName $receivedName textType $textType originalContent $originalContent")
            return relayMessage(
                message,
                titleList,
                receivedName,
                originalContent,
                textType,
                nameList,
                extraText
            )
        }
        for (title in LinkedHashSet(titleList)) {
            if (WeworkRoomUtil.intoRoom(title) || WeworkRoomUtil.intoRoom(title, fastIn = false)) {
                var hasOpenMulti = false
                for (subMessageBean in messageList) {
                    val receivedName = subMessageBean.nameList?.firstOrNull()
                    val textType = subMessageBean.textType
                    val originalContent = subMessageBean.itemMessageList?.firstOrNull()?.text ?: ""
                    LogUtils.d("receivedName $receivedName textType $textType originalContent $originalContent")
                    if (!hasOpenMulti) {
                        if (!receivedName.isNullOrEmpty()) {
                            if (WeworkTextUtil.longClickMessageItem(
                                    //聊天消息列表 1ListView 0RecycleView xViewGroup
                                    AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView),
                                    textType,
                                    receivedName,
                                    originalContent,
                                    "多选"
                                )
                            ) {
                                LogUtils.d("多选成功")
                                hasOpenMulti = true
                            } else {
                                LogUtils.e("$title: 多选失败")
                                if (retryCount > 0) {
                                    return relayMultiMessage(
                                        message,
                                        titleList,
                                        messageList,
                                        nameList,
                                        extraText,
                                        key,
                                        retryCount - 1
                                    )
                                }
                                uploadCommandResult(
                                    message,
                                    ExecCallbackBean.ERROR_BUTTON,
                                    "多选失败 $originalContent",
                                    startTime,
                                    listOf(),
                                    nameList
                                )
                                return false
                            }
                        } else {
                            if (WeworkTextUtil.longClickMyMessageItem(
                                    //聊天消息列表 1ListView 0RecycleView xViewGroup
                                    AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView),
                                    textType,
                                    originalContent,
                                    "多选"
                                )
                            ) {
                                LogUtils.d("多选成功")
                                hasOpenMulti = true
                            } else {
                                LogUtils.e("$title: 多选失败")
                                if (retryCount > 0) {
                                    return relayMultiMessage(
                                        message,
                                        titleList,
                                        messageList,
                                        nameList,
                                        extraText,
                                        key,
                                        retryCount - 1
                                    )
                                }
                                uploadCommandResult(
                                    message,
                                    ExecCallbackBean.ERROR_BUTTON,
                                    "多选失败 $originalContent",
                                    startTime,
                                    listOf(),
                                    nameList
                                )
                                return false
                            }
                        }
                    } else {
                        if (!receivedName.isNullOrEmpty()) {
                            if (WeworkTextUtil.longClickMessageItem(
                                    //聊天消息列表 1ListView 0RecycleView xViewGroup
                                    AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView),
                                    textType,
                                    receivedName,
                                    originalContent,
                                    "单击"
                                )
                            ) {
                                LogUtils.d("单击成功 $originalContent")
                                sleep(Constant.POP_WINDOW_INTERVAL / 2)
                            } else {
                                LogUtils.e("$title: 单击失败")
                                error("$title: 单击失败 $originalContent")
                            }
                        } else {
                            if (WeworkTextUtil.longClickMyMessageItem(
                                    //聊天消息列表 1ListView 0RecycleView xViewGroup
                                    AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView),
                                    textType,
                                    originalContent,
                                    "单击"
                                )
                            ) {
                                LogUtils.d("单击成功 $originalContent")
                                sleep(Constant.POP_WINDOW_INTERVAL / 2)
                            } else {
                                LogUtils.e("$title: 单击失败")
                                error("$title: 单击失败 $originalContent")
                            }
                        }
                    }
                }
                if (hasOpenMulti) {
                    val bottomList = AccessibilityUtil.findOnceByClazz(
                        getRoot(),
                        Views.ViewGroup,
                        minChildCount = 4
                    )
                    if (AccessibilityUtil.performClickWithSon(bottomList)) {
                        if (AccessibilityUtil.findTextAndClick(getRoot(), key)) {
                            val relaySelectResult = relaySelectTarget(nameList, extraText)
                            if (relaySelectResult.result) {
                                AccessibilityExtraUtil.loadingPage(
                                    "CommonSelectActivity",
                                    "ExternalGroupMessageListActivity",
                                    "ExternalWechatUserMessageListActivity",
                                    "MessageListActivity"
                                )
                                AccessibilityUtil.waitForPageMissing("CommonSelectActivity")
                                LogUtils.d("$title: 转发成功")
                                uploadCommandResult(
                                    message,
                                    ExecCallbackBean.SUCCESS,
                                    "$title: 转发成功",
                                    startTime,
                                    relaySelectResult.successList,
                                    relaySelectResult.failList
                                )
                                goHome()
                                return true
                            } else {
                                LogUtils.e("$title: 转发失败")
                                if (retryCount > 0) {
                                    goHome()
                                    return relayMultiMessage(
                                        message,
                                        titleList,
                                        messageList,
                                        nameList,
                                        extraText,
                                        key,
                                        retryCount - 1
                                    )
                                }
                                uploadCommandResult(
                                    message,
                                    ExecCallbackBean.ERROR_RELAY,
                                    "$title: 转发失败",
                                    startTime,
                                    listOf(),
                                    nameList
                                )
                                goHome()
                                return false
                            }
                        } else {
                            LogUtils.e("未找到逐条转发按钮")
                            if (retryCount > 0) {
                                return relayMultiMessage(
                                    message,
                                    titleList,
                                    messageList,
                                    nameList,
                                    extraText,
                                    key,
                                    retryCount - 1
                                )
                            }
                            uploadCommandResult(
                                message,
                                ExecCallbackBean.ERROR_BUTTON,
                                "未找到逐条转发按钮",
                                startTime,
                                listOf(),
                                nameList
                            )
                            return false
                        }
                    } else {
                        LogUtils.e("未找到转发按钮")
                        if (retryCount > 0) {
                            return relayMultiMessage(
                                message,
                                titleList,
                                messageList,
                                nameList,
                                extraText,
                                key,
                                retryCount - 1
                            )
                        }
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_BUTTON,
                            "未找到转发按钮",
                            startTime,
                            listOf(),
                            nameList
                        )
                        return false
                    }
                }
            } else {
                LogUtils.d("$title: 转发失败 未找到房间")
                if (retryCount > 0) {
                    return relayMultiMessage(
                        message,
                        titleList,
                        messageList,
                        nameList,
                        extraText,
                        key,
                        retryCount - 1
                    )
                }
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_INTO_ROOM,
                    "$title: 转发失败 未找到房间",
                    startTime,
                    listOf(),
                    nameList
                )
                return false
            }
        }
        LogUtils.d("转发失败 未找到房间名")
        if (retryCount > 0) {
            return relayMultiMessage(
                message,
                titleList,
                messageList,
                nameList,
                extraText,
                key,
                retryCount - 1
            )
        }
        uploadCommandResult(
            message,
            ExecCallbackBean.ERROR_ILLEGAL_DATA,
            "转发失败 未找到房间名",
            startTime,
            listOf(),
            nameList
        )
        return false
    }

    /**
     * 手机号添加好友或修改好友信息
     * @see WeworkMessageBean.ADD_FRIEND_BY_PHONE
     * @param friend 待添加用户
     */
    fun addFriendByPhone(
        message: WeworkMessageBean,
        friend: WeworkMessageBean.Friend
    ): Boolean {
        val startTime = System.currentTimeMillis()
        //如果已经是好友的可以传name修改好友信息
        if (friend.phone == null && friend.name != null) {
            if (getFriendInfo(friend.name)) {
                if (modifyFriendInfo(friend, addFriend = false)) {
                    LogUtils.d("修改好友信息成功: ${friend.name}")
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.SUCCESS,
                        "",
                        startTime,
                        listOf(friend.name),
                        listOf()
                    )
                    return true
                } else {
                    LogUtils.e("修改用户信息失败: ${friend.name}")
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.ERROR_BUTTON,
                        "修改用户信息失败: ${friend.name}",
                        startTime,
                        listOf(),
                        listOf(friend.name)
                    )
                    return false
                }
            } else {
                LogUtils.e("未找到用户: ${friend.name}")
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_TARGET,
                    "未找到用户: ${friend.name}",
                    startTime,
                    listOf(),
                    listOf(friend.name)
                )
                return false
            }
        }
        //手机号添加好友
        goHome()
        val list = AccessibilityUtil.findOneByClazz(
            getRoot(),
            Views.RecyclerView,
            Views.ListView,
            Views.ViewGroup
        )
        if (list != null) {
            val frontNode = AccessibilityUtil.findFrontNode(list)
            val textViewList = AccessibilityUtil.findAllOnceByClazz(frontNode, Views.TextView)
            if (textViewList.size >= 2) {
                val searchButton: AccessibilityNodeInfo = textViewList[textViewList.size - 2]
                val multiButton: AccessibilityNodeInfo = textViewList[textViewList.size - 1]
                AccessibilityUtil.performClick(multiButton)
                sleep(Constant.POP_WINDOW_INTERVAL)
                val list = AccessibilityUtil.findAllByClazz(getRoot(), Views.ListView).lastOrNull()
                if (list != null) {
                    val button = AccessibilityUtil.findOneByText(
                        list,
                        "添加客户",
                        "添加居民",
                        "加微信",
                        "添加学员",
                        exact = true
                    )
                    if (button != null) {
                        AccessibilityUtil.performClick(button)
                        sleep(Constant.POP_WINDOW_INTERVAL)
                        AccessibilityUtil.findTextAndClick(getRoot(), "搜索手机号添加")
                        AccessibilityUtil.findTextInput(getRoot(), friend.phone.trim())
                        if (AccessibilityUtil.findTextAndClick(getRoot(), "网络查找手机")) {
                            sleep(Constant.POP_WINDOW_INTERVAL)
                            val bothUsedTv = AccessibilityUtil.findOneByTextRegex(
                                getRoot(),
                                "(对方同时使用.*?)|(标签)|(电话)|(描述)|(设置备注和描述)",
                                timeout = 2000
                            )
                            val bothUsedText = bothUsedTv?.text
                            if (bothUsedText != null && bothUsedText.contains("对方同时使用")) {
                                AccessibilityUtil.performClick(
                                    AccessibilityUtil.findOnceByClazz(
                                        AccessibilityUtil.findBackNode(bothUsedTv),
                                        Views.ImageView
                                    )
                                )
                            } else if (AccessibilityUtil.findOnceByText(
                                    getRoot(),
                                    "该用户不存在"
                                ) != null
                            ) {
                                LogUtils.e("该用户不存在: ${friend.phone}")
                                uploadCommandResult(
                                    message,
                                    ExecCallbackBean.ERROR_TARGET,
                                    "该用户不存在: ${friend.phone}",
                                    startTime,
                                    listOf(),
                                    listOf(friend.phone)
                                )
                                return false
                            }
                            if (modifyFriendInfo(friend)) {
                                if (AccessibilityUtil.findTextAndClick(
                                        getRoot(),
                                        "添加为联系人",
                                        timeout = 2000
                                    )
                                ) {
                                    LogUtils.d("准备发送好友邀请: ${friend.phone}")
                                    if (!friend.leavingMsg.isNullOrEmpty()) {
                                        AccessibilityUtil.findTextInput(
                                            getRoot(),
                                            friend.leavingMsg
                                        )
                                    }
                                    if (AccessibilityUtil.findTextAndClick(
                                            getRoot(),
                                            "发送添加邀请",
                                            "发送申请"
                                        )
                                    ) {
                                        LogUtils.d("发送添加邀请成功: ${friend.phone}")
                                        uploadCommandResult(
                                            message,
                                            ExecCallbackBean.SUCCESS,
                                            "",
                                            startTime,
                                            listOf(friend.phone),
                                            listOf()
                                        )
                                        return true
                                    } else {
                                        LogUtils.e("未找到发送邀请按钮")
                                        uploadCommandResult(
                                            message,
                                            ExecCallbackBean.ERROR_BUTTON,
                                            "未找到发送邀请按钮",
                                            startTime,
                                            listOf(),
                                            listOf(friend.phone)
                                        )
                                        return false
                                    }
                                } else {
                                    if (AccessibilityUtil.findOnceByText(
                                            getRoot(),
                                            "发消息",
                                            exact = true
                                        ) != null
                                    ) {
                                        LogUtils.e("已经添加联系人，请勿重复添加" + friend.phone)
                                        uploadCommandResult(
                                            message,
                                            ExecCallbackBean.ERROR_REPEAT,
                                            "已经添加联系人，请勿重复添加" + friend.phone,
                                            startTime,
                                            listOf(),
                                            listOf(friend.phone)
                                        )
                                        return false
                                    } else {
                                        LogUtils.e("未找到添加为联系人")
                                        uploadCommandResult(
                                            message,
                                            ExecCallbackBean.ERROR_BUTTON,
                                            "未找到添加为联系人",
                                            startTime,
                                            listOf(),
                                            listOf(friend.phone)
                                        )
                                        return false
                                    }
                                }
                            } else {
                                LogUtils.e("修改用户信息失败: ${friend.phone}")
                                uploadCommandResult(
                                    message,
                                    ExecCallbackBean.ERROR_BUTTON,
                                    "修改用户信息失败: ${friend.phone}",
                                    startTime,
                                    listOf(),
                                    listOf(friend.phone)
                                )
                                return false
                            }
                        } else {
                            LogUtils.e("未找到查找手机选项")
                            uploadCommandResult(
                                message,
                                ExecCallbackBean.ERROR_BUTTON,
                                "未找到查找手机选项",
                                startTime,
                                listOf(),
                                listOf(friend.phone)
                            )
                            return false
                        }
                    } else {
                        LogUtils.e("未找到添加客户按钮")
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_BUTTON,
                            "未找到添加客户按钮",
                            startTime,
                            listOf(),
                            listOf(friend.phone)
                        )
                        return false
                    }
                } else {
                    LogUtils.e("未找到添加客户列表")
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.ERROR_BUTTON,
                        "未找到添加客户列表",
                        startTime,
                        listOf(),
                        listOf(friend.phone)
                    )
                    return false
                }
            } else {
                LogUtils.e("未找到搜索按钮")
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_BUTTON,
                    "未找到搜索按钮",
                    startTime,
                    listOf(),
                    listOf(friend.phone)
                )
                return false
            }
        } else {
            LogUtils.e("未找到聊天列表")
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_BUTTON,
                "未找到聊天列表",
                startTime,
                listOf(),
                listOf(friend.phone)
            )
            return false
        }
    }

    /**
     * 从外部群添加好友
     * @see WeworkMessageBean.ADD_FRIEND_BY_GROUP
     * @param groupName 外部群
     * @param friend 待添加用户
     */
    fun addFriendByGroup(
        message: WeworkMessageBean,
        groupName: String,
        friend: WeworkMessageBean.Friend
    ): Boolean {
        val startTime = System.currentTimeMillis()
        if (WeworkRoomUtil.intoRoom(groupName) && WeworkRoomUtil.intoGroupManager()) {
            if (AccessibilityUtil.findTextAndClick(getRoot(), "查看全部群成员")) {
                val title = friend.name
                val list = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
                if (list != null) {
                    val frontNode = AccessibilityUtil.findFrontNode(list)
                    val textViewList =
                        AccessibilityUtil.findAllOnceByClazz(frontNode, Views.TextView)
                            .filter { it.text == null }
                    if (textViewList.size >= 2) {
                        val searchButton: AccessibilityNodeInfo =
                            textViewList[textViewList.size - 1]
                        AccessibilityUtil.performClick(searchButton)
                        val needTrim = title.contains(Constant.regTrimTitle)
                        val trimTitle = title.replace(Constant.regTrimTitle, "")
                        AccessibilityUtil.findTextInput(getRoot(), trimTitle)
                        sleep(Constant.CHANGE_PAGE_INTERVAL)
                        //消息页搜索结果列表
                        val selectListView =
                            AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
                        val reverseRegexTitle = RegexHelper.reverseRegexTitle(trimTitle)
                        val regex1 =
                            (if (Constant.friendRemarkStrict) "^$reverseRegexTitle" else "^(微信昵称:)|((企业)?邮箱:)?$reverseRegexTitle") +
                                    (if (needTrim) ".*?" else Constant.suffixString)
                        val regex2 = ".*?\\($reverseRegexTitle\\)$"
                        val regex = "($regex1)|($regex2)"
                        val matchSelect = AccessibilityUtil.findOneByTextRegex(
                            selectListView,
                            regex,
                            timeout = Constant.CHANGE_PAGE_INTERVAL * 3,
                            root = false
                        )
                        if (selectListView != null && matchSelect != null) {
                            for (i in 0 until selectListView.childCount) {
                                val item = selectListView.getChild(i)
                                val searchResult =
                                    AccessibilityUtil.findOnceByTextRegex(item, regex)
                                //过滤异常好友
                                if (searchResult?.parent != null && searchResult.parent.childCount < 3) {
                                    item.refresh()
                                    val imageView = AccessibilityUtil.findOneByClazz(
                                        item,
                                        Views.ImageView,
                                        root = false
                                    )
                                    AccessibilityUtil.performClick(imageView)
                                    break
                                }
                            }
                            if (modifyFriendInfo(friend)) {
                                if (AccessibilityUtil.findTextAndClick(
                                        getRoot(),
                                        "添加为联系人",
                                        timeout = 2000
                                    )
                                ) {
                                    LogUtils.d("准备发送好友邀请: ${friend.name}")
                                    if (!friend.leavingMsg.isNullOrEmpty()) {
                                        AccessibilityUtil.findTextInput(
                                            getRoot(),
                                            friend.leavingMsg
                                        )
                                    }
                                    if (AccessibilityUtil.findTextAndClick(
                                            getRoot(),
                                            "发送添加邀请",
                                            "发送申请"
                                        )
                                    ) {
                                        LogUtils.d("发送添加邀请成功: ${friend.name}")
                                        uploadCommandResult(
                                            message,
                                            ExecCallbackBean.SUCCESS,
                                            "",
                                            startTime,
                                            listOf(friend.name),
                                            listOf()
                                        )
                                        return true
                                    } else {
                                        if (AccessibilityUtil.findOnceByText(
                                                getRoot(),
                                                "发消息",
                                                exact = true
                                            ) != null
                                        ) {
                                            LogUtils.d("已经添加成功: ${friend.name}")
                                            uploadCommandResult(
                                                message,
                                                ExecCallbackBean.SUCCESS,
                                                "",
                                                startTime,
                                                listOf(friend.name),
                                                listOf()
                                            )
                                            return true
                                        }
                                        LogUtils.e("未找到发送邀请按钮")
                                        uploadCommandResult(
                                            message,
                                            ExecCallbackBean.ERROR_BUTTON,
                                            "未找到发送邀请按钮",
                                            startTime,
                                            listOf(),
                                            listOf(friend.name)
                                        )
                                        return false
                                    }
                                } else {
                                    if (AccessibilityUtil.findOnceByText(
                                            getRoot(),
                                            "发消息",
                                            exact = true
                                        ) != null
                                    ) {
                                        LogUtils.e("已经添加联系人，请勿重复添加: ${friend.name}")
                                        uploadCommandResult(
                                            message,
                                            ExecCallbackBean.ERROR_REPEAT,
                                            "已经添加联系人，请勿重复添加 ${friend.name}",
                                            startTime,
                                            listOf(),
                                            listOf(friend.name)
                                        )
                                        return false
                                    } else {
                                        LogUtils.e("未找到添加为联系人")
                                        uploadCommandResult(
                                            message,
                                            ExecCallbackBean.ERROR_BUTTON,
                                            "未找到添加为联系人",
                                            startTime,
                                            listOf(),
                                            listOf(friend.name)
                                        )
                                        return false
                                    }
                                }
                            } else {
                                LogUtils.e("修改用户信息失败: ${friend.name}")
                                uploadCommandResult(
                                    message,
                                    ExecCallbackBean.ERROR_BUTTON,
                                    "修改用户信息失败: ${friend.name}",
                                    startTime,
                                    listOf(),
                                    listOf(friend.name)
                                )
                                return false
                            }
                        } else {
                            LogUtils.e("未搜索到结果: ${friend.name}")
                            uploadCommandResult(
                                message,
                                ExecCallbackBean.ERROR_BUTTON,
                                "未搜索到结果: ${friend.name}",
                                startTime,
                                listOf(),
                                listOf(friend.name)
                            )
                            val noResult = AccessibilityUtil.findOnceByText(
                                getRoot(),
                                "无搜索结果",
                                "暂无搜索结果",
                                exact = true
                            ) != null
                            LogUtils.e("企微: 无搜索结果: $noResult")
                            return false
                        }
                    } else {
                        LogUtils.e("未发现搜索按钮")
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_BUTTON,
                            "未发现搜索按钮",
                            startTime,
                            listOf(),
                            listOf(friend.name)
                        )
                        return false
                    }
                } else {
                    LogUtils.e("未发现通讯录列表")
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.ERROR_BUTTON,
                        "未发现通讯录列表",
                        startTime,
                        listOf(),
                        listOf(friend.name)
                    )
                    return false
                }
            } else {
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_BUTTON,
                    "未找到查看全部群成员按钮 $groupName",
                    startTime,
                    listOf(),
                    listOf(friend.name)
                )
                return false
            }
        } else {
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_INTO_ROOM,
                "进入房间失败 $groupName",
                startTime,
                listOf(),
                listOf(friend.name)
            )
            return false
        }
    }

    /**
     * 给群成员添加备注
     * @see WeworkMessageBean.MODIFY_GROUP_MEMBER_INFO
     * @param groupName 外部群
     * @param friend 待添加用户
     */
    fun modifyGroupMemberInfo(
        message: WeworkMessageBean,
        groupName: String,
        friend: WeworkMessageBean.Friend
    ): Boolean {
        val startTime = System.currentTimeMillis()
        if (WeworkRoomUtil.intoRoom(groupName) && WeworkRoomUtil.intoGroupManager()) {
            if (AccessibilityUtil.findTextAndClick(getRoot(), "查看全部群成员")) {
                val title = friend.name
                val list = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
                if (list != null) {
                    val frontNode = AccessibilityUtil.findFrontNode(list)
                    val textViewList =
                        AccessibilityUtil.findAllOnceByClazz(frontNode, Views.TextView)
                            .filter { it.text == null }
                    if (textViewList.size >= 2) {
                        val searchButton: AccessibilityNodeInfo =
                            textViewList[textViewList.size - 1]
                        AccessibilityUtil.performClick(searchButton)
                        val needTrim = title.contains(Constant.regTrimTitle)
                        val trimTitle = title.replace(Constant.regTrimTitle, "")
                        AccessibilityUtil.findTextInput(getRoot(), trimTitle)
                        sleep(Constant.CHANGE_PAGE_INTERVAL)
                        //消息页搜索结果列表
                        val selectListView =
                            AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
                        val reverseRegexTitle = RegexHelper.reverseRegexTitle(trimTitle)
                        val regex1 =
                            (if (Constant.friendRemarkStrict) "^$reverseRegexTitle" else "^(微信昵称:)|((企业)?邮箱:)?$reverseRegexTitle") +
                                    (if (needTrim) ".*?" else Constant.suffixString)
                        val regex2 = ".*?\\($reverseRegexTitle\\)$"
                        val regex = "($regex1)|($regex2)"
                        val matchSelect = AccessibilityUtil.findOneByTextRegex(
                            selectListView,
                            regex,
                            timeout = Constant.CHANGE_PAGE_INTERVAL * 3,
                            root = false
                        )
                        if (selectListView != null && matchSelect != null) {
                            for (i in 0 until selectListView.childCount) {
                                val item = selectListView.getChild(i)
                                val searchResult =
                                    AccessibilityUtil.findOnceByTextRegex(item, regex)
                                //过滤异常好友
                                if (searchResult?.parent != null && searchResult.parent.childCount < 3) {
                                    item.refresh()
                                    val imageView = AccessibilityUtil.findOneByClazz(
                                        item,
                                        Views.ImageView,
                                        root = false
                                    )
                                    AccessibilityUtil.performClick(imageView)
                                    break
                                }
                            }
                            modifyFriendInfo(friend)
                            return false
                        } else {
                            LogUtils.e("未搜索到结果: ${friend.name}")
                            uploadCommandResult(
                                message,
                                ExecCallbackBean.ERROR_BUTTON,
                                "未搜索到结果: ${friend.name}",
                                startTime,
                                listOf(),
                                listOf(friend.name)
                            )
                            val noResult = AccessibilityUtil.findOnceByText(
                                getRoot(),
                                "无搜索结果",
                                "暂无搜索结果",
                                exact = true
                            ) != null
                            LogUtils.e("企微: 无搜索结果: $noResult")
                            return false
                        }
                    } else {
                        LogUtils.e("未发现搜索按钮")
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_BUTTON,
                            "未发现搜索按钮",
                            startTime,
                            listOf(),
                            listOf(friend.name)
                        )
                        return false
                    }
                } else {
                    LogUtils.e("未发现通讯录列表")
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.ERROR_BUTTON,
                        "未发现通讯录列表",
                        startTime,
                        listOf(),
                        listOf(friend.name)
                    )
                    return false
                }
            } else {
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_BUTTON,
                    "未找到查看全部群成员按钮 $groupName",
                    startTime,
                    listOf(),
                    listOf(friend.name)
                )
                return false
            }
        } else {
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_INTO_ROOM,
                "进入房间失败 $groupName",
                startTime,
                listOf(),
                listOf(friend.name)
            )
            return false
        }
    }

    /**
     * 添加待办
     * @see WeworkMessageBean.ADD_NEED_DEAL
     * @param titleList 内部用户昵称列表
     * @param receivedContent 回复内容
     */
    fun addNeedDeal(
        message: WeworkMessageBean,
        titleList: MutableList<String>,
        receivedContent: String
    ): Boolean {
        val startTime = System.currentTimeMillis()
        goHome()
        if (AccessibilityUtil.findOnceByText(getRoot(), "日程", exact = true) == null) {
            AccessibilityUtil.scrollToTop(WeworkController.weworkService, getRoot())
        }
        val tvDiaryFlag = AccessibilityUtil.findOneByText(getRoot(), "日程", exact = true)
        if (tvDiaryFlag != null && (tvDiaryFlag.parent?.childCount == 2 || tvDiaryFlag.parent?.childCount == 3)) {
            AccessibilityUtil.performClick(tvDiaryFlag)
            val tvNeedDealFlag = AccessibilityUtil.findOneByTextRegex(getRoot(), "^待办( · .*?)?$")
            if (tvNeedDealFlag != null) {
                AccessibilityUtil.performClick(tvNeedDealFlag)
                sleep(Constant.POP_WINDOW_INTERVAL)
                val list = AccessibilityUtil.findOneByClazz(
                    getRoot(),
                    Views.RecyclerView,
                    Views.ViewGroup,
                    minChildCount = 2
                )
                if (list != null) {
                    val frontNode =
                        AccessibilityUtil.findFrontNode(if (list.className == Views.RecyclerView) list.parent else list)
                    val textViewList =
                        AccessibilityUtil.findAllOnceByClazz(frontNode, Views.TextView)
                    if (textViewList.size >= 2) {
                        val addButton: AccessibilityNodeInfo = textViewList[textViewList.size - 1]
                        AccessibilityUtil.performClick(addButton)
                        AccessibilityUtil.findTextInput(getRoot(), receivedContent)
                        AccessibilityUtil.findTextAndClick(getRoot(), "参与人")
                        val relaySelectResult = relaySelectTarget(titleList, needSend = false)
                        if (relaySelectResult.result) {
                            LogUtils.d("添加参与人成功")
                            if (AccessibilityUtil.findTextAndClick(
                                    getRoot(),
                                    "保存并发送到聊天",
                                    "保存并建群发送"
                                )
                            ) {
                                uploadCommandResult(
                                    message,
                                    ExecCallbackBean.SUCCESS,
                                    "",
                                    startTime,
                                    relaySelectResult.successList,
                                    relaySelectResult.failList
                                )
                                goHome()
                                return true
                            } else {
                                LogUtils.e("未找到保存并发送按钮")
                                uploadCommandResult(
                                    message,
                                    ExecCallbackBean.ERROR_BUTTON,
                                    "未找到保存并发送按钮",
                                    startTime,
                                    listOf(),
                                    titleList
                                )
                                goHome()
                                return false
                            }
                        } else {
                            LogUtils.e("添加参与人失败")
                            uploadCommandResult(
                                message,
                                ExecCallbackBean.ERROR_RELAY,
                                "添加参与人失败: $titleList",
                                startTime,
                                listOf(),
                                titleList
                            )
                            return false
                        }
                    } else {
                        LogUtils.e("未找到添加按钮")
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_BUTTON,
                            "未找到添加按钮",
                            startTime,
                            listOf(),
                            titleList
                        )
                        return false
                    }
                } else {
                    LogUtils.e("未找到待办列表")
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.ERROR_BUTTON,
                        "未找到待办列表",
                        startTime,
                        listOf(),
                        titleList
                    )
                    return false
                }
            } else {
                LogUtils.e("未找到待办按钮")
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_BUTTON,
                    "未找到待办按钮",
                    startTime,
                    listOf(),
                    titleList
                )
                return false
            }
        } else {
            LogUtils.e("未找到日程按钮")
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_BUTTON,
                "未找到日程按钮",
                startTime,
                listOf(),
                titleList
            )
            return false
        }
    }

    /**
     * 打卡
     * @see WeworkMessageBean.CLOCK_IN
     */
    fun clockIn(message: WeworkMessageBean): Boolean {
        val startTime = System.currentTimeMillis()
        goHomeTab("工作台")
        val node = AccessibilityUtil.scrollAndFindByText(
            WeworkController.weworkService,
            getRoot(),
            "打卡",
            exact = true
        )
        if (node != null) {
            AccessibilityUtil.performClick(node)
            sleep(Constant.POP_WINDOW_INTERVAL)
            val clockInFlag =
                AccessibilityUtil.findOneByText(getRoot(), "你已在打卡范围内", timeout = 10000)
            if (clockInFlag != null) {
                AccessibilityUtil.findTextAndClick(getRoot(), "上班打卡", "下班打卡")
                val doneFlag =
                    AccessibilityUtil.findOneByText(getRoot(), "上班·正常", "之后可打下班卡", "今日打卡已完成")
                if (doneFlag != null) {
                    LogUtils.d("打卡成功")
                    uploadCommandResult(message, ExecCallbackBean.SUCCESS, "", startTime)
                    return true
                } else {
                    LogUtils.e("未发现完成打卡")
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.ERROR_BUTTON,
                        "未发现完成打卡",
                        startTime
                    )
                    return false
                }
            } else {
                LogUtils.e("未找到上下班打卡")
                uploadCommandResult(message, ExecCallbackBean.ERROR_BUTTON, "未找到上下班打卡", startTime)
                return false
            }
        } else {
            LogUtils.e("未找到在打卡范围")
            uploadCommandResult(message, ExecCallbackBean.ERROR_BUTTON, "未找到在打卡范围", startTime)
            return false
        }
    }

    /**
     * 切换企业
     * @see WeworkMessageBean.SWITCH_CORP
     * @param objectName 企业名称
     */
    fun switchCorp(message: WeworkMessageBean, objectName: String): Boolean {
        val startTime = System.currentTimeMillis()
        Constant.duplicationFilter = false
        if (Constant.myCorp == objectName) {
            LogUtils.d("当前已在目标企业: $objectName")
            uploadCommandResult(
                message,
                ExecCallbackBean.SUCCESS,
                "当前已在目标企业: $objectName",
                startTime,
                listOf(objectName),
                listOf()
            )
            return true
        } else {
            Constant.myCorp = ""
        }
        goHomeTab("消息")
        val firstTv = AccessibilityUtil.findAllByClazz(getRoot(), Views.TextView)
            .firstOrNull { it.text == null }
        AccessibilityUtil.performClick(firstTv, retry = false)
        sleep(Constant.CHANGE_PAGE_INTERVAL)
        val listviewList = AccessibilityUtil.findAllOnceByClazz(
            getRoot(),
            Views.RecyclerView,
            Views.ListView,
            Views.ViewGroup
        )
            .filter { it.childCount >= 2 }
        val listview = listviewList.firstOrNull()
        if (listview != null) {
            val tvCorp = AccessibilityUtil.scrollAndFindByText(
                WeworkController.weworkService,
                listview,
                objectName,
                exact = true
            )
            if (tvCorp != null) {
                LogUtils.d("找到目标企业: $objectName")
                AccessibilityUtil.performClick(tvCorp)
                uploadCommandResult(
                    message,
                    ExecCallbackBean.SUCCESS,
                    "切换企业成功: $objectName",
                    startTime,
                    listOf(objectName),
                    listOf()
                )
                Constant.weworkCorpName = objectName
                IWWAPIUtil.init(Utils.getApp())
                goHome()
                sleep(Constant.LONG_INTERVAL)
                WeworkGetImpl.getMyInfo(message)
                if (Constant.myCorp != objectName) {
                    Constant.myCorp = ""
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.ERROR_TARGET,
                        "切换企业校验失败: $objectName",
                        startTime,
                        listOf(),
                        listOf(objectName)
                    )
                } else {
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.SUCCESS,
                        "切换企业校验成功: $objectName",
                        startTime,
                        listOf(objectName),
                        listOf()
                    )
                }
                return true
            } else {
                LogUtils.e("未找到目标企业: $objectName")
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_TARGET,
                    "未找到目标企业: $objectName",
                    startTime,
                    listOf(),
                    listOf(objectName)
                )
                goHome()
                return false
            }
        } else {
            LogUtils.e("未找到企业列表: $objectName")
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_BUTTON,
                "未找到企业列表: $objectName",
                startTime,
                listOf(),
                listOf(objectName)
            )
            return false
        }
    }

    /**
     * 扫一扫
     * @see WeworkMessageBean.SCAN_QR_CODE
     * @param fileUrl 图片地址
     * @param fileBase64 文件Base64
     */
    fun scanQrCode(message: WeworkMessageBean, fileUrl: String?, fileBase64: String?): Boolean {
        val startTime = System.currentTimeMillis()
        goHome()
        var filePath = ""
        if (fileUrl != null) {
            LogUtils.i("下载开始 $fileUrl")
            val execute = OkGo.get<File>(fileUrl).execute()
            LogUtils.i("下载完成 $fileUrl")
            val body = execute.body()
            if (body != null) {
                val df = SimpleDateFormat("yyyy-MM-dd-HH:mm:ss")
                filePath =
                    "${Utils.getApp().getExternalFilesDir("scan")}/${df.format(Date())}_scan.jpg"
                ImageUtils.save(
                    ImageUtils.getBitmap(body.byteStream()),
                    filePath,
                    Bitmap.CompressFormat.JPEG,
                    100,
                    true
                )
                PropUtil.setProp(PropUtil.propVideo, filePath)
                LogUtils.i("文件存储本地成功 $filePath")
            } else {
                LogUtils.e("文件下载失败")
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_FILE_DOWNLOAD,
                    "文件下载失败 $fileUrl",
                    startTime
                )
                return false
            }
        } else {
            //todo base64
        }
        val list = AccessibilityUtil.findOneByClazz(
            getRoot(),
            Views.RecyclerView,
            Views.ListView,
            Views.ViewGroup
        )
        if (list != null) {
            val frontNode = AccessibilityUtil.findFrontNode(list)
            val textViewList = AccessibilityUtil.findAllOnceByClazz(frontNode, Views.TextView)
            if (textViewList.size >= 2) {
                val searchButton: AccessibilityNodeInfo = textViewList[textViewList.size - 2]
                val multiButton: AccessibilityNodeInfo = textViewList[textViewList.size - 1]
                AccessibilityUtil.performClick(multiButton)
                sleep(Constant.POP_WINDOW_INTERVAL)
                val list = AccessibilityUtil.findAllByClazz(getRoot(), Views.ListView).lastOrNull()
                if (list != null) {
                    if (AccessibilityUtil.findTextAndClick(list, "扫一扫", exact = true)) {
                        AccessibilityExtraUtil.loadingPage("LoginScannerActivity")
                        if (AccessibilityExtraUtil.loadingPage("LoginPcActivity")) {
                            if (AccessibilityUtil.findTextAndClick(
                                    getRoot(),
                                    "登录",
                                    exact = true,
                                    timeout = Constant.LONG_INTERVAL * 2
                                )
                            ) {
                                LogUtils.i("点击登录")
                                uploadCommandResult(
                                    message,
                                    ExecCallbackBean.SUCCESS,
                                    "点击登录",
                                    startTime
                                )
                                sleep(Constant.CHANGE_PAGE_INTERVAL * 3)
                                if (AccessibilityExtraUtil.loadingPage(
                                        "WwMainActivity",
                                        "JsWebActivity",
                                        timeout = 0
                                    )
                                ) {
                                    AccessibilityUtil.findTextAndClick(
                                        getRoot(),
                                        "继续登录",
                                        exact = true
                                    )
                                    sleep(Constant.CHANGE_PAGE_INTERVAL * 3)
                                }
                                return true
                            } else {
                                LogUtils.e("未找到登录按钮")
                                uploadCommandResult(
                                    message,
                                    ExecCallbackBean.ERROR_BUTTON,
                                    "未找到登录按钮",
                                    startTime
                                )
                                return false
                            }
                        } else {
                            LogUtils.e("未找到确认登录页")
                            uploadCommandResult(
                                message,
                                ExecCallbackBean.ERROR_BUTTON,
                                "未找到确认登录页",
                                startTime
                            )
                            return false
                        }
                    } else {
                        LogUtils.e("未找到扫一扫按钮")
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_BUTTON,
                            "未找到扫一扫按钮",
                            startTime
                        )
                        return false
                    }
                } else {
                    LogUtils.e("未找到扫一扫列表")
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.ERROR_BUTTON,
                        "未找到扫一扫列表",
                        startTime
                    )
                    return false
                }
            } else {
                LogUtils.e("未找到搜索按钮")
                uploadCommandResult(message, ExecCallbackBean.ERROR_BUTTON, "未找到搜索按钮", startTime)
                return false
            }
        } else {
            LogUtils.e("未找到聊天列表")
            uploadCommandResult(message, ExecCallbackBean.ERROR_BUTTON, "未找到聊天列表", startTime)
            return false
        }
    }

    /**
     * 删除联系人
     * @see WeworkMessageBean.DELETE_CONTACT
     * @param friend 待删除用户
     */
    fun deleteContact(message: WeworkMessageBean, friend: WeworkMessageBean.Friend): Boolean {
        val startTime = System.currentTimeMillis()
        if (friend.phone == null && friend.name != null) {
            if (getFriendInfo(friend.name) && AccessibilityExtraUtil.loadingPage("ContactDetailBaseContentActivity")) {
                val imageView = AccessibilityUtil.findOneByClazz(getRoot(), Views.ImageView)
                val frontNode = AccessibilityUtil.findFrontNode(imageView?.parent)
                val textViewList = AccessibilityUtil.findAllOnceByClazz(frontNode, Views.TextView)
                if (textViewList.size >= 2) {
                    val multiButton: AccessibilityNodeInfo = textViewList[textViewList.size - 1]
                    AccessibilityUtil.performClick(multiButton)
                    if (AccessibilityExtraUtil.loadingPage("ContactDetailSettingActivity")) {
                        val tvDelete = AccessibilityUtil.scrollAndFindByText(
                            WeworkController.weworkService,
                            getRoot(),
                            "删除",
                            exact = true
                        )
                        if (tvDelete != null) {
                            AccessibilityUtil.performClick(tvDelete)
                            if (AccessibilityUtil.findTextAndClick(
                                    getRoot(),
                                    "确认删除",
                                    exact = true
                                )
                            ) {
                                LogUtils.d("删除联系人成功: ${friend.name}")
                                uploadCommandResult(
                                    message,
                                    ExecCallbackBean.SUCCESS,
                                    "",
                                    startTime,
                                    listOf(friend.name),
                                    listOf()
                                )
                                return true
                            } else {
                                LogUtils.e("未找到确认删除按钮: ${friend.name}")
                                uploadCommandResult(
                                    message,
                                    ExecCallbackBean.ERROR_BUTTON,
                                    "未找到确认删除按钮: ${friend.name}",
                                    startTime,
                                    listOf(),
                                    listOf(friend.name)
                                )
                                return false
                            }
                        } else {
                            LogUtils.e("未找到删除按钮: ${friend.name}")
                            uploadCommandResult(
                                message,
                                ExecCallbackBean.ERROR_BUTTON,
                                "未找到删除按钮: ${friend.name}",
                                startTime,
                                listOf(),
                                listOf(friend.name)
                            )
                            return false
                        }
                    } else {
                        LogUtils.e("进入个人信息详情页失败: ${friend.name}")
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_BUTTON,
                            "进入个人信息详情页失败: ${friend.name}",
                            startTime,
                            listOf(),
                            listOf(friend.name)
                        )
                        return false
                    }
                } else {
                    LogUtils.e("未找到更多按钮: ${friend.name}")
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.ERROR_BUTTON,
                        "未找到更多按钮: ${friend.name}",
                        startTime,
                        listOf(),
                        listOf(friend.name)
                    )
                    return false
                }
            } else {
                LogUtils.e("未找到用户: ${friend.name}")
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_TARGET,
                    "未找到用户: ${friend.name}",
                    startTime,
                    listOf(),
                    listOf(friend.name)
                )
                return false
            }
        } else {
            LogUtils.e("数据异常: ${friend.name}")
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_ILLEGAL_DATA,
                "数据异常: ${friend.name}",
                startTime,
                listOf(),
                listOf(friend.name)
            )
            return false
        }
    }

    /**
     * 展示群信息
     * @see WeworkMessageBean.SHOW_GROUP_INFO
     * @param titleList 待查询群名
     * @param receivedName 原始消息的发送者姓名
     * @param originalContent 原始消息的内容
     * @param textType 原始消息的消息类型
     */
    fun showGroupInfo(
        message: WeworkMessageBean,
        titleList: MutableList<String>,
        receivedName: String,
        originalContent: String,
        textType: Int
    ): Boolean {
        val startTime = System.currentTimeMillis()
        for (groupName in LinkedHashSet(titleList)) {
            if (WeworkRoomUtil.intoRoom(groupName) && WeworkRoomUtil.intoGroupManager()) {
                val groupInfo = WeworkGetImpl.getGroupInfoDetail()
                groupInfo.titleList = arrayListOf(groupName)
                groupInfo.type = WeworkMessageBean.SHOW_GROUP_INFO
                groupInfo.receivedName = receivedName
                groupInfo.originalContent = originalContent
                groupInfo.textType = textType
                WeworkController.weworkService.webSocketManager.send(groupInfo)
                uploadCommandResult(message, ExecCallbackBean.SUCCESS, "", startTime)
                return true
            }
        }
        uploadCommandResult(message, ExecCallbackBean.ERROR_TARGET, "", startTime)
        return false
    }

    /**
     * 转发消息到目标列表
     * 支持场景：长按消息转发、微盘图片转发
     * selectList 昵称或群名列表
     * extraText 转发是否附加一条文本
     */
    private fun relaySelectTarget(
        selectList: List<String>,
        extraText: String? = null,
        needSend: Boolean = true,
        timeout: Long = 5000
    ): SelectResult {
        val selectResult = SelectResult()
        if (SPUtils.getInstance().getInt("num") == 2) {
            sleep(Constant.POP_WINDOW_INTERVAL)
            val aList = AccessibilityUtil.findAllByText(
                WeworkController.weworkService.rootInActiveWindow,
                "企业微信"
            )
            if (aList.size == 2) {
                if (1 == SPUtils.getInstance().getInt("weCom")) {
                    AccessibilityUtil.performClick(aList.firstOrNull())
                } else {
                    AccessibilityUtil.performClick(aList.lastOrNull())
                }
            }
            sleep(Constant.POP_WINDOW_INTERVAL)
        }
        if (AccessibilityUtil.findOneByText(
                getRoot(),
                "选择联系人",
                "选择参与人",
                exact = true,
                timeout = timeout
            ) == null
        ) {
            LogUtils.e("未找到选择联系人/选择参与人")
            error("未找到选择联系人/选择参与人")
            return selectResult
        }
        //聊天消息列表 1ListView 0RecycleView xViewGroup
        val list = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
        if (list != null) {
            val frontNode = AccessibilityUtil.findFrontNode(list, 2)
            val textViewList = AccessibilityUtil.findAllOnceByClazz(frontNode, Views.TextView)
            if (textViewList.size >= 2) {
                val searchButton: AccessibilityNodeInfo = textViewList[textViewList.size - 2]
                val multiButton: AccessibilityNodeInfo = textViewList[textViewList.size - 1]
                AccessibilityUtil.performClick(multiButton)
                AccessibilityUtil.performClick(searchButton)
                var isSelect = false
                for (select in LinkedHashSet(selectList)) {
                    val needTrim = select.contains(Constant.regTrimTitle)
                    val trimTitle = select.replace(Constant.regTrimTitle, "")
                    AccessibilityUtil.findTextInput(getRoot(), trimTitle)
                    sleep(Constant.CHANGE_PAGE_INTERVAL)
                    val selectListView = AccessibilityUtil.findOneByClazz(
                        getRoot(),
                        Views.ListView,
                        Views.RecyclerView,
                        Views.ViewGroup,
                        minChildCount = 2
                    )
                    val reverseRegexTitle = RegexHelper.reverseRegexTitle(trimTitle)
                    val regex1 =
                        (if (Constant.friendRemarkStrict) "^$reverseRegexTitle" else "^(微信昵称:)|((企业)?邮箱:)?$reverseRegexTitle") +
                                (if (needTrim) ".*?" else Constant.suffixString)
                    val regex2 = ".*?\\($reverseRegexTitle\\)$"
                    val regex = "($regex1)|($regex2)"
                    val matchSelect = AccessibilityUtil.findOneByTextRegex(
                        selectListView,
                        regex,
                        timeout = Constant.CHANGE_PAGE_INTERVAL * 3,
                        root = false
                    )
                    if (selectListView != null && matchSelect != null) {
                        for (i in 0 until selectListView.childCount) {
                            val item = selectListView.getChild(i)
                            val searchResult = AccessibilityUtil.findOnceByTextRegex(item, regex)
                            //过滤已退出的群聊
                            if (searchResult?.parent != null && searchResult.parent.childCount < 3) {
                                item.refresh()
                                val imageView = AccessibilityUtil.findOneByClazz(
                                    item,
                                    Views.ImageView,
                                    root = false
                                )
                                AccessibilityUtil.performClick(imageView)
                                isSelect = true
                                break
                            }
                        }
                    }
                    if (matchSelect != null) {
                        selectResult.successList.add(select)
                        LogUtils.d("找到搜索结果: $select")
                    } else {
                        selectResult.failList.add(select)
                        LogUtils.e("未搜索到结果: $select")
                        error("未搜索到结果: $select")
                        val noResult = AccessibilityUtil.findOnceByText(
                            getRoot(),
                            "无搜索结果",
                            "暂无搜索结果",
                            exact = true
                        ) != null
                        LogUtils.e("企微: 无搜索结果: $noResult")
                    }
                    sleep(Constant.POP_WINDOW_INTERVAL)
                }
                if (!isSelect) {
                    LogUtils.e("未选择接收者")
                    error("未选择接收者")
                    return selectResult
                }
                val confirmButton =
                    AccessibilityUtil.findOneByTextRegex(getRoot(), "^确定(\\(\\d+\\))?\$")
                if (confirmButton != null) {
                    AccessibilityUtil.performClick(confirmButton)
                    sleep(Constant.POP_WINDOW_INTERVAL)
                    if (!needSend) {
                        selectResult.result = true
                        return selectResult
                    }
                    if (!extraText.isNullOrBlank()) {
                        LogUtils.d("extraText: $extraText")
                        AccessibilityUtil.findTextInput(getRoot(), extraText)
                    }
                    val sendButton =
                        AccessibilityUtil.findOneByTextRegex(getRoot(), "^发送(\\(\\d+\\))?\$")
                    if (sendButton != null) {
                        AccessibilityUtil.performClick(sendButton)
                        selectResult.result = true
                        return selectResult
                    }
                    LogUtils.e("未发现发送按钮")
                    error("未发现发送按钮")
                    return selectResult
                } else {
                    LogUtils.e("未发现确认按钮")
                    error("未发现确认按钮")
                    return selectResult
                }
            } else {
                LogUtils.e("未发现搜索和多选按钮")
                error("未发现搜索和多选按钮")
                return selectResult
            }
        }
        LogUtils.e("未知错误")
        error("未知错误")
        return selectResult
    }

    /**
     * 创建一个外部群
     */
    private fun createGroup(): Boolean {
        goHomeTab("工作台")
        val node = AccessibilityUtil.scrollAndFindByText(
            WeworkController.weworkService,
            getRoot(),
            "客户群",
            "居民群",
            "学员群",
            exact = true
        )
        if (node != null) {
            AccessibilityUtil.performClick(node)
            sleep(Constant.POP_WINDOW_INTERVAL)
            LogUtils.d("进入客户群应用")
            val textView =
                AccessibilityUtil.findOneByText(getRoot(), "创建一个客户群", "创建一个居民群", "创建一个学员群")
            return AccessibilityUtil.performClick(textView)
        }
        LogUtils.e("未找到客户群应用")
        error("未找到客户群应用")
        return false
    }

    /**
     * 建群前检查是否达到当日建群上限
     * @return true允许建群 false不允许建群
     */
    private fun beforeCreateGroupCheck(): Boolean {
        //有建群权限且最近300秒内发现限制建群
        if (SPUtils.getInstance("limit").getBoolean("canCreateGroup", false)) {
            val interval = System.currentTimeMillis() / 1000 - SPUtils.getInstance("limit")
                .getLong("createGroupLimit", 0)
            if (interval < 300) {
                LogUtils.e("发现达到当日建群上限 请等待${300 - interval}秒后再试!")
                return false
            }
        }
        return true
    }

    /**
     * 建群后检查是否达到当日建群上限
     * @return true达到上限 false为达到上限
     */
    private fun createGroupLimit(): Boolean {
        val hasLimit =
            AccessibilityUtil.findOneByText(getRoot(), "新建群聊功能暂时被限制", "未验证企业", timeout = 2000)
        if (hasLimit == null) {
            SPUtils.getInstance("limit").put("canCreateGroup", true)
        } else if (SPUtils.getInstance("limit").getBoolean("canCreateGroup", false)) {
            SPUtils.getInstance("limit").put("createGroupLimit", System.currentTimeMillis() / 1000)
            LogUtils.e("发现达到当日建群上限")
        }
        return hasLimit != null
    }

    /**
     * 建群后检查是否被限制建群功能
     * @return true达到上限 falseE为达到上限
     */
    private fun createGroupError(): Boolean {
        val hasLimit =
            AccessibilityUtil.findOneByText(getRoot(), "账号异常", "新建客户群功能已被限制使用", timeout = 2000)
        return hasLimit != null
    }

    /**
     * 修改群名称
     */
    private fun groupRename(groupName: String?): Boolean {
        if (groupName == null) return true
        if (WeworkRoomUtil.intoGroupManager()) {
            val textView = AccessibilityUtil.findOneByText(getRoot(), "全部群成员", "微信用户创建")
                ?: return false
            if (textView.text?.toString()?.contains("微信用户创建") == true) {
                var button = AccessibilityUtil.findFrontNode(textView)
                if (button?.className == Views.ImageView) {
                    button = AccessibilityUtil.findFrontNode(button)
                }
                if (button != null) {
                    AccessibilityUtil.performClick(button)
                    AccessibilityUtil.findTextInput(getRoot(), groupName)
                    val confirmButton = AccessibilityUtil.findOneByText(getRoot(), "确定")
                    AccessibilityUtil.performClick(confirmButton)
                    sleep(Constant.CHANGE_PAGE_INTERVAL * 2)
                    return true
                } else {
                    LogUtils.e("未找到填写群名按钮")
                    error("未找到填写群名按钮")
                    return false
                }
            } else {
                val result = AccessibilityUtil.findTextAndClick(getRoot(), "群聊名称")
                if (result) {
                    AccessibilityUtil.findTextInput(getRoot(), groupName)
                    val confirmButton = AccessibilityUtil.findOneByText(getRoot(), "确定")
                    AccessibilityUtil.performClick(confirmButton)
                    sleep(Constant.CHANGE_PAGE_INTERVAL * 2)
                    return true
                } else {
                    LogUtils.e("未找到群聊名称按钮")
                    error("未找到群聊名称按钮")
                }
            }
        }
        return false
    }

    /**
     * 添加群成员/拉人
     * 默认不附带历史记录
     */
    private fun groupAddMember(
        selectList: List<String>?,
        showMessageHistory: Boolean = false
    ): SelectResult {
        val selectResult = SelectResult()
        if (selectList.isNullOrEmpty()) {
            selectResult.result = true
            return selectResult
        }
        if (WeworkRoomUtil.intoGroupManager()) {
            AccessibilityUtil.findOneByText(
                getRoot(),
                "全部群成员",
                "微信用户创建",
                timeout = Constant.CHANGE_PAGE_INTERVAL
            )
                ?: return selectResult
            val gridView = AccessibilityUtil.findOnceByClazz(getRoot(), Views.GridView)
            if (gridView != null && gridView.childCount >= 2) {
                val tvEmptySize = AccessibilityUtil.findAllOnceByClazz(gridView, Views.TextView)
                    .filter { it.text == null }.size
                LogUtils.v("tvEmptySize: $tvEmptySize")
                if (tvEmptySize == 0) {
                    selectResult.result = true
                    return selectResult
                } else if (tvEmptySize == 1 || tvEmptySize == 2) {
                    LogUtils.d("点击拉人按钮")
                    AccessibilityUtil.performClick(gridView.getChild(gridView.childCount - tvEmptySize))
                }
            } else {
                val recyclerViewList =
                    AccessibilityUtil.findAllOnceByClazz(getRoot(), Views.RecyclerView)
                if (recyclerViewList.size >= 2 && recyclerViewList[1].childCount >= 2) {
                    val rvList = recyclerViewList[1]
                    var ivEmptySize = 0
                    for (i in 0 until rvList.childCount) {
                        if (rvList.getChild(i).childCount == 1) {
                            ivEmptySize++
                        }
                    }
                    if (ivEmptySize == 0) {
                        selectResult.result = true
                        return selectResult
                    } else if (ivEmptySize == 1 || ivEmptySize == 2) {
                        LogUtils.d("点击拉人按钮")
                        AccessibilityUtil.performClick(rvList.getChild(rvList.childCount - ivEmptySize))
                    }
                } else {
                    LogUtils.e("未找到添加成员按钮")
                    error("未找到添加成员按钮")
                    return selectResult
                }
            }
            //群详情列表
            val list = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
            if (list != null) {
                val frontNode = AccessibilityUtil.findFrontNode(list, 2)
                val textViewList = AccessibilityUtil.findAllOnceByClazz(frontNode, Views.TextView)
                if (textViewList.size >= 2) {
                    val multiButton = textViewList.lastOrNull()
                    var count = 0
                    for (select in LinkedHashSet(selectList)) {
                        val needTrim = select.contains(Constant.regTrimTitle)
                        val trimTitle = select.replace(Constant.regTrimTitle, "")
                        AccessibilityUtil.performClick(multiButton)
                        AccessibilityUtil.findTextInput(getRoot(), trimTitle)
                        sleep(Constant.POP_WINDOW_INTERVAL)
                        val selectListView = AccessibilityUtil.findOneByClazz(
                            getRoot(),
                            Views.ListView,
                            Views.RecyclerView,
                            Views.ViewGroup,
                            minChildCount = 2,
                            firstChildClazz = Views.TextView
                        )
                        sleep(Constant.POP_WINDOW_INTERVAL)
                        val reverseRegexTitle = RegexHelper.reverseRegexTitle(trimTitle)
                        val regex1 =
                            (if (Constant.friendRemarkStrict) "^$reverseRegexTitle" else "^(微信昵称:)|((企业)?邮箱:)?$reverseRegexTitle") +
                                    (if (needTrim) ".*?" else Constant.suffixString)
                        val regex2 = ".*?\\($reverseRegexTitle\\)$"
                        val regex = "($regex1)|($regex2)"
                        val matchSelect = AccessibilityUtil.findOneByTextRegex(
                            selectListView,
                            regex,
                            timeout = Constant.CHANGE_PAGE_INTERVAL * 3,
                            root = false
                        )
                        if (selectListView != null && (matchSelect != null || reverseRegexTitle.matches(
                                Constant.regMail
                            ))
                        ) {
                            var flag = false
                            for (i in 0 until selectListView.childCount) {
                                val item = selectListView.getChild(i)
                                if ((matchSelect == null && item.className == Views.RelativeLayout)
                                    || AccessibilityUtil.findOnceByTextRegex(item, regex) != null
                                ) {
                                    item.refresh()
                                    val imageView = AccessibilityUtil.findOneByClazz(
                                        item,
                                        Views.ImageView,
                                        root = false
                                    )
                                    if (imageView != null && !imageView.isEnabled) {
                                        flag = true
                                    } else if (AccessibilityUtil.performClick(imageView)) {
                                        flag = true
                                        count += 1
                                    }
                                    if (select.contains(" ")) {
                                        break
                                    }
                                }
                            }
                            if (!flag) {
                                LogUtils.e("拉人失败 找不到: $select")
                                error("拉人失败 找不到: $select")
                            }
                        }
                        val noResult = AccessibilityUtil.findOnceByText(
                            getRoot(),
                            "无搜索结果",
                            "暂无搜索结果",
                            exact = true
                        ) != null
                        val textView = AccessibilityUtil.findOnceByClazz(getRoot(), Views.TextView)
                        if (textView != null && textView.text.isNullOrBlank()) {
                            AccessibilityUtil.performClick(textView)
                            sleep(Constant.POP_WINDOW_INTERVAL)
                        }
                        if (matchSelect != null) {
                            selectResult.successList.add(select)
                            LogUtils.d("找到搜索结果: $select")
                        } else {
                            selectResult.failList.add(select)
                            LogUtils.e("未搜索到结果: $select")
                            error("未搜索到结果: $select")
                            LogUtils.e("企微: 无搜索结果: $noResult")
                            if (Constant.groupStrict) return selectResult
                        }
                    }
                    if (count == 0) {
                        while (AccessibilityUtil.findOnceByText(
                                getRoot(),
                                "全部群成员",
                                "微信用户创建"
                            ) == null && !isAtHome()
                        ) {
                            backPress()
                        }
                        LogUtils.d("拉入0人")
                        selectResult.result = true
                        return selectResult
                    }
                    sleep(Constant.CHANGE_PAGE_INTERVAL)
                    if (showMessageHistory) {
                        AccessibilityUtil.findTextAndClick(getRoot(), "聊天记录")
                    }
                    val confirmButton =
                        AccessibilityUtil.findOneByTextRegex(getRoot(), "^确定(\\(\\d+\\))?\$")
                    if (confirmButton != null) {
                        AccessibilityUtil.performClick(confirmButton)
                        if (AccessibilityExtraUtil.loadingPage(
                                "CustomDialog",
                                timeout = Constant.POP_WINDOW_INTERVAL
                            )
                        ) {
                            AccessibilityUtil.findTextAndClick(getRoot(), "邀请", exact = true)
                            log("群邀请: ${selectList.joinToString()}")
                        }
                        selectResult.result = true
                        return selectResult
                    } else {
                        LogUtils.e("未发现确认按钮")
                        error("未发现确认按钮")
                        return selectResult
                    }
                } else {
                    LogUtils.e("未找到搜索按钮")
                    error("未找到搜索按钮")
                    return selectResult
                }
            } else {
                LogUtils.e("未找到成员列表")
                error("未找到成员列表")
                return selectResult
            }
        } else {
            LogUtils.e("进入群详情失败")
            error("进入群详情失败")
            return selectResult
        }
    }

    /**
     * 移除群成员/踢人
     */
    private fun groupRemoveMember(removeList: List<String>?): SelectResult {
        val selectResult = SelectResult()
        if (removeList.isNullOrEmpty()) {
            selectResult.result = true
            return selectResult
        }
        if (WeworkRoomUtil.intoGroupManager()) {
            AccessibilityUtil.findOneByText(
                getRoot(),
                "全部群成员",
                "微信用户创建",
                timeout = Constant.CHANGE_PAGE_INTERVAL
            )
                ?: return selectResult
            var ivEmptySize = 0
            val gridView = AccessibilityUtil.findOnceByClazz(getRoot(), Views.GridView)
            if (gridView != null && gridView.childCount >= 2) {
                val tvEmptySize = AccessibilityUtil.findAllOnceByClazz(gridView, Views.TextView)
                    .filter { it.text == null }.size
                LogUtils.v("tvEmptySize: $tvEmptySize")
                if (tvEmptySize <= 1) {
                    LogUtils.e("未找到踢人按钮")
                    error("未找到踢人按钮")
                    selectResult.result = true
                    return selectResult
                } else if (tvEmptySize == 2) {
                    LogUtils.d("点击踢人按钮")
                    AccessibilityUtil.performClick(gridView.getChild(gridView.childCount - 1))
                }
            } else {
                val recyclerViewList =
                    AccessibilityUtil.findAllOnceByClazz(getRoot(), Views.RecyclerView)
                if (recyclerViewList.size >= 2 && recyclerViewList[1].childCount >= 2) {
                    val rvList = recyclerViewList[1]
                    for (i in 0 until rvList.childCount) {
                        if (rvList.getChild(i).childCount == 1) {
                            ivEmptySize++
                        }
                    }
                    if (ivEmptySize <= 1) {
                        LogUtils.e("未找到踢人按钮")
                        error("未找到踢人按钮")
                        selectResult.result = true
                        return selectResult
                    } else if (ivEmptySize == 2) {
                        LogUtils.d("点击踢人按钮")
                        AccessibilityUtil.performClick(rvList.getChild(rvList.childCount - 1))
                    }
                } else {
                    LogUtils.e("未找到删除成员按钮")
                    error("未找到删除成员按钮")
                    return selectResult
                }
            }
            //群详情列表
            val list = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
            if (list != null) {
                val frontNode = AccessibilityUtil.findFrontNode(list, 2)
                val textViewList = AccessibilityUtil.findAllOnceByClazz(frontNode, Views.TextView)
                if (textViewList.size >= 2) {
                    val multiButton =
                        if (ivEmptySize == 0) textViewList.lastOrNull() else textViewList[textViewList.size - 2]
                    var count = 0
                    for (select in LinkedHashSet(removeList)) {
                        val needTrim = select.contains(Constant.regTrimTitle)
                        val trimTitle = select.replace(Constant.regTrimTitle, "")
                        AccessibilityUtil.performClick(multiButton)
                        AccessibilityUtil.findTextInput(getRoot(), trimTitle)
                        sleep(Constant.POP_WINDOW_INTERVAL)
                        val selectListView = AccessibilityUtil.findOneByClazz(
                            getRoot(),
                            Views.ListView,
                            Views.RecyclerView,
                            Views.ViewGroup,
                            minChildCount = 2,
                            firstChildClazz = Views.RelativeLayout
                        )
                        val reverseRegexTitle = RegexHelper.reverseRegexTitle(trimTitle)
                        val regex1 =
                            (if (Constant.friendRemarkStrict) "^$reverseRegexTitle" else "^(微信昵称:)|((企业)?邮箱:)?$reverseRegexTitle") +
                                    (if (needTrim) ".*?" else Constant.suffixString)
                        val regex2 = ".*?\\($reverseRegexTitle\\)$"
                        val regex = "($regex1)|($regex2)"
                        val matchSelect = AccessibilityUtil.findOneByTextRegex(
                            selectListView,
                            regex,
                            timeout = Constant.CHANGE_PAGE_INTERVAL * 3,
                            root = false
                        )
                        sleep(Constant.POP_WINDOW_INTERVAL)
                        if (selectListView != null && matchSelect != null) {
                            for (i in 0 until selectListView.childCount) {
                                val item = selectListView.getChild(i)
                                val searchResult =
                                    AccessibilityUtil.findOnceByTextRegex(item, regex)
                                if (searchResult != null) {
                                    item.refresh()
                                    val imageView = AccessibilityUtil.findOneByClazz(
                                        item,
                                        Views.ImageView,
                                        root = false
                                    )
                                    if (imageView != null && imageView.isSelected) {

                                    } else if (AccessibilityUtil.performClick(imageView)) {
                                        count += 1
                                    }
                                    sleep(Constant.POP_WINDOW_INTERVAL)
//                                    if (AccessibilityUtil.performClick(imageView)) {
//                                        count += 1
//                                    }
                                }
                            }
                        }
                        val noResult = AccessibilityUtil.findOnceByText(
                            getRoot(),
                            "无搜索结果",
                            "暂无搜索结果",
                            exact = true
                        ) != null
                        val textView = AccessibilityUtil.findOnceByClazz(getRoot(), Views.TextView)
                        if (textView != null && textView.text.isNullOrBlank()) {
                            AccessibilityUtil.performClick(textView)
                            sleep(Constant.POP_WINDOW_INTERVAL)
                        }
                        if (matchSelect != null) {
                            selectResult.successList.add(select)
                            LogUtils.d("找到搜索结果: $select")
                        } else {
                            selectResult.failList.add(select)
                            LogUtils.e("未搜索到结果: $select")
                            error("未搜索到结果: $select")
                            LogUtils.e("企微: 无搜索结果: $noResult")
                            //待踢人已经不在群里的不算失败
                            if (Constant.groupStrict) return selectResult
                        }
                    }
                    if (count == 0) {
                        var retry = 3
                        while (retry-- > 0 && WeworkController.weworkService.currentClass == "com.tencent.wework.choosecontact.controller.CommonChooseListActivity") {
                            backPress()
                        }
                        LogUtils.d("移出0人")
                        selectResult.result = true
                        return selectResult
                    }
                    sleep(Constant.CHANGE_PAGE_INTERVAL)
                    val confirmButton =
                        AccessibilityUtil.findOneByText(getRoot(), "移出(")
                    if (confirmButton != null) {
                        AccessibilityUtil.performClick(confirmButton)
                        selectResult.result = true
                        return selectResult
                    } else {
                        LogUtils.e("未发现移出按钮")
                        error("未发现移出按钮")
                        return selectResult
                    }
                } else {
                    LogUtils.e("未找到搜索按钮")
                    error("未找到搜索按钮")
                    return selectResult
                }
            } else {
                LogUtils.e("未找到成员列表")
                error("未找到成员列表")
                return selectResult
            }
        } else {
            LogUtils.e("进入群详情失败")
            error("进入群详情失败")
            return selectResult
        }
    }

    /**
     * 修改群公告
     * 注：首次为发布 后续为编辑
     * 注2：外部群为edittext 内部群为webview(只能追加文本)
     */
    private fun groupChangeAnnouncement(groupAnnouncement: String?): Boolean {
        if (groupAnnouncement == null) return true
        if (WeworkRoomUtil.intoGroupManager()) {
            val textView = AccessibilityUtil.findOneByText(getRoot(), "群公告", exact = true)
            if (textView != null) {
                AccessibilityUtil.performClick(textView)
                val editButton =
                    AccessibilityUtil.findOneByText(getRoot(), "编辑", timeout = 2000, exact = true)
                if (editButton != null) {
                    LogUtils.d("群公告编辑中: $groupAnnouncement")
                    var retry = 0
                    while (retry++ < 10) {
                        AccessibilityUtil.performClick(editButton)
                        sleep(Constant.POP_WINDOW_INTERVAL)
                        if (AccessibilityUtil.findOnceByText(getRoot(), "编辑", exact = true) == null)
                            break
                    }
                }
                if (AccessibilityUtil.findTextInput(getRoot(), groupAnnouncement)) {
                    LogUtils.d("群公告发布中: $groupAnnouncement")
                    if (AccessibilityUtil.findTextAndClick(getRoot(), "发布")) {
                        val publishButtonList = AccessibilityUtil.findAllByText(getRoot(), "发布")
                        if (publishButtonList.size >= 2) {
                            AccessibilityUtil.performClick(publishButtonList[1])
                        }
                        sleep(Constant.CHANGE_PAGE_INTERVAL * 3)
                    } else {
                        LogUtils.e("无法进行群公告发布")
                        error("无法进行群公告发布")
                    }
                } else {
                    LogUtils.e("无法进行群公告发布和编辑")
                    error("无法进行群公告发布和编辑")
                    return false
                }
            } else {
                LogUtils.e("未找到群公告按钮")
                error("未找到群公告按钮")
                return false
            }
        } else {
            LogUtils.e("进入群管理页失败")
            error("进入群管理页失败")
        }
        return true
    }

    /**
     * 修改群备注
     * 注：首次为发布 后续为编辑
     * 注2：外部群为edittext 内部群为webview(只能追加文本)
     */
    private fun groupChangeRemark(groupRemark: String?): Boolean {
        if (groupRemark == null) return true
        if (WeworkRoomUtil.intoGroupManager()) {
            val textView = AccessibilityUtil.scrollAndFindByText(
                WeworkController.weworkService,
                getRoot(),
                "备注",
                exact = true
            )
            if (textView != null) {
                AccessibilityUtil.performClick(textView)
                if (AccessibilityUtil.findTextInput(getRoot(), groupRemark)) {
                    LogUtils.d("群备注修改: $groupRemark")
                    if (AccessibilityUtil.findTextAndClick(getRoot(), "确定")) {
                        return true
                    } else {
                        LogUtils.e("无法进行群备注发布")
                        error("无法进行群备注发布")
                    }
                } else {
                    LogUtils.e("无法进行群备注修改")
                    error("无法进行群备注修改")
                }
            } else {
                LogUtils.e("未找到群公告按钮")
                error("未找到群公告按钮")
            }
        } else {
            LogUtils.e("进入群管理页失败")
            error("进入群管理页失败")
        }
        return false
    }

    /**
     * 修改群模板
     */
    private fun groupTemplate(groupTemplate: String?): Boolean {
        if (groupTemplate == null) return true
        if (WeworkRoomUtil.intoGroupManager()) {
            val textView = AccessibilityUtil.scrollAndFindByText(
                WeworkController.weworkService,
                getRoot(),
                "使用模板快速配置群",
                exact = true
            )
            if (textView != null) {
                AccessibilityUtil.performClick(textView)
                val item = AccessibilityUtil.findOneByDesc(getRoot(), groupTemplate)
                if (item != null) {
                    AccessibilityUtil.performClick(item)
                    sleep(Constant.POP_WINDOW_INTERVAL)
                    val useTemplateTv = AccessibilityUtil.findOneByDesc(getRoot(), "使用该模板")
                    if (useTemplateTv != null) {
                        AccessibilityUtil.performClick(useTemplateTv)
                        var useTv = AccessibilityUtil.findOneByDesc(
                            getRoot(),
                            "使用",
                            exact = true,
                            timeout = 2000
                        )
                        if (useTv == null) {
                            val useTemplateTv = AccessibilityUtil.findOneByDesc(getRoot(), "使用该模板")
                            if (useTemplateTv != null) {
                                AccessibilityUtil.performClick(useTemplateTv)
                            }
                            useTv = AccessibilityUtil.findOneByDesc(
                                getRoot(),
                                "使用",
                                exact = true,
                                timeout = 2000
                            )
                        }
                        if (useTv != null) {
                            AccessibilityUtil.performClick(useTv)
                            return true
                        } else {
                            LogUtils.e("未找到使用按钮: $groupTemplate")
                            error("未找到使用按钮: $groupTemplate")
                        }
                    } else {
                        LogUtils.e("未找到使用该模板按钮: $groupTemplate")
                        error("未找到使用该模板按钮: $groupTemplate")
                    }
                } else {
                    LogUtils.e("未找到指定配置: $groupTemplate")
                    error("未找到指定配置: $groupTemplate")
                }
            } else {
                LogUtils.e("未找到使用模板按钮")
                error("未找到使用模板按钮")
            }
        } else {
            LogUtils.e("进入群管理页失败")
            error("进入群管理页失败")
        }
        return false
    }

    /**
     * 发送消息+@at
     */
    private fun sendChatMessage(
        text: String,
        at: String? = null,
        atList: List<String>? = null,
        reply: Boolean? = false,
        title: String
    ): Boolean {
        val roomType = WeworkRoomUtil.getRoomType()
        var titleList = arrayListOf(title) ?: WeworkRoomUtil.getRoomTitle()
        if (titleList.count { it.endsWith("…") } > 0) {
            LogUtils.d("title too long... try get full name titleList: ${titleList.joinToString()}")
            if (roomType == WeworkMessageBean.ROOM_TYPE_INTERNAL_CONTACT || roomType == WeworkMessageBean.ROOM_TYPE_EXTERNAL_CONTACT) {
                titleList = WeworkRoomUtil.getFriendName()
            } else if (Constant.fullGroupName
                && (roomType == WeworkMessageBean.ROOM_TYPE_INTERNAL_GROUP || roomType == WeworkMessageBean.ROOM_TYPE_EXTERNAL_GROUP)
            ) {
                titleList = WeworkRoomUtil.getFullGroupTitle()
            }
        }
        AccessibilityExtraUtil.loadingPage(
            "ExternalGroupMessageListActivity",
            "ExternalWechatUserMessageListActivity",
            "MessageListActivity"
        )
        if (roomType == WeworkMessageBean.ROOM_TYPE_UNKNOWN || titleList.size == 0) {
            LogUtils.e("非聊天房间 无法发送消息")
            error("非聊天房间 无法发送消息")
            return false
        }
        val voiceFlag = AccessibilityUtil.findOnceByText(getRoot(), "按住 说话", "按住说话", exact = true)
        if (voiceFlag != null) {
            AccessibilityUtil.performClickWithSon(AccessibilityUtil.findFrontNode(voiceFlag))
        }
        val quitFlag = AccessibilityUtil.findOnceByText(getRoot(), "无法在已退出的群聊中发送消息", exact = true)
        if (quitFlag != null) {
            LogUtils.e("无法在已退出的群聊中发送消息 title: $title")
            error("无法在已退出的群聊中发送消息 title: $title")
            if (WeworkRoomUtil.intoGroupManager()) {
                if (AccessibilityUtil.findTextAndClick(getRoot(), "删除", exact = true)) {
                    if (AccessibilityExtraUtil.loadingPage("CommonIconInfoDialog")) {
                        if (AccessibilityUtil.findTextAndClick(getRoot(), "删除", exact = true)) {
                            LogUtils.e("删除群聊成功 title: $title")
                            log("删除群聊成功 title: $title")
                        } else {
                            LogUtils.e("未找到确认删除按钮 title: $title")
                            error("未找到确认删除按钮 title: $title")
                        }
                    } else {
                        LogUtils.e("未找到确认删除对话框 title: $title")
                        error("未找到确认删除对话框 title: $title")
                    }
                } else {
                    LogUtils.e("未找到删除按钮 title: $title")
                    error("未找到删除按钮 title: $title")
                }
            } else {
                LogUtils.e("未进入群详情页 title: $title")
                error("未进入群详情页 title: $title")
            }
            return false
        }
        var atFailed = false
        val atList = if (!at.isNullOrEmpty()) arrayListOf(at) else atList?.toMutableList()
        if (!atList.isNullOrEmpty() && (roomType == WeworkMessageBean.ROOM_TYPE_INTERNAL_GROUP || roomType == WeworkMessageBean.ROOM_TYPE_EXTERNAL_GROUP)) {
            if (atList.count { it.startsWith("#regex#") } > 0 && WeworkRoomUtil.intoGroupManager()) {
                val groupInfo =
                    WeworkGetImpl.getGroupInfoDetail(saveAddress = false, saveMembers = true)
                val regex =
                    atList.first { it.startsWith("#regex#") }.split("#regex#").last().toRegex()
                if (groupInfo.nameList != null) {
                    for (name in groupInfo.nameList) {
                        if (name != Constant.myName && name.matches(regex)) {
                            atList.add(name)
                        }
                    }
                }
            }
            atList.removeIf { it.startsWith("#regex#") }
            LogUtils.v("atList: ${atList.joinToString()}")
            LinkedHashSet(atList).forEachIndexed { index, at ->
                if (index == 0) {
                    AccessibilityUtil.findTextInput(getRoot(), "@")
                } else {
                    AccessibilityUtil.sendTextForEditText(
                        Utils.getApp(),
                        AccessibilityUtil.findOnceByClazz(getRoot(), Views.EditText), "@"
                    )
                }
                val atFlag = AccessibilityUtil.findOneByText(getRoot(), "选择提醒的人", exact = true)
                if (atFlag != null) {
                    val searchFlag = AccessibilityUtil.findOneByText(getRoot(), "搜索", exact = true)
                    val container =
                        AccessibilityUtil.findBackNode(searchFlag, minChildCount = 2)?.parent
                    if (container != null) {
                        val atNode = AccessibilityUtil.findOnceByTextRegex(
                            container,
                            "${RegexHelper.reverseRegexTitle(at)}(@.*)?(\\(.*\\))?"
                        )
                        if (atNode != null && !at.matches("^[A-Z#]$".toRegex())) {
                            AccessibilityUtil.performClick(atNode)
                        } else {
                            AccessibilityUtil.findTextInput(getRoot(), at)
                            val atNodeList = AccessibilityUtil.findAllByTextRegex(
                                container,
                                "${RegexHelper.reverseRegexTitle(at)}(@.*)?(\\(.*\\))?",
                                root = false,
                                minSize = 2
                            )
                            if (atNodeList.size > 1 && at != "@所有人") {
                                AccessibilityUtil.performClick(atNodeList[1])
                            } else {
                                LogUtils.e("未找到at人: $at")
                                atFailed = true
                                backPress()
                            }
                        }
                        sleep(Constant.POP_WINDOW_INTERVAL)
                    } else {
                        LogUtils.e("未找到搜索按钮和@列表")
                        error("未找到搜索按钮和@列表")
                        backPress()
                        sleep(Constant.POP_WINDOW_INTERVAL)
                    }
                } else {
                    LogUtils.e("未找到选择提醒的人按钮")
                    error("未找到选择提醒的人按钮")
                }
            }
        }
        LogUtils.v("atFailed: $atFailed")
        val content = if (atFailed) "@${atList?.joinToString()} $text" else text
        val append = (reply == true) || (!atList.isNullOrEmpty() && !atFailed)
        WeworkLoopImpl.getChatMessageList(
            needInfer = false,
            imageCheck = false,
            titleList = titleList
        )
        if (AccessibilityUtil.findTextInput(getRoot(), content, append = append)) {
            AccessibilityUtil.findOneByText(getRoot(), "发送", exact = true, timeout = 2000)
            val sendButton = AccessibilityUtil.findAllByClazz(getRoot(), Views.Button)
                .firstOrNull { it.text?.toString() == "发送" }
            if (sendButton != null) {
                LogUtils.d("发送消息: \n$content")
                log("发送消息: \n$content")
                AccessibilityUtil.performClick(sendButton)
                sleep(Constant.POP_WINDOW_INTERVAL)
                WeworkLoopImpl.getChatMessageList(needInfer = false, titleList = titleList)
                goHome()
                return true
            } else {
                LogUtils.e("未找到发送按钮")
                error("未找到发送按钮")
            }
        } else {
            LogUtils.e("未找到输入框")
            error("未找到输入框")
        }
        return false
    }

    /**
     * 从通讯录查询好友信息
     */
    private fun getFriendInfo(title: String): Boolean {
        goHomeTab("通讯录")
        val list = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView, Views.RecyclerView)
        if (list != null) {
            val frontNode = AccessibilityUtil.findFrontNode(list, minChildCount = 2)
            val textViewList = AccessibilityUtil.findAllOnceByClazz(frontNode, Views.TextView)
            if (textViewList.size >= 2) {
                val searchButton: AccessibilityNodeInfo = textViewList[textViewList.size - 2]
                val multiButton: AccessibilityNodeInfo = textViewList[textViewList.size - 1]
                AccessibilityUtil.performClick(searchButton)
                val needTrim = title.contains(Constant.regTrimTitle)
                val trimTitle = title.replace(Constant.regTrimTitle, "")
                AccessibilityUtil.findTextInput(getRoot(), trimTitle)
                sleep(Constant.CHANGE_PAGE_INTERVAL)
                //消息页搜索结果列表
                val selectListView = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
                val reverseRegexTitle = RegexHelper.reverseRegexTitle(trimTitle)
                val regex1 =
                    (if (Constant.friendRemarkStrict) "^$reverseRegexTitle" else "^(微信昵称:)|((企业)?邮箱:)?$reverseRegexTitle") +
                            (if (needTrim) ".*?" else Constant.suffixString)
                val regex2 = ".*?\\($reverseRegexTitle\\)$"
                val regex = "($regex1)|($regex2)"
                val matchSelect = AccessibilityUtil.findOneByTextRegex(
                    selectListView,
                    regex,
                    timeout = Constant.CHANGE_PAGE_INTERVAL * 3,
                    root = false
                )
                var isSelect = false
                if (selectListView != null && matchSelect != null) {
                    for (i in 0 until selectListView.childCount) {
                        val item = selectListView.getChild(i)
                        val searchResult = AccessibilityUtil.findOnceByTextRegex(item, regex)
                        //过滤异常好友
                        if (searchResult?.parent != null && searchResult.parent.childCount < 3) {
                            item.refresh()
                            val imageView = AccessibilityUtil.findOneByClazz(
                                item,
                                Views.ImageView,
                                root = false
                            )
                            AccessibilityUtil.clickByNode(WeworkController.weworkService, imageView)
                            LogUtils.d("选择联系人")
                            isSelect = true
                            break
                        }
                    }
                }
                if (isSelect) {
                    LogUtils.d("找到搜索结果: $title")
                    return true
                } else {
                    LogUtils.e("未搜索到结果: $title")
                    error("未搜索到结果: $title")
                    val noResult = AccessibilityUtil.findOnceByText(
                        getRoot(),
                        "无搜索结果",
                        "暂无搜索结果",
                        exact = true
                    ) != null
                    LogUtils.e("企微: 无搜索结果: $noResult")
                }
            } else {
                LogUtils.e("ActionBar获取失败: $title")
                error("ActionBar获取失败: $title")
            }
        } else {
            LogUtils.e("通讯录列表获取失败: $title")
            error("通讯录列表获取失败: $title")
        }
        return false
    }

    /**
     * 修改好友信息
     */
    private fun modifyFriendInfo(
        friend: WeworkMessageBean.Friend,
        addFriend: Boolean = true
    ): Boolean {
        if (AccessibilityUtil.findOneByText(
                getRoot(),
                "标签",
                "电话",
                "描述",
                "设置备注和描述",
                exact = true
            ) != null
        ) {
            var markTv = AccessibilityUtil.findOnceByText(getRoot(), "设置备注和描述", exact = true)
            if (markTv == null) {
                markTv = AccessibilityUtil.findOnceByText(getRoot(), "企业", exact = true)
            }
            if (markTv == null) {
                markTv = AccessibilityUtil.findOnceByText(getRoot(), "描述", exact = true)
            }
            //设置备注
            if (markTv != null && (friend.markName != null
                        || friend.markCorp != null || friend.markExtra != null)
            ) {
                AccessibilityUtil.performClick(markTv)
                val etList =
                    AccessibilityUtil.findAllByClazz(getRoot(), Views.EditText, minSize = 2)
                if (etList.size >= 4) {
                    //微信用户 备注/企业/电话/电话/描述
                    if (friend.markName != null) {
                        AccessibilityUtil.editTextInput(etList[0], friend.markName)
                    }
                    if (friend.markCorp != null) {
                        AccessibilityUtil.editTextInput(etList[1], friend.markCorp)
                    }
                    if (friend.markExtra != null) {
                        AccessibilityUtil.editTextInput(etList[etList.size - 1], friend.markExtra)
                    }
                } else if (etList.size == 2) {
                    //同企业内部用户 备注/描述
                    if (friend.markName != null) {
                        AccessibilityUtil.editTextInput(etList[0], friend.markName)
                    }
                    if (friend.markExtra != null) {
                        AccessibilityUtil.editTextInput(etList[etList.size - 1], friend.markExtra)
                    }
                } else if (etList.size == 3) {
                    //外部企业用户 备注/电话/描述
                    if (friend.markName != null) {
                        AccessibilityUtil.editTextInput(etList[0], friend.markName)
                    }
                    if (friend.markExtra != null) {
                        AccessibilityUtil.editTextInput(etList[etList.size - 1], friend.markExtra)
                    }
                }
                AccessibilityUtil.findTextAndClick(getRoot(), "保存")
            }
            //设置标签
            if (!friend.tagList.isNullOrEmpty()) {
                if (AccessibilityUtil.findTextAndClick(getRoot(), "标签")) {
                    setFriendTags(friend.tagList)
                }
            }
            if (!addFriend) {
                return true
            }
            //添加联系人
            val imageView = AccessibilityUtil.findOneByClazz(getRoot(), Views.ImageView)
            if (imageView != null) {
                val textViewList =
                    AccessibilityUtil.findAllOnceByClazz(imageView.parent, Views.TextView)
                val filter = textViewList.filter { it.text != null && it.text.toString() != "微信" }
                if (filter.isNotEmpty()) {
                    val tvNick = filter[0]
                    LogUtils.d("好友昵称或备注名: ${tvNick.text}")
                }
            }
            return true
        } else {
            if (AccessibilityUtil.findOnceByText(getRoot(), "无权查看") != null) {
                LogUtils.e("无权查看该用户")
                error("无权查看该用户")
                return false
            }
            LogUtils.e("未找到标签")
            error("未找到标签")
            return false
        }
    }

    /**
     * 设置好友标签
     */
    fun setFriendTags(tagList: List<String>): Boolean {
        val tagList = if (tagList.size > 5) tagList.subList(0, 5) else tagList
        var tvTag = AccessibilityUtil.findAllByText(getRoot(), "个人标签", exact = true).lastOrNull()
        if (tvTag == null) {
            AccessibilityUtil.scrollAndFindByText(WeworkController.weworkService, getRoot(), "个人标签")
            tvTag = AccessibilityUtil.findAllByText(getRoot(), "个人标签", exact = true).lastOrNull()
        }
        val oldTagList = arrayListOf<String>()
        val list = AccessibilityUtil.findBackNode(tvTag)
        if (list != null && list.childCount > 0) {
            for (i in 0 until list.childCount) {
                val child = list.getChild(i)
                if (child.className.equals(Views.TextView) && child.text != null) {
                    oldTagList.add(child.text.toString())
                }
            }
            //不存在的标签先添加
            for (tag in tagList) {
                if (!oldTagList.contains(tag)) {
                    if (Constant.version >= 40108) {
                        AccessibilityUtil.findTextAndClick(getRoot(), "    十    ")
                        AccessibilityUtil.findTextInput(getRoot(), tag)
                        AccessibilityUtil.findTextAndClick(getRoot(), "确定")
                    } else {
                        AccessibilityUtil.findOneByText(getRoot(), "个人标签")
                        sleep(Constant.POP_WINDOW_INTERVAL)
                        val tempList = AccessibilityUtil.findBackNode(
                            AccessibilityUtil.findAllByText(getRoot(), "个人标签").lastOrNull()
                        )
                        if (tempList != null && tempList.childCount > 0) {
                            AccessibilityUtil.performClick(tempList.getChild(0))
                            AccessibilityUtil.findTextInput(getRoot(), tag)
                            AccessibilityUtil.findTextAndClick(getRoot(), "确定")
                        }
                    }
                }
            }
            //确认只选择列表里的标签
            val count = list.childCount
            for (i in 0 until count) {
                val child = list.getChild(i)
                if (child != null) {
                    val text = child.text
                    val selected = child.isSelected
                    LogUtils.v("text: $text selected: $selected")
                    if (tagList.count { it == text?.toString() } > 0) {
                        if (!selected) {
                            AccessibilityUtil.performClick(child)
                        }
                    } else {
                        if (selected) {
                            AccessibilityUtil.performClick(child)
                        }
                    }
                }
                list.refresh()
            }
            if (AccessibilityUtil.findTextAndClick(getRoot(), "确定", "保存", exact = true)) {
                sleep(Constant.POP_WINDOW_INTERVAL)
                //可能有两次确定 另一次为添加新tag
                val textNode =
                    AccessibilityUtil.findOneByText(getRoot(), "确定", "保存", "个人信息", exact = true)
                if (textNode?.text?.toString() in arrayOf("确定", "保存")) {
                    AccessibilityUtil.performClick(textNode)
                }
                LogUtils.d("设置标签完成")
                return true
            }
        }
        LogUtils.e("未找到个人标签")
        error("未找到个人标签")
        return false
    }

    /**
     * 获取群二维码并上传后台
     */
    private fun getGroupQrcode(groupName: String, groupRemark: String?): Boolean {
        if (!Constant.groupQrCode) return true
        if (AccessibilityUtil.findOneByText(
                getRoot(),
                "全部群成员",
                "微信用户创建",
                timeout = Constant.CHANGE_PAGE_INTERVAL
            ) != null ||
            (WeworkRoomUtil.intoRoom(groupName) && WeworkRoomUtil.intoGroupManager())
        ) {
            val tvList = AccessibilityUtil.findAllOnceByClazz(getRoot(), Views.TextView)
            tvList.forEachIndexed { index, tv ->
                if (tv.text?.toString()?.contains("微信用户创建") == true) {
                    if (index + 1 < tvList.size) {
                        val tvQr = tvList[index + 1]
                        AccessibilityUtil.performClick(tvQr)
                    }
                }
            }
            AccessibilityUtil.findOneByText(getRoot(), "保存到相册")
            val startTime = System.currentTimeMillis()
            var currentTime = startTime
            while (currentTime - startTime <= Constant.CHANGE_PAGE_INTERVAL * 5) {
                AccessibilityUtil.findOnceByClazz(getRoot(), Views.ProgressBar) ?: break
                sleep(Constant.POP_WINDOW_INTERVAL / 5)
                currentTime = System.currentTimeMillis()
            }
            if (AccessibilityUtil.findTextAndClick(getRoot(), "保存到相册")) {
                sleep(Constant.CHANGE_PAGE_INTERVAL)
                val fileDirPath = "/storage/emulated/0/DCIM/WeixinWork"
                val fileDir = FileUtils.getFileByPath(fileDirPath)
                if (fileDir.isDirectory) {
                    for (file in fileDir.listFiles().filter { it.name.endsWith(".jpg") }) {
                        val fileTime = file.name.replace("mmexport", "")
                            .replace(".jpg", "")
                        LogUtils.v("fileTime: $fileTime")
                        if (fileTime.isNotBlank()) {
                            if (fileTime.toLongOrNull() ?: 0 > currentTime) {
                                LogUtils.d("找到最新保存二维码图片: $fileTime")
                                try {
                                    val bitmap = ImageUtils.bytes2Bitmap(file.readBytes())
                                    val mDecoder = QRCodeDecoder.Builder().build()
                                    val qrcode = mDecoder.decode(bitmap)
                                    LogUtils.d("group: $groupName qrcode: $qrcode")
                                    val weworkMessageBean = WeworkMessageBean()
                                    weworkMessageBean.type = WeworkMessageBean.GET_GROUP_QRCODE
                                    weworkMessageBean.groupName = groupName
                                    weworkMessageBean.groupRemark = groupRemark
                                    weworkMessageBean.qrcode = qrcode
                                    WeworkController.weworkService.webSocketManager.send(
                                        weworkMessageBean
                                    )
                                    return true
                                } catch (e: Exception) {
                                    LogUtils.e(e)
                                }
                            }
                        }
                    }
                }
            }
        }
        return false
    }

    /**
     * 保存到通讯录
     */
    private fun saveToContract(): Boolean {
        if (WeworkRoomUtil.intoGroupManager()) {
            AccessibilityUtil.findOneByText(getRoot(), "全部群成员", "微信用户创建") ?: return false
            LogUtils.d("保存到通讯录")
            val tvAddressFlag = AccessibilityUtil.scrollAndFindByText(
                WeworkController.weworkService,
                getRoot(),
                "保存到通讯录",
                exact = true
            )
            val tvAddress = AccessibilityUtil.findBackNode(tvAddressFlag, minChildCount = 1)
            val addressDesc =
                AccessibilityUtil.findOnceByDesc(tvAddress, "false", "true", exact = true)
            if (addressDesc?.contentDescription == "false") {
                LogUtils.d("未保存到通讯录 进行保存...")
                AccessibilityUtil.performClick(addressDesc)
            }
        }
        return true
    }

    /**
     *转让群主
     */
    fun transferGroup(
        message: WeworkMessageBean,
        groupName: String
    ): Boolean {
        val startTime = System.currentTimeMillis()
        if ((WeworkRoomUtil.intoRoom(groupName) || WeworkRoomUtil.intoRoom(
                groupName,
                fastIn = false
            )) && WeworkRoomUtil.intoGroupManager()
        ) {
            val groupManagerTv = AccessibilityUtil.scrollAndFindByText(
                WeworkController.weworkService,
                getRoot(),
                "群管理",
                exact = true
            )
            if (groupManagerTv != null) {
                AccessibilityUtil.performClick(groupManagerTv)
                val dismissTv =
                    AccessibilityUtil.findOneByText(getRoot(), "转让群主", exact = true, timeout = 2000)
                AccessibilityUtil.performClick(dismissTv)
                val selectListView = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
                if (selectListView != null) {
                    var type = false
                    for (i in 0 until selectListView.childCount) {
                        val item = selectListView.getChild(i)
                        var result = AccessibilityUtil.findAllOnceByClazz(item, Views.TextView)
                            .mapNotNull { it.text }
//                        val searchResult =
//                            AccessibilityUtil.findOnceByTextRegex(item)
                        if (result.isNotEmpty() && result[0].toString() == message.transferName) {
                            AccessibilityUtil.performClick(item)
                            val transfer =
                                AccessibilityUtil.findOneByText(
                                    getRoot(),
                                    "确定",
                                    "确定",
                                    exact = true,
                                    timeout = 2000
                                )
                            if (transfer != null) {
                                type = true
                                AccessibilityUtil.performClick(transfer)
                            }
                            break
                        }
                    }
                    if (type) {
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.SUCCESS,
                            "",
                            startTime,
                            listOf(groupName),
                            listOf()
                        )
                        return true
                    }
                }
            }
            uploadCommandResult(
                message,
                ExecCallbackBean.ERROR_BUTTON,
                "查询不到人",
                startTime,
                listOf(groupName),
                listOf()
            )
            LogUtils.d("查询不到人...")
        }
        return false
    }

    /**
     *设置管理员
     */
    fun administrators(
        message: WeworkMessageBean,
        groupName: String
    ): Boolean {
        val startTime = System.currentTimeMillis()
        if ((WeworkRoomUtil.intoRoom(groupName) || WeworkRoomUtil.intoRoom(
                groupName,
                fastIn = false
            )) && WeworkRoomUtil.intoGroupManager()
        ) {
            val groupManagerTv = AccessibilityUtil.scrollAndFindByText(
                WeworkController.weworkService,
                getRoot(),
                "群管理",
                exact = true
            )
            if (groupManagerTv != null) {
                AccessibilityUtil.performClick(groupManagerTv)
                val dismissTv =
                    AccessibilityUtil.findOneByText(getRoot(), "群管理员", exact = true, timeout = 2000)
                AccessibilityUtil.performClick(dismissTv)
                sleep(Constant.POP_WINDOW_INTERVAL)
                val gridView = AccessibilityUtil.findOnceByClazz(getRoot(), Views.GridView)
                if (gridView != null && gridView.childCount >= 2) {
                    val tvEmptySize =
                        AccessibilityUtil.findAllOnceByClazz(gridView, Views.ImageView)
                            .filter { it.text == null }.size
                    LogUtils.v("tvEmptySize: $tvEmptySize")
                    if (tvEmptySize == 0) {
//                        selectResult.result = true
                        return false
                    } else {
                        LogUtils.d("点击拉人按钮")
                        AccessibilityUtil.performClick(gridView.getChild(gridView.childCount - 2))
                    }

                } else if (gridView != null) {
                    LogUtils.d("点击拉人按钮")
                    AccessibilityUtil.performClick(gridView.getChild(gridView.childCount - 1))
                }
            }
            sleep(Constant.POP_WINDOW_INTERVAL)
            val list = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
            if (list != null) {
                val frontNode = AccessibilityUtil.findFrontNode(list, 2)
                val textViewList = AccessibilityUtil.findAllOnceByClazz(frontNode, Views.TextView)
                if (textViewList.size >= 2) {
                    val multiButton = textViewList.lastOrNull()
                    var count = 0
                    for (select in LinkedHashSet(message.selectList)) {
                        val needTrim = select.contains(Constant.regTrimTitle)
                        val trimTitle = select.replace(Constant.regTrimTitle, "")
                        AccessibilityUtil.performClick(multiButton)
                        AccessibilityUtil.findTextInput(getRoot(), trimTitle)
                        sleep(Constant.POP_WINDOW_INTERVAL)
                        val selectListView = AccessibilityUtil.findOneByClazz(
                            getRoot(),
                            Views.ListView,
                            Views.RecyclerView,
                            Views.ViewGroup
                        )
                        val reverseRegexTitle = RegexHelper.reverseRegexTitle(trimTitle)
                        val regex1 =
                            (if (Constant.friendRemarkStrict) "^$reverseRegexTitle" else "^(微信昵称:)|((企业)?邮箱:)?$reverseRegexTitle") +
                                    (if (needTrim) ".*?" else Constant.suffixString)
                        val regex2 = ".*?\\($reverseRegexTitle\\)$"
                        val regex = "($regex1)|($regex2)"
                        val matchSelect = AccessibilityUtil.findOneByTextRegex(
                            selectListView,
                            regex,
                            timeout = Constant.CHANGE_PAGE_INTERVAL * 3,
                            root = false
                        )
                        if (selectListView != null && (matchSelect != null || reverseRegexTitle.matches(
                                Constant.regMail
                            ))
                        ) {
                            var flag = false
                            for (i in 0 until selectListView.childCount) {
                                val item = selectListView.getChild(i)
                                if ((matchSelect == null && item.className == Views.RelativeLayout)
                                    || AccessibilityUtil.findOnceByTextRegex(item, regex) != null
                                ) {
                                    item.refresh()
                                    val imageView = AccessibilityUtil.findOneByClazz(
                                        item,
                                        Views.ImageView,
                                        root = false
                                    )
                                    if (imageView != null && !imageView.isEnabled) {
                                        flag = true
                                    } else if (AccessibilityUtil.performClick(imageView)) {
                                        flag = true
                                        count += 1
                                    }
                                    if (select.contains(" ")) {
                                        break
                                    }
                                }
                            }
                            if (!flag) {
                                LogUtils.e("拉人失败 找不到: $select")
                                error("拉人失败 找不到: $select")
                            }
                        }
                        val noResult = AccessibilityUtil.findOnceByText(
                            getRoot(),
                            "无搜索结果",
                            "暂无搜索结果",
                            exact = true
                        ) != null
                        val textView = AccessibilityUtil.findOnceByClazz(getRoot(), Views.TextView)
                        if (textView != null && textView.text.isNullOrBlank()) {
                            AccessibilityUtil.performClick(textView)
                            sleep(Constant.POP_WINDOW_INTERVAL)
                        }
//                        if (matchSelect != null) {
//                            selectResult.successList.add(select)
//                            LogUtils.d("找到搜索结果: $select")
//                        } else {
//                            selectResult.failList.add(select)
//                            LogUtils.e("未搜索到结果: $select")
//                            error("未搜索到结果: $select")
//                            LogUtils.e("企微: 无搜索结果: $noResult")
//                            if (Constant.groupStrict) return selectResult
//                        }
                    }
                    if (count == 0) {
                        while (AccessibilityUtil.findOnceByText(
                                getRoot(),
                                "全部群成员",
                                "微信用户创建"
                            ) == null && !isAtHome()
                        ) {
                            backPress()
                        }
                        LogUtils.d("拉入0人")
//                        selectResult.result = true
//                        return selectResult
                    }
                    val confirmButton =
                        AccessibilityUtil.findOneByTextRegex(getRoot(), "^确定(\\(\\d+\\))?\$")
                    if (confirmButton != null) {
                        AccessibilityUtil.performClick(confirmButton)
                        if (AccessibilityExtraUtil.loadingPage(
                                "CustomDialog",
                                timeout = Constant.POP_WINDOW_INTERVAL
                            )
                        ) {
                            AccessibilityUtil.findTextAndClick(getRoot(), "邀请", exact = true)
                        }
//                        return true
                    } else {
                        LogUtils.e("未发现确认按钮")
//                        error("未发现确认按钮")
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_BUTTON,
                            "未发现确认按钮",
                            startTime,
                            listOf(groupName),
                            listOf()
                        )
                        return false
                    }
                }
            }
        }
        uploadCommandResult(
            message,
            ExecCallbackBean.SUCCESS,
            "",
            startTime,
            listOf(groupName),
            listOf()
        )
        return true
    }

    fun removeAdministrators(
        message: WeworkMessageBean,
        groupName: String
    ): Boolean {
        val startTime = System.currentTimeMillis()
        if ((WeworkRoomUtil.intoRoom(groupName) || WeworkRoomUtil.intoRoom(
                groupName,
                fastIn = false
            )) && WeworkRoomUtil.intoGroupManager()
        ) {
            val groupManagerTv = AccessibilityUtil.scrollAndFindByText(
                WeworkController.weworkService,
                getRoot(),
                "群管理",
                exact = true
            )
            if (groupManagerTv != null) {
                AccessibilityUtil.performClick(groupManagerTv)
                val dismissTv =
                    AccessibilityUtil.findOneByText(getRoot(), "群管理员", exact = true, timeout = 2000)
                AccessibilityUtil.performClick(dismissTv)
                sleep(Constant.POP_WINDOW_INTERVAL)
                val gridView = AccessibilityUtil.findOnceByClazz(getRoot(), Views.GridView)
                if (gridView != null && gridView.childCount >= 2) {
                    val tvEmptySize =
                        AccessibilityUtil.findAllOnceByClazz(gridView, Views.ImageView)
                            .filter { it.text == null }.size
                    LogUtils.v("tvEmptySize: $tvEmptySize")
                    if (tvEmptySize == 0) {
                        LogUtils.e("没有找到列表")
                        return false
                    } else {
                        LogUtils.d("点击拉人按钮")
                        AccessibilityUtil.performClick(gridView.getChild(gridView.childCount - 1))
                    }

                }
            }
            sleep(Constant.POP_WINDOW_INTERVAL)
            val list = AccessibilityUtil.findOneByClazz(getRoot(), Views.ListView)
            if (list != null) {
                val frontNode = AccessibilityUtil.findFrontNode(list, 2)
                val textViewList = AccessibilityUtil.findAllOnceByClazz(frontNode, Views.TextView)
                if (textViewList.size >= 2) {
                    val multiButton = textViewList.lastOrNull()
                    var count = 0
                    for (select in LinkedHashSet(message.selectList)) {
                        val needTrim = select.contains(Constant.regTrimTitle)
                        val trimTitle = select.replace(Constant.regTrimTitle, "")
                        AccessibilityUtil.performClick(multiButton)
                        AccessibilityUtil.findTextInput(getRoot(), trimTitle)
                        sleep(Constant.POP_WINDOW_INTERVAL)
                        val selectListView = AccessibilityUtil.findOneByClazz(
                            getRoot(),
                            Views.ListView,
                            Views.RecyclerView,
                            Views.ViewGroup
                        )
                        val reverseRegexTitle = RegexHelper.reverseRegexTitle(trimTitle)
                        val regex1 =
                            (if (Constant.friendRemarkStrict) "^$reverseRegexTitle" else "^(微信昵称:)|((企业)?邮箱:)?$reverseRegexTitle") +
                                    (if (needTrim) ".*?" else Constant.suffixString)
                        val regex2 = ".*?\\($reverseRegexTitle\\)$"
                        val regex = "($regex1)|($regex2)"
                        val matchSelect = AccessibilityUtil.findOneByTextRegex(
                            selectListView,
                            regex,
                            timeout = Constant.CHANGE_PAGE_INTERVAL * 3,
                            root = false
                        )
                        if (selectListView != null && (matchSelect != null || reverseRegexTitle.matches(
                                Constant.regMail
                            ))
                        ) {
                            var flag = false
                            for (i in 0 until selectListView.childCount) {
                                val item = selectListView.getChild(i)
                                if ((matchSelect == null && item.className == Views.RelativeLayout)
                                    || AccessibilityUtil.findOnceByTextRegex(item, regex) != null
                                ) {
                                    item.refresh()
                                    val imageView = AccessibilityUtil.findOneByClazz(
                                        item,
                                        Views.ImageView,
                                        root = false
                                    )
                                    if (imageView != null && !imageView.isEnabled) {
                                        flag = true
                                    } else if (AccessibilityUtil.performClick(imageView)) {
                                        flag = true
                                        count += 1
                                    }
                                    if (select.contains(" ")) {
                                        break
                                    }
                                }
                            }
                            if (!flag) {
                                LogUtils.e("拉人失败 找不到: $select")
                                error("拉人失败 找不到: $select")
                            }
                        }
                        val noResult = AccessibilityUtil.findOnceByText(
                            getRoot(),
                            "无搜索结果",
                            "暂无搜索结果",
                            exact = true
                        ) != null
                        val textView = AccessibilityUtil.findOnceByClazz(getRoot(), Views.TextView)
                        if (textView != null && textView.text.isNullOrBlank()) {
                            AccessibilityUtil.performClick(textView)
                            sleep(Constant.POP_WINDOW_INTERVAL)
                        }
                    }
                    if (count == 0) {
                        while (AccessibilityUtil.findOnceByText(
                                getRoot(),
                                "全部群成员",
                                "微信用户创建"
                            ) == null && !isAtHome()
                        ) {
                            backPress()
                        }
                    }
                    val confirmButton =
                        AccessibilityUtil.findOneByTextRegex(getRoot(), "^确定(\\(\\d+\\))?\$")
                    if (confirmButton != null) {
                        AccessibilityUtil.performClick(confirmButton)
                        if (AccessibilityExtraUtil.loadingPage(
                                "CustomDialog",
                                timeout = Constant.POP_WINDOW_INTERVAL
                            )
                        ) {
                            AccessibilityUtil.findTextAndClick(getRoot(), "邀请", exact = true)
                        }
                    } else {
                        LogUtils.e("未发现确认按钮")
//                        error("未发现确认按钮")
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.ERROR_BUTTON,
                            "未发现确认按钮",
                            startTime,
                            listOf(groupName),
                            listOf()
                        )
                        return false
                    }
                }
            }
        }
        uploadCommandResult(
            message,
            ExecCallbackBean.SUCCESS,
            "",
            startTime,
            listOf(groupName),
            listOf()
        )
        return true
    }

    fun prohibitGroupName(type: String?): Boolean {
        if (type == null) {
            return true
        }
        if (WeworkRoomUtil.intoGroupManager()) {
            val textView = AccessibilityUtil.scrollAndFindByText(
                WeworkController.weworkService,
                getRoot(),
                "群管理",
                exact = true
            )
            if (textView != null) {
                AccessibilityUtil.performClick(textView)
            }
            val tvAddressFlag =
                AccessibilityUtil.findOneByText(getRoot(), "禁止改群名", exact = true, timeout = 2000)
            if (tvAddressFlag != null) {
                val tvAddress = AccessibilityUtil.findBackNode(tvAddressFlag, minChildCount = 1)
                val addressDesc =
                    AccessibilityUtil.findOnceByDesc(tvAddress, "false", "true", exact = true)
//                if (addressDesc?.contentDescription == "false") {
                AccessibilityUtil.performClick(addressDesc)
//                }
            }
        }
        return true
    }

    fun cancelHarassRules(message: WeworkMessageBean): Boolean {
        val startTime = System.currentTimeMillis()
        val successList = arrayListOf<String>()
        val failList = arrayListOf<String>()
        for (title in LinkedHashSet(message.groupList)) {
            if ((WeworkRoomUtil.intoRoom(title.name) || WeworkRoomUtil.intoRoom(
                    title.name,
                    fastIn = false
                )) && WeworkRoomUtil.intoGroupManager()
            ) {
                if (WeworkRoomUtil.intoGroupManager()) {
                    if (WeworkRoomUtil.intoGroupHarass()) {
                        sleep(Constant.POP_WINDOW_INTERVAL)
                        val settingTv = AccessibilityUtil.findOneByText(
                            getRoot(),
                            "编辑",
                            timeout = 2000
                        )
                        AccessibilityUtil.performClick(settingTv)
                        sleep(Constant.POP_WINDOW_INTERVAL)
                        val removeTv = AccessibilityUtil.findOneByText(
                            getRoot(),
                            "移除",
                            timeout = 2000
                        )
                        AccessibilityUtil.performClick(removeTv)
                        sleep(Constant.POP_WINDOW_INTERVAL)
                        val node = AccessibilityUtil.scrollAndFindByText(
                            WeworkController.weworkService,
                            getRoot(),
                            message.name,
                            exact = true
                        )
                        if (node != null) {
                            AccessibilityUtil.performClick(node)
                            sleep(Constant.POP_WINDOW_INTERVAL)
                            val remove = AccessibilityUtil.findOneByText(
                                getRoot(),
                                "移除",
                                timeout = 2000
                            )
                            AccessibilityUtil.performClick(remove)
                            successList.add(title.id)
                        } else {
                            //TODO 查询不到规则
                            failList.add(title.id)
                        }
                    }
                }
            } else {
                //TODO 进入群失败
                failList.add(title.id)
            }
        }
        uploadCommandResult(
            message,
            ExecCallbackBean.SUCCESS,
            "",
            startTime,
            successList,
            failList
        )
        return true
    }

    fun applyHarassRules(message: WeworkMessageBean): Boolean {
        val startTime = System.currentTimeMillis()
        val successList = arrayListOf<String>()
        val failList = arrayListOf<String>()
        for (title in LinkedHashSet(message.groupList)) {
            if ((WeworkRoomUtil.intoRoom(title.name) || WeworkRoomUtil.intoRoom(
                    title.name,
                    fastIn = false
                )) && WeworkRoomUtil.intoGroupManager()
            ) {
                if (WeworkRoomUtil.intoGroupManager()) {
                    if (WeworkRoomUtil.intoGroupHarass()) {
                        sleep(Constant.POP_WINDOW_INTERVAL)
                        val selectTv = AccessibilityUtil.scrollAndFindByText(
                            WeworkController.weworkService,
                            getRoot(),
                            message.name,
                            exact = true
                        )
                        if (selectTv == null) {
                            val setting = AccessibilityUtil.scrollAndFindByText(
                                WeworkController.weworkService,
                                getRoot(),
                                "配置规则到客户群",
                                "配置",
                                exact = true
                            )
                            AccessibilityUtil.performClick(setting)
                            sleep(Constant.POP_WINDOW_INTERVAL)
                            val select = AccessibilityUtil.scrollAndFindByText(
                                WeworkController.weworkService,
                                getRoot(),
                                message.name,
                                exact = true
                            )
                            if (select != null) {
                                AccessibilityUtil.performClick(select)
                                sleep(Constant.POP_WINDOW_INTERVAL)
                                val add = AccessibilityUtil.findOneByText(
                                    getRoot(),
                                    "完成",
                                    timeout = 2000
                                )
                                AccessibilityUtil.performClick(add)
                                successList.add(title.id)
                            } else {
                                failList.add(title.id)
                            }
                        } else {
                            successList.add(title.id)
                        }
                    }
                }
            } else {
                //TODO 进入群失败
                failList.add(title.id)
            }
        }
        uploadCommandResult(
            message,
            ExecCallbackBean.SUCCESS,
            "",
            startTime,
            successList,
            failList
        )
        return true
    }

    fun deleteHarassRules(message: WeworkMessageBean): Boolean {
        goHomeTab("工作台")
        val node = AccessibilityUtil.scrollAndFindByText(
            WeworkController.weworkService,
            getRoot(),
            "客户群",
            "居民群",
            "学员群",
            exact = true
        )
        val startTime = System.currentTimeMillis()
        if (node != null) {
            AccessibilityUtil.performClick(node)
            sleep(Constant.POP_WINDOW_INTERVAL)
            val groupManagerTv = AccessibilityUtil.scrollAndFindByText(
                WeworkController.weworkService,
                getRoot(),
                "防骚扰",
                exact = true
            )
            if (groupManagerTv != null) {
                AccessibilityUtil.performClick(groupManagerTv)
                val settingTv = AccessibilityUtil.findOneByText(
                    getRoot(),
                    "配置企业成员防骚扰规则",
                    timeout = 2000
                )
                AccessibilityUtil.performClick(settingTv)
                sleep(Constant.POP_WINDOW_INTERVAL)
                val groupTv = AccessibilityUtil.scrollAndFindByText(
                    WeworkController.weworkService,
                    getRoot(),
                    message.name,
                    exact = true
                )
                if (groupTv != null) {
                    AccessibilityUtil.performClick(groupTv)
                    sleep(Constant.POP_WINDOW_INTERVAL)
                    val detailsTv = AccessibilityUtil.findOneByText(
                        getRoot(),
                        "编辑",
                        timeout = 2000
                    )
                    AccessibilityUtil.performClick(detailsTv)
                    sleep(Constant.POP_WINDOW_INTERVAL)
                    val delete = AccessibilityUtil.scrollAndFindByText(
                        WeworkController.weworkService,
                        getRoot(),
                        "删除",
                        exact = true
                    )
                    AccessibilityUtil.performClick(delete)
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.SUCCESS,
                        "",
                        startTime
                    )
                } else {
                    uploadCommandResult(
                        message,
                        ExecCallbackBean.ERROR_SEARCH_ALARM,
                        "搜索不到规则",
                        startTime
                    )
                }
            } else {
                uploadCommandResult(
                    message,
                    ExecCallbackBean.ERROR_SEARCH_ALARM,
                    "没有搜索到配置企业成员防骚扰规则",
                    startTime
                )
            }
        }
        return true
    }

    fun setHarassRules(message: WeworkMessageBean): Boolean {
        goHomeTab("工作台")
        val node = AccessibilityUtil.scrollAndFindByText(
            WeworkController.weworkService,
            getRoot(),
            "客户群",
            "居民群",
            "学员群",
            exact = true
        )
        val startTime = System.currentTimeMillis()
        if (node != null) {
            AccessibilityUtil.performClick(node)
            sleep(Constant.POP_WINDOW_INTERVAL)
            val groupManagerTv = AccessibilityUtil.scrollAndFindByText(
                WeworkController.weworkService,
                getRoot(),
                "防骚扰",
                exact = true
            )
            if (groupManagerTv != null) {
                AccessibilityUtil.performClick(groupManagerTv)
                val settingTv = AccessibilityUtil.findOneByText(
                    getRoot(),
                    "配置企业成员防骚扰规则",
                    timeout = 2000
                )
                AccessibilityUtil.performClick(settingTv)
                sleep(Constant.POP_WINDOW_INTERVAL)
                val addTv = AccessibilityUtil.scrollAndFindByText(
                    WeworkController.weworkService,
                    getRoot(),
                    "添加规则",
                    "新建",
                    exact = true
                )
                sleep(Constant.POP_WINDOW_INTERVAL)
                if (addTv != null) {
                    AccessibilityUtil.performClick(addTv)
                    sleep(Constant.POP_WINDOW_INTERVAL)
                }
                if (settingAlarm(message)) {
                    sleep(Constant.BASE_CHANGE_PAGE_INTERVAL)
                    val confirm = AccessibilityUtil.findOneByText(
                        getRoot(),
                        "确定",
                        exact = true
                    )
                    if (confirm != null) {
                        AccessibilityUtil.performClick(confirm)
                        uploadCommandResult(
                            message,
                            ExecCallbackBean.SUCCESS,
                            "",
                            startTime
                        )
                        return true
                    }
                }
            }
        }
        uploadCommandResult(
            message,
            ExecCallbackBean.ERROR_OTHER,
            "",
            startTime
        )
        return false
    }

    fun settingAlarm(message: WeworkMessageBean): Boolean {
        if ("1" == message.msgCheckFlag && message.msgKeywordList != null) {
            val msgCheckFlag =
                AccessibilityUtil.findOneByText(
                    getRoot(),
                    "消息包含关键词踢出群聊",
                    timeout = 2000
                )
            val tvMsgCheck =
                AccessibilityUtil.findBackNode(msgCheckFlag, minChildCount = 1)
            val msgCheckDesc =
                AccessibilityUtil.findOnceByDesc(
                    tvMsgCheck,
                    "false",
                    "true",
                    exact = true
                )
            AccessibilityUtil.performClick(msgCheckDesc)
            sleep(Constant.POP_WINDOW_INTERVAL)
            val msgKeywordSize = message.msgKeywordList.size
            for (i in 0..msgKeywordSize - 1) {
                val etList =
                    AccessibilityUtil.findAllByClazz(
                        getRoot(),
                        Views.EditText,
                        minSize = 2
                    )
                AccessibilityUtil.editTextInput(
                    etList[i],
                    message.msgKeywordList.get(i)
                )
                if (i < msgKeywordSize - 1) {
                    val addMsgTv = AccessibilityUtil.scrollAndFindByText(
                        WeworkController.weworkService,
                        getRoot(),
                        "添加关键词",
                        exact = true
                    )
                    AccessibilityUtil.performClick(addMsgTv)
                    sleep(Constant.POP_WINDOW_INTERVAL)
                }
            }
        }
        if ("1" == message.miniSendFlag && message.miniNameList != null) {
            val miniCheckFlag =
                AccessibilityUtil.findOneByText(
                    getRoot(),
                    "踢发小程序",
                    timeout = 2000
                )
            val tvMiniCheck =
                AccessibilityUtil.findBackNode(miniCheckFlag, minChildCount = 1)
            val miniCheckDesc =
                AccessibilityUtil.findOnceByDesc(
                    tvMiniCheck,
                    "false",
                    "true",
                    exact = true
                )
            AccessibilityUtil.performClick(miniCheckDesc)
            sleep(Constant.POP_WINDOW_INTERVAL)
            val miniNameSize = message.miniNameList.size
            for (i in 0..miniNameSize - 1) {
                val addMsgTv = AccessibilityUtil.scrollAndFindByText(
                    WeworkController.weworkService,
                    getRoot(),
                    "配置",
                    exact = true
                )
                AccessibilityUtil.performClick(addMsgTv)
                sleep(Constant.POP_WINDOW_INTERVAL)
                val mini = AccessibilityUtil.scrollAndFindByText(
                    WeworkController.weworkService,
                    getRoot(),
                    message.miniNameList.get(i),
                    exact = true
                )
                sleep(Constant.POP_WINDOW_INTERVAL)
                AccessibilityUtil.performClick(mini)
            }
        }
        if ("1" == message.urlSendFlag && message.urlList != null) {
            val urlCheckFlag =
                AccessibilityUtil.findOneByText(
                    getRoot(),
                    "踢发网页",
                    timeout = 2000
                )
            val tvUrlCheck =
                AccessibilityUtil.findBackNode(urlCheckFlag, minChildCount = 1)
            val urlCheckDesc =
                AccessibilityUtil.findOnceByDesc(
                    tvUrlCheck,
                    "false",
                    "true",
                    exact = true
                )
            AccessibilityUtil.performClick(urlCheckDesc)
            sleep(Constant.POP_WINDOW_INTERVAL)
            val urlSize = message.urlList.size
            for (i in 0..urlSize - 1) {
                var urlTag =
                    AccessibilityUtil.findAllByText(getRoot(), "配置", exact = true)
                        .lastOrNull()
                AccessibilityUtil.performClick(urlTag)
                sleep(Constant.POP_WINDOW_INTERVAL)
                AccessibilityUtil.findTextInput(getRoot(), message.urlList.get(i))
                val urlComplete = AccessibilityUtil.findOneByText(
                    getRoot(),
                    "完成",
                    timeout = 2000
                )
                AccessibilityUtil.performClick(urlComplete)
            }
        }
        if ("1" == message.qrcodeSendFlag) {
            val codeTv = AccessibilityUtil.scrollAndFindByText(
                WeworkController.weworkService,
                getRoot(),
                "踢发二维码",
                exact = true
            )
            sleep(Constant.POP_WINDOW_INTERVAL)
            val tvCodeCheck =
                AccessibilityUtil.findBackNode(codeTv, minChildCount = 1)
            val codeCheckDesc =
                AccessibilityUtil.findOnceByDesc(
                    tvCodeCheck,
                    "false",
                    "true",
                    exact = true
                )
            AccessibilityUtil.performClick(codeCheckDesc)
            sleep(Constant.POP_WINDOW_INTERVAL)
        }
        if ("1" == message.moreFlag) {
            val moreTv = AccessibilityUtil.scrollAndFindByText(
                WeworkController.weworkService,
                getRoot(),
                "更多设置",
                exact = true
            )
            sleep(Constant.POP_WINDOW_INTERVAL)
            AccessibilityUtil.performClick(moreTv)
            sleep(Constant.POP_WINDOW_INTERVAL)
            if ("1" == message.photoSendFlag) {
                val photoTv = AccessibilityUtil.scrollAndFindByText(
                    WeworkController.weworkService,
                    getRoot(),
                    "踢发图片",
                    exact = true
                )
                val tvPhotoCheck =
                    AccessibilityUtil.findBackNode(photoTv, minChildCount = 1)
                val photoCheckDesc =
                    AccessibilityUtil.findOnceByDesc(
                        tvPhotoCheck,
                        "false",
                        "true",
                        exact = true
                    )
                AccessibilityUtil.performClick(photoCheckDesc)
            }
            if ("1" == message.chatSendFlag) {
                val chatSendTv = AccessibilityUtil.scrollAndFindByText(
                    WeworkController.weworkService,
                    getRoot(),
                    "踢发聊天记录",
                    exact = true
                )
                val tvChatSendCheck =
                    AccessibilityUtil.findBackNode(chatSendTv, minChildCount = 1)
                val chatSendCheckDesc =
                    AccessibilityUtil.findOnceByDesc(
                        tvChatSendCheck,
                        "false",
                        "true",
                        exact = true
                    )
                AccessibilityUtil.performClick(chatSendCheckDesc)
            }
            if ("1" == message.voiceSendFlag) {
                val voiceSendTv = AccessibilityUtil.scrollAndFindByText(
                    WeworkController.weworkService,
                    getRoot(),
                    "踢发语音",
                    exact = true
                )
                val tvVoiceSendCheck =
                    AccessibilityUtil.findBackNode(voiceSendTv, minChildCount = 1)
                val voiceSendCheckDesc =
                    AccessibilityUtil.findOnceByDesc(
                        tvVoiceSendCheck,
                        "false",
                        "true",
                        exact = true
                    )
                AccessibilityUtil.performClick(voiceSendCheckDesc)
            }
            if ("1" == message.videoSendFlag) {
                val videoSendTv = AccessibilityUtil.scrollAndFindByText(
                    WeworkController.weworkService,
                    getRoot(),
                    "踢发视频",
                    exact = true
                )
                val tvVideoSendCheck =
                    AccessibilityUtil.findBackNode(videoSendTv, minChildCount = 1)
                val videoSendCheckDesc =
                    AccessibilityUtil.findOnceByDesc(
                        tvVideoSendCheck,
                        "false",
                        "true",
                        exact = true
                    )
                AccessibilityUtil.performClick(videoSendCheckDesc)
            }
            if ("1" == message.fileSendFlag) {
                val fileSendTv = AccessibilityUtil.scrollAndFindByText(
                    WeworkController.weworkService,
                    getRoot(),
                    "踢发文件",
                    exact = true
                )
                val tvFileSendCheck =
                    AccessibilityUtil.findBackNode(fileSendTv, minChildCount = 1)
                val fileSendCheckDesc =
                    AccessibilityUtil.findOnceByDesc(
                        tvFileSendCheck,
                        "false",
                        "true",
                        exact = true
                    )
                AccessibilityUtil.performClick(fileSendCheckDesc)
            }
            if ("1" == message.cardSendFlag) {
                val cardSendTv = AccessibilityUtil.scrollAndFindByText(
                    WeworkController.weworkService,
                    getRoot(),
                    "踢发名片",
                    exact = true
                )
                val tvCardSendCheck =
                    AccessibilityUtil.findBackNode(cardSendTv, minChildCount = 1)
                val cardSendCheckDesc =
                    AccessibilityUtil.findOnceByDesc(
                        tvCardSendCheck,
                        "false",
                        "true",
                        exact = true
                    )
                AccessibilityUtil.performClick(cardSendCheckDesc)
            }
            if ("1" == message.nicknameCheckFlag && message.nicknameKeywordList != null) {
                val nicknameSendTv = AccessibilityUtil.scrollAndFindByText(
                    WeworkController.weworkService,
                    getRoot(),
                    "客户昵称包含以下关键词踢出群聊",
                    exact = true
                )
                val tvNicknameSendCheck =
                    AccessibilityUtil.findBackNode(nicknameSendTv, minChildCount = 1)
                val nicknameSendCheckDesc =
                    AccessibilityUtil.findOnceByDesc(
                        tvNicknameSendCheck,
                        "false",
                        "true",
                        exact = true
                    )
                AccessibilityUtil.performClick(nicknameSendCheckDesc)
                sleep(Constant.POP_WINDOW_INTERVAL)
                val nicknameKeywordSize = message.nicknameKeywordList.size
                val index = if (message.msgKeywordList == null) 0 else
                    message.msgKeywordList.size
                for (i in 0..nicknameKeywordSize - 1) {
                    val etList =
                        AccessibilityUtil.findAllByClazz(
                            getRoot(),
                            Views.EditText,
                            minSize = 2
                        )

                    AccessibilityUtil.editTextInput(
                        etList[index + i],
                        message.nicknameKeywordList.get(i)
                    )
                    if (i < nicknameKeywordSize - 1) {
                        val addNicknameKeywordListTv =
                            AccessibilityUtil.scrollAndFindByText(
                                WeworkController.weworkService,
                                getRoot(),
                                "添加昵称",
                                exact = true
                            )
                        AccessibilityUtil.performClick(addNicknameKeywordListTv)
                        sleep(Constant.POP_WINDOW_INTERVAL)
                    }
                }
            }

        }
        if ("1" == message.maxLengthFlag) {
            val nicknameSendTv = AccessibilityUtil.scrollAndFindByText(
                WeworkController.weworkService,
                getRoot(),
                "踢消息长度超过"
            )
            val tvNicknameSendCheck =
                AccessibilityUtil.findBackNode(nicknameSendTv, minChildCount = 1)
            val nicknameSendCheckDesc =
                AccessibilityUtil.findOnceByDesc(
                    tvNicknameSendCheck,
                    "false",
                    "true",
                    exact = true
                )
            AccessibilityUtil.performClick(nicknameSendCheckDesc)
            sleep(Constant.POP_WINDOW_INTERVAL)
            var index = if (message.msgKeywordList == null) 0 else
                message.msgKeywordList.size
            index += if (message.nicknameKeywordList == null) 0 else
                message.nicknameKeywordList.size
            val etList =
                AccessibilityUtil.findAllByClazz(
                    getRoot(),
                    Views.EditText,
                    minSize = 2
                )
            AccessibilityUtil.editTextInput(
                etList[index],
                message.msgMaxLength
            )
        }
        if ("1" == message.maxLineFlag) {
            val nicknameSendTv = AccessibilityUtil.scrollAndFindByText(
                WeworkController.weworkService,
                getRoot(),
                "踢消息换行超过"
            )
            val tvNicknameSendCheck =
                AccessibilityUtil.findBackNode(nicknameSendTv, minChildCount = 1)
            val nicknameSendCheckDesc =
                AccessibilityUtil.findOnceByDesc(
                    tvNicknameSendCheck,
                    "false",
                    "true",
                    exact = true
                )
            AccessibilityUtil.performClick(nicknameSendCheckDesc)
            sleep(Constant.POP_WINDOW_INTERVAL)
            var index = if (message.msgKeywordList == null) 0 else
                message.msgKeywordList.size
            index += if (message.nicknameKeywordList == null) 0 else
                message.nicknameKeywordList.size
            index += if ("1" == message.maxLengthFlag) 1 else
                0
            val etList =
                AccessibilityUtil.findAllByClazz(
                    getRoot(),
                    Views.EditText,
                    minSize = 2
                )
            AccessibilityUtil.editTextInput(
                etList[index],
                message.msgMaxLine
            )
        }
        if (null != message.timeInterval && null != message.msgNumInInterval) {
            val nicknameSendTv = AccessibilityUtil.scrollAndFindByText(
                WeworkController.weworkService,
                getRoot(),
                "秒内连续发送"
            )
            val tvNicknameSendCheck =
                AccessibilityUtil.findBackNode(nicknameSendTv, minChildCount = 1)
            val nicknameSendCheckDesc =
                AccessibilityUtil.findOnceByDesc(
                    tvNicknameSendCheck,
                    "false",
                    "true",
                    exact = true
                )
            AccessibilityUtil.performClick(nicknameSendCheckDesc)
            sleep(Constant.POP_WINDOW_INTERVAL)
            var index = if (message.msgKeywordList == null) 0 else
                message.msgKeywordList.size
            index += if (message.nicknameKeywordList == null) 0 else
                message.nicknameKeywordList.size
            index += if ("1" == message.maxLengthFlag) 1 else
                0
            index += if ("1" == message.maxLineFlag) 1 else
                0
            val etList =
                AccessibilityUtil.findAllByClazz(
                    getRoot(),
                    Views.EditText,
                    minSize = 2
                )
            AccessibilityUtil.editTextInput(
                etList[index],
                message.timeInterval
            )
            AccessibilityUtil.editTextInput(
                etList[index + 1],
                message.msgNumInInterval
            )
        }
        if ("1" == message.outsideSendFlag) {
            val outsideSendTv = AccessibilityUtil.scrollAndFindByText(
                WeworkController.weworkService,
                getRoot(),
                "禁止其他企业员工进群",
                exact = true
            )
            val tvOutsideSendCheck =
                AccessibilityUtil.findBackNode(outsideSendTv, minChildCount = 1)
            val outsideSendCheckDesc =
                AccessibilityUtil.findOnceByDesc(
                    tvOutsideSendCheck,
                    "false",
                    "true",
                    exact = true
                )
            AccessibilityUtil.performClick(outsideSendCheckDesc)
        }

        val settingKickTv = AccessibilityUtil.scrollAndFindByText(
            WeworkController.weworkService,
            getRoot(),
            "仅发警告",
            exact = true
        )
        AccessibilityUtil.performClick(settingKickTv)
        sleep(Constant.POP_WINDOW_INTERVAL)
        val setting = AccessibilityUtil.findOneByText(
            getRoot(),
            message.operateTypeName,
            exact = true
        )
        AccessibilityUtil.performClick(setting)
        sleep(Constant.POP_WINDOW_INTERVAL)
        val etList =
            AccessibilityUtil.findAllByClazz(
                getRoot(),
                Views.EditText,
                minSize = 2
            )

        if ("1" != message.operateType) {
            AccessibilityUtil.editTextInput(
                etList[etList.size - 2],
                message.alarmMsg
            )
        }
        if ("4" != message.operateType && "1" == message.addBlacklistFlag) {
            val addBlackTv = AccessibilityUtil.scrollAndFindByText(
                WeworkController.weworkService,
                getRoot(),
                "踢出后加入群聊黑名单",
                exact = true
            )
            val tvAddBlackCheck =
                AccessibilityUtil.findBackNode(addBlackTv, minChildCount = 1)
            val addBlackCheckDesc =
                AccessibilityUtil.findOnceByDesc(
                    tvAddBlackCheck,
                    "false",
                    "true",
                    exact = true
                )
            AccessibilityUtil.performClick(addBlackCheckDesc)
            sleep(Constant.POP_WINDOW_INTERVAL)
        }
        AccessibilityUtil.editTextInput(
            etList[etList.size - 1],
            message.name
        )
        val complete = AccessibilityUtil.findOneByText(
            getRoot(),
            "完成",
            exact = true
        )
        AccessibilityUtil.performClick(complete)
        uploadCommandResult(
            message,
            ExecCallbackBean.SUCCESS,
            "",
            System.currentTimeMillis()
        )
        return true
    }

    fun switchWeCom(message: WeworkMessageBean): Boolean {
        Utils.getApp().packageManager.getLaunchIntentForPackage(Constant.PACKAGE_NAMES)
            ?.apply {
                this.flags = Intent.FLAG_ACTIVITY_NEW_TASK
                startActivity(this)
                sleep(Constant.POP_WINDOW_INTERVAL)
                // 查找并点击第一个应用
                val rootNode = WeworkController.weworkService.rootInActiveWindow
                var aa = AccessibilityUtil.findAllByClazz(rootNode, Views.ImageView)
                val firstAppNode: AccessibilityNodeInfo = if (message.weCom == 1) {
                    AccessibilityUtil.findAllByClazz(rootNode, Views.ImageView).firstOrNull()!!
                } else {
                    AccessibilityUtil.findAllByClazz(rootNode, Views.ImageView).lastOrNull()!!
                }
                AccessibilityUtil.performClick(firstAppNode)
                SPUtils.getInstance().put("weCom", message.weCom)
                WeworkController.weworkService.webSocketManager.send(
                    WeworkMessageBean(
                        WeworkMessageBean.WE_COM_TYPE,
                        SPUtils.getInstance().getInt("weCom"),
                        null,
                        null
                    )
                )
                return true
            }
        return false
    }

    fun init(message: WeworkMessageBean): Boolean {
        if (message.weworkSchema != SPUtils.getInstance().getString("weworkSchema")) {
            SPUtils.getInstance().put("weworkSchema", message.weworkSchema)
            IWWAPIUtil.init()
        }
        WeworkController.enableLoopRunning = true
        uploadCommandResult(
            message,
            ExecCallbackBean.SUCCESS,
            "",
            System.currentTimeMillis()
        )
        return true
    }
}