<template>
  <div class="main">
    <el-scrollbar class="left"> <!-- 左边栏 -->
      <LeftToolbar :buttons="buttons" :active-key="activeKey" :is-locked="isLocked" @click="handleBtnClick" />
      <el-button style="position: absolute;left: 20px; bottom: 20px;" @click="showHostDlg = true">执行主播库</el-button>
    </el-scrollbar>
    <!-- 中间手机区域 -->
    <div class="content" @click.self="selectedDevice = 999">
      <div class="video-container" @click.self="selectedDevice = 999" v-for="(device, index) in deviceInformation"
        :key="device.udid" @mouseup="(e) => handleCanvasup(device.udid, e, index)">
        <div class="video-canvas">
          <video :ref="(el) => (videoElement[device.udid] = el)" autoplay muted playsinline
            :style="getVideoStyle(index)" @click.stop="selectedDevice = index"></video>
          <canvas class="canvas" v-show="selectedDevice == index" :ref="(el) => (canvasRef[device.udid] = el)"
            @mousemove.stop="(e) => handleMouseMove(device.udid, e, index)"
            @mousedown.stop="(e) => handleCanvasdown(device.udid, e, index)" :style="{
              transform: getTransformStyle(index)
            }">
          </canvas>
        </div>
        <div class="input-info" v-show="selectedDevice == index"
          :style="{ left: phone.width * 1.4 + 4 + '0px', transform: getTransformStyle(index), }">

          <div class="app-button" @click="resetApp(device.udid, index)">重置应用</div>
          <div class="app-button"
            @click="wsActions.clickCopyList(device.udid, index); openShowChat = true; istranslate = true">
            翻译本页对话</div>
          <div class="app-button" @click="wsActions.clickCopyList(device.udid, index); openShowChat = true;">
            回复消息</div>
          <!-- <div class="app-button" @click="wsActions.getSize(device.udid, index)">获取屏幕尺寸</div> -->

          <div class="app-button" @click="wsActions.test(device.udid, index)">打印ui节点树</div>
          <!-- <div class="app-button" @click="wsActions.isOneLive(device.udid, index)">判断单人还是双人</div>  -->
          <div class="app-button" @click="wsActions.slideDown(device.udid, index)">下滑</div>
          <div class="app-button" @click="wsActions.killNow(device.udid, index)">关闭当前应用</div>
          <div class="app-button" @click="chooseFile(device.udid, index, 1, wsActions)">安装 APK
            文件</div>
          <div class="app-button" @click="chooseFile(device.udid, index, 2, wsActions)">
            传送文件</div>
          <div style="display: flex;">
            <input style="border: 1px solid #000;margin:0px 14px;" v-model="textContent[index]" type="text"></input>
            <div class="app-button" style="margin: 0px;height: 40px;width: 60px;font-size: 14px;"
              @click="setComText(index)">发送
            </div>
          </div>
          <!-- <div class="app-button" @click="wsActions.isHost(device.udid, index)">一键养号</div> -->
        </div>
      </div>
    </div>
    <div class="right" @click.self="selectedDevice = 999">
      <div style="margin: 14px;"></div>
      <ChatDialog :visible="openShowChat" :messages="chatList" />
    </div>
    <MultiLineInputDialog v-model:visible="showDialog" :initialText='""' :title="dialogTitle" :index="selectedDevice"
      @confirm="onDialogConfirm" @cancel="stop" />
    <HostListManagerDialog v-model:visible="showHostDlg" @save="onHostSaved" />
  </div>
</template>

<script setup>
import { ref, onMounted, computed, onUnmounted, onBeforeUnmount, watch, inject, nextTick } from "vue";
import VideoConverter from "h264-converter";
import { useRouter } from 'vue-router';
import {
  setphoneXYinfo, getphoneXYinfo, getUser,
  getHostList, setHostList, addToHostList, getContentpriList,
  setContentpriList, getContentList, setContentList,
  setsessionId, getsessionId
} from '@/stores/storage'
import { toBufferBtn, stringToUtf8ByteArray, getClipboard, setClipboard, bufferToString, startsWithHeader, trimLongArray, base64ToBinary, toBuffer } from '@/utils/bufferUtils';
import { createWsActions } from '@/utils/wsActions';
import { ElMessage, ElMessageBox, ElLoading } from 'element-plus'
import { chat, translationToChinese, translation } from "@/api/chat";
import { update } from '@/api/account';   //更新主播信息
import MultiLineInputDialog from '@/components/MultiLineInputDialog.vue'; // 根据实际路径修改
import ChatDialog from '@/components/ChatDialog.vue'
// import { splitArray } from '@/utils/arrUtil'  //分割数组  分配主播 已废弃
import { chooseFile } from '@/utils/fileUtil'
import { connectSSE } from '@/utils/sseUtils'
import { prologue, comment } from '@/api/account';
import { createTaskQueue } from '@/composables/useTaskQueue'    //创建任务
import { useCanvasPointer } from '@/composables/useCanvasPointer'   //canvas 初始化 点击转换
import { attachTrimmerForIndex } from '@/composables/useVideoStream'  //修剪器
import HostListManagerDialog from '@/components/HostListManagerDialog.vue'
import { useMonitor } from '@/composables/useMonitor'
import { useTeardown } from '@/composables/useTeardown'     //销毁
import LeftToolbar from '@/components/LeftToolbar.vue' //左侧工具栏
import { useStreams } from '@/composables/useStreams' //视频流处理
import { useDeviceDiscovery } from '@/composables/useDeviceDiscovery' //设备发现
import { useTouch } from '@/composables/useTouch' //触摸事件
const router = useRouter();
let wsActions = null;
let userdata = getUser();
// 引入刷新方法
const reloadPage = inject("reload")

let phone = ref({ width: 207, height: 470 });
const openStr = base64ToBinary("ZQBwAAAAAAA8CgLQAtAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA");  //开启视频流的启动命令
const eitwo = base64ToBinary("BAIAAABHVFJD");         //开启设备信息的命令
let isshow = ref(true);                   //页面是否隐藏
let playTimer = ref([{}, {}, {}, {}, {}, {}, {}, {}]); // 播放定时器
let isdown = ref(false);             //是否是按下鼠标状态
const videoElement = ref({});       //视频流元素DOM
let deviceInformation = ref([]);    //设备信息列表
//当前弹窗类型
let dialogTitle = ref('');
//评论文本内容
let textContent = ref(['', '', '', '', '', '', '', '']);
let textContentArr = ref([[], [], [], [], [], [], [], [], []]);
//当前主播id内容
let hostIdArr = ref([{}, {}, {}, {}, {}, {}, {}, {}]);
// let hostIdContentArr = ref([[], [], [], [], [], [], [], [], []]);
//私信文本内容
let textContentpri = ref(['', '', '', '', '', '', '', '']);
let textContentpriArr = ref([[], [], [], [], [], [], [], [], []]);
//保存聊天内容
let chatList = ref([]);
//保存爬虫发送的主播信息 待存缓存
let stroageHost = ref([]);
//选中设备
let selectedDevice = ref(999);
//ws列表
let wslist = [];
// 是否停止
let isStop = ref(false);

//sse弹窗是否存在  
let isMsgPop = ref(false);
//播放器列表
let instanceList = [{}, {}, {}, {}, {}, {}, {}, {}];
//是否是在关注主播
let runType = ref('');
//屏幕尺寸系数
let isMonitor = ref(false);
let iponeCoefficient = ref([{ width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }, { width: 1, height: 1 }]);
//是否是发送的内容
let isSend = ref(false)
//弹窗是否显示
let showDialog = ref(false);
//监听消息定时器
let isShowMes = ref();
//给ws-scrcpy发送的数据格式
const mouseData = {
  type: 2,
  action: 0,
  pointerId: 0,
  position: {
    point: { x: 0, y: 0 },
    screenSize: { width: 320, height: 720 },
  },
  pressure: 1,
  buttons: 1,
};
//打开聊天窗口的状态
let openShowChat = ref(true);
let istranslate = ref(false); //是否是翻译本页
let phoneXYinfo = ref(getphoneXYinfo() == null ? [{}, {}, {}, {}, {}, {}, {}, {}] : getphoneXYinfo());

const isMonitorOn = ref(false) // false 表示关闭，true 表示开启
// 这四个互斥模式的 key，和你的 runType 对应
const EXCLUSIVE_KEYS = ['brushLive', 'like', 'follow', 'listen'];

// 映射一下中文名，仅用于提示
const KEY_LABEL = {
  brushLive: '刷直播',
  like: '刷视频',
  follow: '一键关注并打招呼',
  listen: '监测消息',
};
const showHostDlg = ref(false)
function onHostSaved(list) {
  console.log('保存后的 HostList:', list)
}
// 当前激活的互斥 key（runType 里只要是这四个之一就视为锁定）
const activeKey = computed(() => EXCLUSIVE_KEYS.includes(runType.value) ? runType.value : '');

// 是否处于锁定（有激活模式）
const isLocked = computed(() => !!activeKey.value);

// 尝试激活某个模式（带拦截、可二次点击退出）
function tryActivate(key, runner) {
  // 其它模式在运行，阻止切换
  if (activeKey.value && activeKey.value !== key) {
    ElMessage.warning(`当前正在【${KEY_LABEL[activeKey.value]}】。请先点击“全部停止”或再次点击当前红色按钮停止。`);
    return;
  }
  // 二次点击同一按钮 => 视为停止
  if (activeKey.value === key) {
    stop();   // 你已有的停止方法，会把 runType 置空并清理状态
    return;
  }
  // 设置 runType 并跑逻辑
  runType.value = key;
  if (typeof runner === 'function') runner();
}

// 供模板使用：是否为激活按钮
function isActive(btn) {
  return !!btn.key && activeKey.value === btn.key;
}

// 供模板使用：是否应禁用
function isDisabled(btn) {
  // 只禁用互斥组内的按钮；非互斥按钮（刷新/重置/登出等）不受影响
  return !!btn.key && isLocked.value && activeKey.value !== btn.key && EXCLUSIVE_KEYS.includes(btn.key);
}

// 统一处理点击，拦截禁用状态
function handleBtnClick(btn) {
  if (isDisabled(btn)) return;
  if (typeof btn.onClick === 'function') btn.onClick();
}
// 你可以用这种方式声明按钮们
const buttons = [
  {
    label: '刷新',
    onClick: () => reload({ onlySelected: selectedDevice.value !== 999, hard: true }),
    show: () => true,
    img: {
      normal: new URL('@/assets/video/leftBtn1.png', import.meta.url).href,
      hover: new URL('@/assets/video/leftBtn1-1.png', import.meta.url).href
    }
  },
  {
    label: '打开tiktok',
    onClick: () => openTk(),
    show: () => true,
    img: {
      normal: new URL('@/assets/video/leftBtn2.png', import.meta.url).href,
      hover: new URL('@/assets/video/leftBtn2-2.png', import.meta.url).href
    }
  },
  {
    label: '重置tiktok',
    onClick: () => resetTk(),
    show: () => true,
    img: {
      normal: new URL('@/assets/video/leftBtn3.png', import.meta.url).href,
      hover: new URL('@/assets/video/leftBtn3-3.png', import.meta.url).href
    }
  },
  {
    label: '刷直播',
    key: 'brushLive',
    onClick: () => tryActivate('brushLive', () => {
      runType.value = 'brushLive';
      brushLive();
    }),
    show: () => true,
    img: {
      normal: new URL('@/assets/video/leftBtn4.png', import.meta.url).href,
      hover: new URL('@/assets/video/leftBtn4-4.png', import.meta.url).href
    },
    style: () => ({ backgroundColor: isActive({ key: 'brushLive' }) ? 'red' : '' })
  },
  {
    label: '刷视频',
    key: 'like',
    onClick: () => tryActivate('like', () => {
      runType.value = 'like';
      parentNum();
    }),
    show: () => true,
    img: {
      normal: new URL('@/assets/video/leftBtn5.png', import.meta.url).href,
      hover: new URL('@/assets/video/leftBtn5-5.png', import.meta.url).href
    },
    style: () => ({ backgroundColor: isActive({ key: 'like' }) ? 'red' : '' })
  },
  {
    label: '一键关注并打招呼',
    key: 'follow',
    onClick: () => tryActivate('follow', () => {
      runType.value = 'follow';
      showDialog.value = true;
      dialogTitle.value = '主播ID';
      selectedDevice.value = 999;
    }),
    show: () => true,
    img: {
      normal: new URL('@/assets/video/leftBtn6.png', import.meta.url).href,
      hover: new URL('@/assets/video/leftBtn6-6.png', import.meta.url).href
    },
    style: () => ({ backgroundColor: isActive({ key: 'follow' }) ? 'red' : '' })
  },
  {
    label: '监测消息',
    key: 'listen',
    onClick: () => tryActivate('listen', () => {
      isMonitorOn.value = true;
      openMonitor();
    }),
    show: () => true,
    img: {
      normal: new URL('@/assets/video/leftBtn1.png', import.meta.url).href,
      hover: new URL('@/assets/video/leftBtn1-1.png', import.meta.url).href
    },
    style: () => ({ backgroundColor: isActive({ key: 'listen' }) ? 'red' : '' })
  },
  {
    label: '全部停止',
    onClick: () => stop(),
    show: () => true,
    img: {
      normal: new URL('@/assets/video/leftBtn8.png', import.meta.url).href,
      hover: new URL('@/assets/video/leftBtn8-8.png', import.meta.url).href
    }
  },
  {
    label: '登出',
    onClick: () => {
      td.disposeAll('logout')
      router.push('/')
    },
    show: () => true,
    img: {
      normal: new URL('@/assets/video/leftBtn9.png', import.meta.url).href,
      hover: new URL('@/assets/video/leftBtn9-9.png', import.meta.url).href
    }
  }
]
//返回上一层
const Back = (udid, index) => {
  wslist[index].send(toBufferBtn({ "type": 0, "action": 0, "keycode": 4, "metaState": 0, "repeat": 0 }));
  wslist[index].send(toBufferBtn({ "type": 0, "action": 1, "keycode": 4, "metaState": 0, "repeat": 0 }));
}
//返回首页
const Home = (udid, index) => {
  wslist[index].send(toBufferBtn({ "type": 0, "action": 0, "keycode": 3, "metaState": 0, "repeat": 0 }));
  wslist[index].send(toBufferBtn({ "type": 0, "action": 1, "keycode": 3, "metaState": 0, "repeat": 0 }));
}
//任务视图
const Overview = (udid, index) => {
  wslist[index].send(toBufferBtn({ "type": 0, "action": 0, "keycode": 187, "metaState": 0, "repeat": 0 }));
  wslist[index].send(toBufferBtn({ "type": 0, "action": 1, "keycode": 187, "metaState": 0, "repeat": 0 }));
}

// 建立 monitor
const {
  isPausedByIndex,
  pauseMonitorByIndex,
  resumeMonitorByIndex,
  openMonitor,
  closeMonitor,
  stopAll,
  resumeAndKick,
} = useMonitor({
  deviceInformation,
  runType,
  isStop,
  isMonitorOn,
  isShowMes,
  wsActionsRef: () => wsActions,   // wsActions 是你 onopen 里创建的
});



// 放在变量都已声明之后（要能拿到 phone、toBuffer、wslist）
const { canvasRef, frameMeta, initCanvas, getCanvasCoordinate, sendPointer } =
  useCanvasPointer({
    phone,                      // 你已有的 ref({ width, height })
    toBuffer,                   // 你已有的工具函数
    getWs: (i) => wslist[i]     // 取对应 index 的 WebSocket
  });
const { sleep, tapAt, longPressAt, drag, clickxy } = useTouch({
  deviceInformation,
  sendPointer,
  wsActionsRef: () => wsActions,
  phoneXYinfoRef: phoneXYinfo,
  Back,
})

// —— 放在变量区（deviceInformation 已经是 ref([])）——
const pausedDevices = new Set(); // 用 UDID 做键



const wsCache = new Map();

const td = useTeardown({
  deviceInformation,
  wslist,
  instanceList,
  videoElement,
  canvasRef,
  playTimer,
  isShowMes,
  wsCache,
  createTaskQueue,
  stopAll, // useMonitor 里的
  removeDocListeners: () => {
    document.removeEventListener('visibilitychange', handleVisibilityChange);
  }
})

const { feedState, pushFrame, resetFeedState, waitForVideoEl, refreshStream } = useStreams({
  instanceList,
  videoElement,
  wslist,
  openStr,
  VideoConverter, // 传入页面已引入的构造器，避免在 composable 重复引入
})


//````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````
// 初始化 手机显示WebSocket 和视频流
const initVideoStream = async (udid, index) => {
  //````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````
  // 1. 检查缓存中是否已有实例
  if (wsCache.has(udid)) {
    const cached = wsCache.get(udid);
    if (cached?.ws?.readyState === WebSocket.OPEN) {
      return cached.ws;
    }
    // 如果连接已关闭，清除缓存并重新创建
    wsCache.delete(udid);
  }

  // 等待 <video> 元素挂载
  const el = await waitForVideoEl(udid);
  if (!el) {
    console.error('[initVideoStream] video element not ready for', udid);
    return;
  }

  // 准备容器
  instanceList[index] = { converter: null, timer: null };
  //````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````
  if (!videoElement.value) return;
  if (!videoElement.value?.[udid]) {
    console.warn('video element missing for', udid);
    return; // 不创建 converter，避免传 null 进去
  }
  // 1. 创建 h264-converter 实例
  instanceList[index].converter = new VideoConverter(videoElement.value[udid], 60, 1);
  // 2. 连接 WebSocket
  wslist[index] = new WebSocket(
    `ws://127.0.0.1:8000/?action=proxy-adb&remote=tcp%3A8886&udid=${udid}`
  );
  wslist[index].binaryType = "arraybuffer";
  attachTrimmerForIndex(instanceList, videoElement, deviceInformation, index, 10, 2000);  // 挂上修剪器
  wslist[index].onopen = () => {
    console.log("手机显示ws已开启");
    wsActions = createWsActions(wslist);
    // 发送 开启 视频流数据
    setTimeout(() => {
      wslist[index].send(openStr);
    }, 300);
    wsCache.set(udid, { ws: wslist[index], index });
  };
  const magicSize = stringToUtf8ByteArray('scrcpy_message');
  // 3. 处理接收到的二进制数据
  wslist[index].onmessage = (event) => {

    //判断返回的如果是字符串为自定义返回
    if (typeof event.data == 'string') {
      if (isStop.value) {
        createTaskQueue(index).clear();//清除队伍中的任务
        return;
      }
      const resData = JSON.parse(event.data)
      //成功处理
      console.log('自定义返回', resData)
      if (resData.status === 'success') {
        //触发长按该位置
        if (resData.type == 'clickCopy') {
          console.log('长按', resData.x * iponeCoefficient.value[index].width, resData.y * iponeCoefficient.value[index].height, index)
          clickxy(resData.x * iponeCoefficient.value[index].width, resData.y * iponeCoefficient.value[index].height, index, 9) //index为9的时候长按
          setTimeout(() => {
            wsActions.clickCopyText(resData.device, index)
          }, 1500);
        } else if (resData.type == 'getmesNum') {
          if (resData.message == 0) {
            console.log('没有消息')
            if (runType.value == 'follow') {
              LikesToLikesToLikes(deviceInformation.value[index].udid, index)

            }
            //如果检测到有新消息，会收到两条ws回复，一条message==1 一条message==成功
          } else if (resData.message == 1) {
            console.log('有消息')
            pauseMonitorByIndex(index); // 新增：暂停该设备的轮询
          } else if (resData.message == '点击成功') {
            console.log('双击', resData.x, resData.y, index)
            console.log('双击', resData.x * iponeCoefficient.value[index].width, resData.y * iponeCoefficient.value[index].height, index)
            setTimeout(() => {
              clickxy(resData.x * getphoneXYinfo()[index].width, resData.y * getphoneXYinfo()[index].height, index)
              setTimeout(() => {
                clickxy(resData.x * getphoneXYinfo()[index].width, resData.y * getphoneXYinfo()[index].height, index) //index为9的时候长按
                wsActions.clickSysMesage(deviceInformation.value[index].udid, index) //点击消息进入对话框
              }, 100)

            }, 2000)
          }
        } else if (resData.type == 'clickMesage') {
          //点击进入新消息页面以后，获取页面信息
          wsActions.clickCopyList(deviceInformation.value[index].udid, index)
        } else if (resData.type == 'clickSysMesage') {
          setTimeout(() => {
            Back('', index)
            setTimeout(() => {
              Back('', index)
              if (runType.value == 'follow') {
                LikesToLikesToLikes(deviceInformation.value[index].udid, index)
              }
              // 仅监听模式下恢复
              if (runType.value === 'listen' || isMonitorOn.value) {
                resumeMonitorByIndex(index);
                // 轻微延迟后立刻补一次检测
                setTimeout(() => {
                  const udid = deviceInformation.value[index]?.udid;
                  if (udid) wsActions.getmesNum(udid, index);
                }, 1500);
              }
            }, 1000)
          }, 1000)

        } else if (resData.type == 'isVideoAndLive') {
          console.log(resData.message)
        } else if (resData.type == 'clickCopyList') { //获取到的消息列表
          //打印所有信息
          console.log('消息列表', resData.message)
          chatList.value = resData.message
          getTranslation(chatList.value)
          const mesBox = resData.message[resData.message.length - 1]
          //打印最新一条信息
          console.log('最新消息', mesBox)
          console.log("翻译", istranslate.value)
          if (istranslate.value == false) {
            if (mesBox.position == 'right') {
              Back('', index)
              setTimeout(() => {
                Back('', index)
              }, 1000)
              return
            }
            openShowChat.value = true
            console.log("执行ai")

            chat({ msg: mesBox.text }).then(res => {
              console.log("ai返回", res)
              textContentpri.value[index] = res.result
              PrivatetexToPrivatePush(deviceInformation.value[index].udid, index)
            })

          } else {
            console.log("翻译本页")
            istranslate.value = false
          }
        } else if (resData.action == 'getSize') {
          // console.log(iponeCoefficient.value, '手机尺寸宽度：', resData.width, '高度：', resData.height);
          const RAW_W = Math.max(1, resData.width || 0);
          const RAW_H = Math.max(1, resData.height || 1);

          // 目标高度固定 720，按比例缩放宽
          const TARGET_H = 720;
          const ratio = TARGET_H / RAW_H;
          const scaledWFloat = RAW_W * ratio;
          const scaledH = TARGET_H;

          // 只向下对齐（floor）。要 32 对齐就把 ALIGN 改 32
          const ALIGN = 16;
          const downAlign = (x, a) => Math.max(a, Math.floor(x / a) * a);
          const scaledW = downAlign(scaledWFloat, ALIGN);

          // 1) 给后续发送 pointer 用的 screenSize（服务端就按这个坐标系解释 point）
          mouseData.position.screenSize.width = scaledW;
          mouseData.position.screenSize.height = scaledH;

          // 2) 保存“对齐后的尺寸”，用于坐标换算等
          frameMeta.value[resData.device] = {
            w: scaledW,
            h: scaledH,
            rotation: 0,
          };

          // 3) 你代码里很多地方用 resData.x * iponeCoefficient，把它同步到 320×720 逻辑坐标
          //    这样 UI 节点坐标（原始帧坐标） -> 320×720 逻辑坐标
          // iponeCoefficient.value[index].width = 320 / scaledW;
          // iponeCoefficient.value[index].height = 720 / scaledH;
          iponeCoefficient.value[index].width = scaledW / resData.width
          iponeCoefficient.value[index].height = scaledH / resData.height
          console.log(index)
          phoneXYinfo.value[index].width = scaledW / resData.width
          phoneXYinfo.value[index].height = scaledH / resData.height
          console.log(
            `[getSize] raw=${RAW_W}x${RAW_H} -> scaled=${scaledW}x${scaledH} (align↓${ALIGN}) ${iponeCoefficient.value[index].width} ${iponeCoefficient.value[index].height}`
          );
        } else {
          console.log(resData.type, '坐标返回：x:', resData.x, 'y:', resData.y);
        }

        phoneXYinfo.value[index].id = resData.device
        if (resData.type == 'Likes') {//判断是否是 点赞
          phoneXYinfo.value[index].Likes = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
          if (runType.value == 'follow') {
            wsActions.slideDown(deviceInformation.value[index].udid, index)//是否继续下一个视频
          }
        } else if (resData.type == 'Comment') {//打开评论
          phoneXYinfo.value[index].Comment = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
        } else if (resData.type == 'CommentText') {//复制评论
          phoneXYinfo.value[index].CommentText = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
          textContent.value[index] = resData.message
        } else if (resData.type == 'Comtext') {//评论输入
          phoneXYinfo.value[index].Comtext = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
        } else if (resData.type == 'ComPush') {//评论发送
          phoneXYinfo.value[index].ComPush = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
          setTimeout(() => {
            Back('', index)
            if (runType.value == 'follow') {
              setTimeout(() => {
                Back('', index)
              }, 1000)
            } else {
              setTimeout(() => {
                wsActions.slideDown(deviceInformation.value[index].udid, index)//是否继续下一个视频
                setTimeout(() => {
                  console.log('观看视频中')
                  randomSeeVideo(deviceInformation.value[index].udid, index)  //50秒后继续循环任务
                }, 1000);
              }, 1000)
            }
          }, 800)
        } else if (resData.type == 'tomy') {//打开主页
          phoneXYinfo.value[index].tomy = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
        } else if (resData.type == 'Attention') {//关注、打开私信
          phoneXYinfo.value[index].Attention = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
          // LikesToCommentToComPush(deviceInformation.value[index].udid, index)  //是否继续循环任务
        } else if (resData.type == 'return') {//私信评论
          phoneXYinfo.value[index].return = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
        } else if (resData.type == 'addHost') {//添加关注
          phoneXYinfo.value[index].addHost = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
          wsActions.slideDown(deviceInformation.value[index].udid, index)//是否继续下一个视频
          setTimeout(() => {
            wsActions.isHost(deviceInformation.value[index].udid, index)//检测
          }, 1000);
        } else if (resData.type == 'Privatetex') {//私信评论
          phoneXYinfo.value[index].Privatetex = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
        } else if (resData.type == 'PrivatePush' || resData.type == 'PrivatePushFollow') {//私信发送
          phoneXYinfo.value[index].PrivatePush = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
          setTimeout(() => {
            Back('', index);
            setTimeout(() => {
              Back('', index);
              setTimeout(() => {
                Back('', index);
                setTimeout(() => {
                  if (resData.type == 'PrivatePush') {
                    Back('', index);
                    setTimeout(() => {
                      Back('', index);
                      setTimeout(() => {
                        Back('', index);
                        if (isMonitor.value) {
                          //正常没有消息，发送完私信以后，返回六次，然后继续下一个任务
                          wsActions.getmesNum(deviceInformation.value[index].udid, index)
                        } else {
                          LikesToLikesToLikes(deviceInformation.value[index].udid, index)
                        }


                      }, 1000);
                    }, 1000);
                  } else if (resData.type == 'PrivatePushFollow') {
                    //如果有新消息，回复完私信以后，返回三次，然后继续下一个任务
                    // wsActions.getmesNum(deviceInformation.value[index].udid, index)
                    // LikesToLikesToLikes(deviceInformation.value[index].udid, index)

                    if (runType.value === 'listen' || isMonitorOn.value) {
                      resumeAndKick(index); // ← 一步到位：恢复并在 1.5s 后补一次 getmesNum
                    }

                  }

                }, 1000);
              }, 1000);
            }, 1000);
          }, 1000);

        } else if (resData.type == 'clickCopy') {//点击复制
          phoneXYinfo.value[index].clickCopy = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
        } else if (resData.type == 'hostVideo') {//观看主播视频
          phoneXYinfo.value[index].hostVideo = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
        } else if (resData.type == 'isHost') {//视频关注主播
          phoneXYinfo.value[index].isHost = { x: resData.x * iponeCoefficient.value[index].width, y: resData.y * iponeCoefficient.value[index].height }
          if (resData.message == 0) {
            console.log('无关注', index)
            Back(deviceInformation.value[index].udid, index)
            setTimeout(() => {
              console.log('观看视频中', index)
              randomSeeVideo(deviceInformation.value[index].udid, index)  //30-50秒后继续循环任务
            }, 1000);
          } else if (resData.message == 1) {
            console.log('有关注', index)
            const randomNum = Math.random(); // 生成一个0到1之间的随机数
            //是否点赞评论的概率
            if (randomNum < 0.07) {
              console.log('进行点赞评论', index)
              LikesToCommentToComPush(deviceInformation.value[index].udid, index)
            } else {
              console.log('下一个', index)
              wsActions.slideDown(deviceInformation.value[index].udid, index)//是否继续下一个视频
              randomSeeVideo(deviceInformation.value[index].udid, index)  //30-50秒后继续循环任务
            }
          }
        } else if (resData.type == 'openDY') {//视频关注主播
          createTaskQueue(index).clear();//清除队伍中的任务
        } else if (resData.type == 'toLive') {//打开直播

          wsActions.isHead(deviceInformation.value[index].udid, index)//判断直播

        } else if (resData.type == 'isHead') {//判断有没有头像
          if (resData.message == 1) {
            wsActions.isOneLive(deviceInformation.value[index].udid, index)//判断直播
          } else {
            return
          }

        } else if (resData.type == 'isOneLive') {//判断单人还是双人
          if (resData.message == 0) {
            wsActions.slideDown(deviceInformation.value[index].udid, index)//是否继续下一个视频
            wsActions.isHead(deviceInformation.value[index].udid, index)//判断直播
            return
          }
          // 用法：
          (async () => {
            const result = await randomDelayAndExecute();
            if (runType.value !== 'brushLive') {
              return
            }
            //30%概率
            if (result) {

              let count = 0;
              const num = Math.floor(Math.random() * 31) + 5;
              const interval = setInterval(() => {
                if (count >= num) {
                  clearInterval(interval);
                  wsActions.slideDown(deviceInformation.value[index].udid, index)//是否继续下一个视频
                  wsActions.isHead(deviceInformation.value[index].udid, index)//判断直播

                  return;
                }
                clickxy(
                  resData.x * iponeCoefficient.value[index].width,
                  resData.y * iponeCoefficient.value[index].height,
                  index
                )
                count++;
              }, 300);
              return;
            } else {
              wsActions.slideDown(deviceInformation.value[index].udid, index)//是否继续下一个视频
              wsActions.isHead(deviceInformation.value[index].udid, index)//判断直播
              return
            }
          })();

        }

        setphoneXYinfo(phoneXYinfo.value)
        if (resData.type != 'isHost') {
          if (resData.type == 'hostVideo' || resData.type == 'Likes') {
            setTimeout(() => {
              createTaskQueue(index).next(); // 继续队列中下一个任务
            }, 5000)
          } else if (resData.type == 'getmesNum') {

          } else {
            createTaskQueue(index).next(); // 继续队列中下一个任务
          }
        }
      } else {
        // ----------------------------------------------------------------------------------------------------报错处理
        //如果该视频无法被评论,或者没有评论，返回刷下一条视频
        if (resData.type == 'Comtext' || resData.type == 'CommentText') {
          if (runType.value == 'follow') {

            Back('', index)
            setTimeout(() => {
              Back('', index)
              createTaskQueue(index).next(); // 继续队列中下一个任务
              createTaskQueue(index).next(); // 继续队列中下一个任务
            }, 1000)
          } else {
            resetApp(udid, index)
            setTimeout(() => {
              wsActions.isHost(deviceInformation.value[index].udid, index)
            }, 1000)
          }
          //如果该视频无法被搜索到，返回刷下一条视频
        } else if (resData.type == 'toHost') {
          Back('', index)
          setTimeout(() => {
            Back('', index)
            createTaskQueue(index).clear();//清除队伍中的任务
            setTimeout(() => {
              Back('', index)
              LikesToLikesToLikes(deviceInformation.value[index].udid, index)
            }, 1000)
          }, 1000)
        } else if (resData.type == 'PrivatePush' || resData.type == 'Privatetex' || resData.type == 'hostVideo' || resData.type == 'search' || resData.type == 'Attention' || resData.type == 'Comment') {
          if (runType.value == 'follow') {
            //关注的时候出现无法私信和没有视频的情况  错误重置
            resetApp(udid, index)
            setTimeout(() => {
              if (isMonitor.value) {
                //正常没有消息，发送完私信以后，返回六次，然后继续下一个任务
                wsActions.getmesNum(deviceInformation.value[index].udid, index)
              } else {
                LikesToLikesToLikes(deviceInformation.value[index].udid, index)
              }
              // LikesToLikesToLikes(deviceInformation.value[index].udid, index)
            }, 1000)
          }

        } else if (resData.type == 'getmesNum') {
          if (runType.value == 'follow') {
            LikesToLikesToLikes(deviceInformation.value[index].udid, index)
          }
          //getmesNum出现没有消息的情况
        } else if (resData.type == 'clickMesage' || resData.type == 'ComPush') {
          //ComPush关注主播的时候出现无法评论的视频  会跳过评论发送，不处理评论发送的返回错误
        } else if (resData.type == 'clickCopyList') {
          //如果无法获取到聊天记录，返回继续检测
          console.error('未找到聊天，返回')
          Back('', index)

        } else if (resData.type == 'clickSysMesage') {
          //如果没有系统消息，则点击新消息
          wsActions.clickMesage(deviceInformation.value[index].udid, index) //点击消息进入对话框
        } else {
          console.error(resData.message, resData.type); // 错误处理
          ElMessage.error(resData.message);
          createTaskQueue(index).clear();//清除队伍中的任务
        }
        // createTaskQueue(index).next(); // 继续队列中下一个任务
      }
    } else {
      const buf = event.data;                // ArrayBuffer
      const view = new Uint8Array(buf);      // 只创建视图，不复制

      // 粘贴板消息头判断（FIX: 用 view，别用未定义的 data）
      if (startsWithHeader(magicSize, view)) {
        if (!isSend.value) {
          const payload = trimLongArray(view, magicSize);
          const paste = bufferToString(payload);
          console.log('获取粘贴板内容', paste);
        }
        return; // 这类消息不走视频通道
      }

      // 视频流
      if (instanceList[index].converter && isshow.value) {
        pushFrame(index, buf);               //处理视频流帧
      }
    }



  };
  // 4. 错误处理
  wslist[index].onerror = (error) => {
    wsCache.delete(udid); // 错误时清理缓存
  };
  //``````````````````````````````````````````````````````````````````````````````````
  wslist[index].onclose = (event) => {
    wsCache.delete(udid)// 自动清理缓存
    clearInterval(instanceList[index].timer); // 清理定时器// 移除缓存
  };
  //``````````````````````````````````````````````````````````````````````````````````
};

const { open: openDiscovery } = useDeviceDiscovery({
  deviceInformation,
  initCanvas,
  initVideoStream,
  wsActionsRef: () => wsActions,
  td
})

// 鼠标按下事件处理
const handleCanvasdown = (udid, e, index) => {
  const { x, y } = getCanvasCoordinate(e, udid);
  isdown.value = true;
  sendPointer(udid, index, 0, x, y);
  setTimeout(() => { selectedDevice.value = index; }, 300);
};

// 鼠标抬起事件处理
const handleCanvasup = (udid, e, index) => {
  const { x, y } = getCanvasCoordinate(e, udid);
  isdown.value = false;
  sendPointer(udid, index, 1, x, y);
};

// 鼠标移动事件处理
const handleMouseMove = (udid, e, index) => {
  if (!isdown.value) return;
  const { x, y } = getCanvasCoordinate(e, udid);
  sendPointer(udid, index, 2, x, y);
};






// ======= 对齐工具 =======
const ALIGN_BASE = 16;                    // 改成 32 就是 32 对齐
const ROUND_MODE = 'nearest';             // 'down' | 'up' | 'nearest'

function alignTo(x, a = ALIGN_BASE, mode = ROUND_MODE) {
  if (a <= 1) return Math.round(x);
  const q = x / a;
  if (mode === 'down') return Math.floor(q) * a;
  if (mode === 'up') return Math.ceil(q) * a;
  /* nearest */         return Math.round(q) * a;
}


//回车 index手机下标   state up按下 down抬起      keycode 键
const key = (index, state, keycode) => {
  // console.log("退格", index)
  if (index === 999) {
    return
  } else {
    if (state == 'up') {
      wslist[index].send(toBufferBtn({ "type": 0, "action": 1, "keycode": keycode, "metaState": 0, "repeat": 0 }));
    } else if (state == 'down') {
      wslist[index].send(toBufferBtn({ "type": 0, "action": 0, "keycode": keycode, "metaState": 0, "repeat": 0 }));
    }
  }
}

const handleVisibilityChange = () => {
  if (document.visibilityState === "hidden") {
    console.log("页面被隐藏");
    isshow.value = false;
    // 页面被隐藏时执行的逻辑
  } else if (document.visibilityState === "visible") {
    console.log("页面变为可见");
    setTimeout(() => {
      isshow.value = true;
      // ObtainDeviceInformation();
    }, 500);

  }
};


onMounted(() => {
  // document.addEventListener("visibilitychange", handleVisibilityChange);
  ObtainDeviceInformation();
  // window.addEventListener('keydown', (e) => {
  //   // console.log('触发按键了 键盘事件有效', e)
  //   if (e.key == 'Backspace') {
  //     key(selectedDevice.value, 'down', 67)
  //   }
  // })
  // window.addEventListener('keyup', (e) => {
  //   // console.log('触发按键了 键盘事件有效抬起', e.keyCode, e.key)
  //   if (e.key == 'Backspace') {
  //     key(selectedDevice.value, 'up', 67)
  //   }
  // })

  const loading = ElLoading.service({
    lock: true,
    text: '初始化中...',
    background: 'rgba(0, 0, 0, 0.7)',
  })
  // reloadPage()
  setTimeout(() => {
    loading.close()

  }, 2000)

  //sse接收爬虫发送的消息
  const es = connectSSE(`https://datasave.api.yolozs.com/api/sse/connect/${userdata.tenantId}/${userdata.id}`, (data) => {
    // connectSSE(`http://192.168.1.155:19665/api/sse/connect/${userdata.tenantId}/${userdata.id}`, (data) => {
    // 处理服务端推送的数据
    console.log('来自服务端:', data)

    //接收到start
    if (data === 'start') {
      if (!isMsgPop.value) {
        isMsgPop.value = true;

        ElMessageBox.confirm(
          '检测到YOLO助手正在爬取主播，是否进行操作？',
          '消息提醒',
          {
            confirmButtonText: '开始',
            cancelButtonText: '取消',
            type: 'success',
          }
        )
          .then(() => {
            //开启sse版follow任务
            ElMessage({
              type: 'success',
              message: '任务开启成功',
            })
            addToHostList(stroageHost.value)
            //重启tk
            resetTk()
            //获取评论
            comment().then((resA) => {
              console.log('resA:', resA);
              setContentList(resA)
              //评论
              textContentArr.value.forEach((item, indexA) => {
                textContent.value[indexA] = resA[getRandomNumber(resA.length - 1)];
              })
              prologue().then((resB) => {
                console.log('resB:', resB);
                setContentpriList(resB)
                //私信
                textContentpriArr.value.forEach((item, indexA) => {
                  textContentpri.value[indexA] = resB[getRandomNumber(resB.length - 1)];
                  runType.value = 'follow'
                  console.log('runType', runType.value)
                })
                deviceInformation.value.forEach((device, indexB) => {
                  if (getHostList().length <= 0) return;

                  // LikesToLikesToLikes(device.udid, indexB)
                  wsActions.getmesNum(device.udid, indexB)
                })
              })
            })
          })
          .catch(() => {
            stroageHost.value = []
            isMsgPop.value = false;
          })
      }
    } else {
      stroageHost.value = getHostList()
      stroageHost.value.push(({ country: data.country, text: data.hostsId, state: false }))
      if (runType.value == 'follow') {
        addToHostList([{ country: data.country, text: data.hostsId, state: false }])
      }

    }


  })
  td.setSSE(es)
});
//更新状态
// update(
//   {
//     id: data.id,
//     operationStatus: 1,
//   }
// ).then(() => {

// })

onBeforeUnmount(() => {
  // document.removeEventListener("visibilitychange", handleVisibilityChange);
});

// 组件卸载时清理
onUnmounted(() => {
  console.log("卸载组件");
  cloesMonitor(); //关闭检测消息
});

//获取设备信息
const ObtainDeviceInformation = () => {
  openDiscovery("ws://127.0.0.1:8000/?action=multiplex", eitwo)
}

//喜欢-输入评论
async function LikesToCommentToComPush(udid, index) {
  await sendWsTask(index, { udid, action: 'click', type: 'Likes', index, resourceId: 'com.zhiliaoapp.musically:id/dy6' });
  await sendWsTask(index, { udid, action: 'click', type: 'Comment', index, resourceId: 'com.zhiliaoapp.musically:id/cvd' });
  await sendWsTask(index, { udid, action: 'dump', type: 'CommentText', index, resourceId: 'com.zhiliaoapp.musically:id/d5q' });
  await sendWsTask(index, { udid, action: 'click', type: 'Comtext', index, resourceId: 'com.zhiliaoapp.musically:id/cs0' });
  await sendWsTask(index, { udid, action: 'click', type: 'ComPush', index, resourceId: 'com.zhiliaoapp.musically:id/bqg' });
}

//点赞主页4个作品+评论最后一个作品并返回
async function LikesToLikesToLikes(udid, index) {
  isStop.value = false;
  runType.value = 'follow';

  // await sendWsTask(index, { udid, action: 'click', type: 'getmesNum', index, resourceId: 'com.zhiliaoapp.musically:id/jyv' });
  await sendWsTask(index, { udid, action: 'click', type: 'search', index, resourceId: 'com.zhiliaoapp.musically:id/gtz' });
  await sendWsTask(index, { udid, action: 'click', type: 'searchHost', index, resourceId: 'com.zhiliaoapp.musically:id/t6f' });
  await sendWsTask(index, { udid, action: 'click', type: 'toHost', index, resourceId: 'com.zhiliaoapp.musically:id/iso' });
  await sendWsTask(index, { udid, action: 'click', type: 'hostVideo', index, resourceId: 'com.zhiliaoapp.musically:id/u3o', num: 0 });
  await sendWsTask(index, { udid, action: 'click', type: 'Likes', index, resourceId: 'com.zhiliaoapp.musically:id/dy6' });
  await sendWsTask(index, { udid, action: 'click', type: 'Likes', index, resourceId: 'com.zhiliaoapp.musically:id/dy6' });
  await sendWsTask(index, { udid, action: 'click', type: 'Likes', index, resourceId: 'com.zhiliaoapp.musically:id/dy6' });
  await sendWsTask(index, { udid, action: 'click', type: 'Likes', index, resourceId: 'com.zhiliaoapp.musically:id/dy6' });
  await sendWsTask(index, { udid, action: 'click', type: 'Comment', index, resourceId: 'com.zhiliaoapp.musically:id/cvd' });
  await sendWsTask(index, { udid, action: 'click', type: 'Comtext', index, resourceId: 'com.zhiliaoapp.musically:id/cs0' });
  await sendWsTask(index, { udid, action: 'click', type: 'ComPush', index, resourceId: 'com.zhiliaoapp.musically:id/bqg' });
  await sendWsTask(index, { udid, action: 'click', type: 'Attention', index, resourceId: 'com.zhiliaoapp.musically:id/dhx' });
  await sendWsTask(index, { udid, action: 'click', type: 'Attention', index, resourceId: 'com.zhiliaoapp.musically:id/dhx' });
  await sendWsTask(index, { udid, action: 'click', type: 'Privatetex', index, resourceId: 'com.zhiliaoapp.musically:id/hob' });
  await sendWsTask(index, { udid, action: 'click', type: 'PrivatePush', index, resourceId: 'com.zhiliaoapp.musically:id/hog' });
  // await sendWsTask(index, { udid, action: 'click', type: 'fanhui', index, resourceId: 'com.zhiliaoapp.musically:id/awi' });
}

//私信
async function PrivatetexToPrivatePush(udid, index) {
  await sendWsTask(index, { udid, action: 'click', type: 'Privatetex', index, resourceId: 'com.zhiliaoapp.musically:id/hob' });
  await sendWsTask(index, { udid, action: 'click', type: 'PrivatePushFollow', index, resourceId: 'com.zhiliaoapp.musically:id/hog' });
}

//重置当前应用
async function resetApp(udid, index) {
  createTaskQueue(index).clear();//清除队伍中的任务

  await sendWsTask(index, { udid, action: 'killNow' });
  await sendWsTask(index, { udid, action: 'openDY' });
}
//发送评论字符到手机方法
function setComText(index) {
  isSend.value = true;
  setTimeout(() => {
    isSend.value = false;
  }, 300);
  console.log('发送评论内容', index, textContent.value[index])
  wslist[index].send(setClipboard(textContent.value[index]));
  if (runType.value === 'follow') {
    textContent.value[index] = getContentList()[index][getRandomNumber(getContentList()[index].length - 1)];
  }
}

//发送主播ID字符到手机方法
function setHostId(index) {
  isSend.value = true;
  setTimeout(() => {
    isSend.value = false;
  }, 300);
  const host = markFirstFalseAsTrue(getHostList())
  if (host == null) {
    createTaskQueue(index).clear();//清除队伍中的任务
    ElMessage.success('主播ID已全部发送完毕');
    return;
  }
  hostIdArr.value[index] = host;
  wslist[index].send(setClipboard(host.text));   //发送内容

}


//发送私信字符到手机方法
function setPrivateText(index, datatype) {
  isSend.value = true;
  setTimeout(() => {
    isSend.value = false;
  }, 300);
  console.log('发送私信内容', index, textContentpri.value[index])
  //如果是在关注主播中，发送的开场白进行对应国家翻译
  if (runType.value === 'follow' && datatype == 'PrivatePush') {
    translation({ msg: getContentpriList()[index][getRandomNumber(getContentpriList()[index].length - 1)], country: hostIdArr.value[index].country }).then(res => {
      console.log(res)
      textContentpri.value[index] = res;
      wslist[index].send(setClipboard(textContentpri.value[index]));
    })
  } else {
    wslist[index].send(setClipboard(textContentpri.value[index]));
    if (getContentpriList()[index]) {
      textContentpri.value[index] = getContentpriList()[index][getRandomNumber(getContentpriList()[index].length - 1)];
    }
  }


}
//获取手机粘贴板方法
function getText(index) {
  wslist[index].send(getClipboard());
}

function getComArr(index, type) {
  if (type == '评论') {
    ElMessageBox.alert(getContentList()[index], `当前${type}内容`, {
      confirmButtonText: 'OK',
    })
  } else {
    ElMessageBox.alert(getContentpriList()[index], `当前${type}内容`, {
      confirmButtonText: 'OK',
    })
  }
}




const reload = (opts = {}) => {
  const { onlySelected = false, hard = true } = opts;
  const targets = (onlySelected && selectedDevice.value !== 999)
    ? [selectedDevice.value]
    : deviceInformation.value.map((_, i) => i);

  targets.forEach(i => refreshStream(i, hard));
  ElMessage.success(`已刷新${onlySelected ? '当前设备' : '全部设备'}`);
};


//发送任务前的处理
function sendWsTask(index, data) {
  console.log('任务等待中', data.type);
  return new Promise((resolve) => {
    try {
      const queue = createTaskQueue(index);
      // console.log("创建队列", queue.getNum());
      const task = () => {

        //发送评论的文本粘贴事件
        if (data.type == 'Likes') {
          clickxy(160, 360, index)
        }
        if (data.type == 'isHost') {
        }
        if (data.type == 'Comment') {
          if (runType.value == 'follow') {
            clickxy(160, 360, index)
          }
        }
        if (data.type == 'ComPush') {
          setTimeout(() => {
            setComText(index)//粘贴内容
          }, 500)
        }
        if (data.type == 'searchHost') {
          setTimeout(() => {
            setHostId(index)//粘贴内容
          }, 500)
        }
        //发送私信的文本粘贴事件
        if (data.type == 'PrivatePush' || data.type == 'PrivatePushFollow') {
          setPrivateText(index, data.type)
        }
        //关注前的返回和右滑
        if (data.type == 'Attention') {

        }
        //发送关注之前的返回
        if (data.type == 'addHost') {
        }
        //发送任务
        if (data.type == 'Attention') {
          setTimeout(() => {
            wslist[index].send(JSON.stringify(data));
            resolve();
          }, 1000)
        } else {
          wslist[index].send(JSON.stringify(data));
          resolve();
        }
        // 表示当前任务“已发出”，但不是“已完成”
        // 实际完成由 onmessage 中的 success 决定并继续执行队列
      };
      queue.enqueue(task);
    } catch (e) {
      console.error('发送任务错误：', e);
    }

  });
}

// 生成start秒到end秒的随机延迟
function randomDelay(start, end) {
  return Math.floor(Math.random() * end * 1000) + start * 1000;
}

//一个0到n之间的随机整数
function getRandomNumber(n) {
  return Math.floor(Math.random() * (n + 1));
}

//延迟30-50秒后检测关注
function randomSeeVideo(udid, index) {
  const delay = Math.floor(Math.random() * (50 - 30) + 10) * 1000;
  playTimer.value[index] = setTimeout(() => {
    console.log('观看结束', index);
    wsActions.isHost(udid, index)//检测
  }, delay);
}
//延迟1-4分钟后秒后检测关注
async function randomDelayAndExecute() {
  const minDelay = 1 * 60 * 1000;
  const maxDelay = 4 * 60 * 1000;
  const randomDelay = Math.floor(Math.random() * (maxDelay - minDelay + 1)) + minDelay;

  console.log(`将延迟 ${Math.round(randomDelay / 1000)} 秒后执行...`);

  return new Promise((resolve) => {
    setTimeout(() => {
      const randomNum = Math.floor(Math.random() * 100);
      if (randomNum < 30) {
        console.log("30%概率触发");
        resolve(true);
      } else {
        console.log("70%概率触发");
        resolve(false);
      }
    }, randomDelay);
  });
}

//选中样式
function getVideoStyle(index) {
  const isSelected = selectedDevice.value === index;
  const baseWidth = phone.value.width;
  const baseHeight = phone.value.height;

  return {
    width: isSelected ? baseWidth * 1.4 + 'px' : baseWidth + 'px',
    height: isSelected ? baseHeight * 1.4 + 'px' : baseHeight + 'px',
    // border: isSelected ? '2px solid blue' : '1px solid blue',
    position: isSelected ? 'absolute' : 'relative',
    top: isSelected ? '0' : 'unset',
    left: isSelected ? '0' : 'unset',
    zIndex: isSelected ? 1000 : 1,
    pointerEvents: isSelected ? 'none' : 'auto',
    transform: getTransformStyle(index),
    transition: 'all 0.3s ease',
  };
}

function stop() {
  // actions[index] = [];
  stopAll();         // ← 替代 cloesMonitor + pausedDevices.clear
  isStop.value = true; //停止所有任务
  isMsgPop.value = false;//关闭爬虫sse任务

  deviceInformation.value.forEach((item, i) => {
    console.log('停止', i);
    createTaskQueue(i).clear();//清除队伍中的任务
    console.log(createTaskQueue(i).getNum())
    //停止当前任务

    //重置当前状态
    runType.value = ''
    //清除观看视频定时器
    clearInterval(playTimer.value[i])
    playTimer.value[i] = null;//清除定时器

  })
  console.log('停止', isStop.value);
}


function openTk() {
  deviceInformation.value.forEach((device, index) => {
    wsActions.open(device.udid, index)
  })
}
function resetTk() {
  isStop.value = false;
  deviceInformation.value.forEach((device, index) => {
    resetApp(device.udid, index)
  })
}


//关闭监听
function cloesMonitor() {
  isMonitorOn.value = false;
  deviceInformation.value.forEach(() => { runType.value = '' });
  clearInterval(isShowMes.value);
  isShowMes.value = '';
  pausedDevices.clear(); // 新增
}

//一键养号
function parentNum() {
  isStop.value = false;
  deviceInformation.value.forEach((device, index) => {
    runType.value = 'like'
    wsActions.isHost(device.udid, index)
  })
}
function brushLive() {
  isStop.value = false;
  deviceInformation.value.forEach((device, index) => {
    runType.value = 'brushLive'
    wsActions.toLive(device.udid, index)
  })
}
//确认多行文本框内容
function onDialogConfirm(result, type, index, isMon) {
  console.log(type, index, isMon);
  if (type == '评论') {
    if (index == 998) {
      textContentArr.value.forEach((item, indexA) => {
        textContent.value[indexA] = result[getRandomNumber(result.length - 1)];
      })
      setContentList(result)
      //打开私信弹窗
      selectedDevice.value = 999;
      dialogTitle.value = '私信';
      setTimeout(() => {
        showDialog.value = true;
      }, 600)
    } else {
      setContentList(result)

      textContent.value[index] = result[getRandomNumber(result.length - 1)];
    }
  } else if (type == '私信') {
    //index ==999 表示全部
    if (index == 999) {
      isMonitor.value = isMon  //是否自动回复
      textContentpriArr.value.forEach((item, indexA) => {
        textContentpri.value[indexA] = result[getRandomNumber(result.length - 1)];
        runType.value = 'follow'
      })
      // isStop.value = true; //停止所有任务
      setContentpriList(result)
      deviceInformation.value.forEach((device, indexB) => {
        if (getHostList().length <= 0) return;

        if (isMon) {
          console.log(isMon)
          console.error('自动回复');
          wsActions.getmesNum(device.udid, indexB)
        } else {
          console.error('开始关注');
          LikesToLikesToLikes(device.udid, indexB)
        }
        // LikesToLikesToLikes(device.udid, indexB)

      })
    } else {
      textContentpriArr.value[index] = result;
      textContentpri.value[index] = result[getRandomNumber(result.length - 1)];
    }
  } else if (type == '主播ID') {
    //index ==999 表示全部
    if (index == 999) {
      //分割数组  几台设备 分为几个数组
      let hostListResult = [];
      result.forEach((item, indexA) => {
        hostListResult.push({ country: '', text: item, state: false })
      })
      addToHostList(hostListResult)
      //打开评论弹窗
      selectedDevice.value = 998;
      dialogTitle.value = '评论';
      setTimeout(() => {
        showDialog.value = true;
      }, 600)
    }
  }
}

function getTranslation(list) {
  list.forEach((item, index) => {
    translationToChinese({ msg: item.text }).then(res => {
      console.log(res);
      chatList.value[index].text = res
    })
  })
}

function markFirstFalseAsTrue(hostList) {
  const index = hostList.findIndex(item => item.state === false);
  if (index !== -1) {
    hostList[index].state = true;
    setHostList(hostList)
    return hostList[index]; // 可选：返回被修改的对象
  }
  return null; // 没有找到 false 的项
}
//计算手机canvas是否需要偏移
function getTransformStyle(index) {
  return selectedDevice.value === index && index >= 3
    ? 'translateY(-30%)'
    : 'none';
}

function manualGc() {
  window.electronAPI.manualGc()
}


</script>

<style scoped lang="less">
@import '../static/css/video.less';
</style>
