/**
 * 声网会议核心 Hook
 * 提供会议的基础功能：加入/离开、音视频控制、用户管理等
 *
 * 设计原则：
 * 1. 使用回调函数通知业务层处理 toast，避免在 Hook 中直接使用 Toast
 * 2. 业务层（组件）统一处理用户反馈
 */

import AgoraRTC, {
  type IAgoraRTCClient,
  type IAgoraRTCError,
  type IAgoraRTCRemoteUser,
  type ICameraVideoTrack,
  type ILocalVideoTrack,
  type IMicrophoneAudioTrack,
  type NetworkQuality,
  type RemoteStreamType,
} from 'agora-rtc-sdk-ng';
import { type Ref, computed, nextTick, reactive, ref, shallowRef, unref, watch, watchEffect } from 'vue';
import { useRoute } from 'vue-router';
import type { LocalUser, MeetingEventCallbacks, NetworkQualityLevel, OnJoinRoomData } from './types';
import { TokenManager } from './useTokenManager';
import { getMeetingTokenAxios } from '@/api/meeting';

/**
 * 声网会议 Hook 配置
 */
export interface AgoraMeetingOptions {
  /** 是否禁用本地音视频轨道（用于监控端等纯观看场景） */
  disableLocalTracks?: Ref<boolean> | boolean;
  /**
   * 是否在 user-published 时自动播放到 player-${uid}
   * - 教室端/监控端（有列表容器）可保持默认 true
   * - 学生端（只有一个主画面容器）应设为 false，由页面自行播放
   */
  autoPlayRemoteVideo?: boolean;
}

/**
 * 声网会议核心 Hook
 * @param {Ref<string>} courseRoomId - 课程房间 ID
 * @param {Ref<string>} userName - 用户名称
 * @param {Ref<number>} shortUidRef - 短 UID 引用（由外部维护）
 * @param {MeetingEventCallbacks} callbacks - 事件回调函数
 * @param {AgoraMeetingOptions} options - 配置项
 */
export function useAgoraMeeting(
  courseRoomId: Ref<string>,
  userName: Ref<string>,
  shortUidRef: Ref<number>,
  callbacks?: MeetingEventCallbacks,
  options?: AgoraMeetingOptions
) {
  /** 设置声网日志等级 */
  AgoraRTC.setLogLevel(2);
  // 从路由获取设备 ID
  const route = useRoute();
  /** 摄像头设备 ID */
  const cameraDeviceId = computed(() => String(route.query.cameraDeviceId || ''));
  /** 麦克风设备 ID */
  const microphoneDeviceId = computed(() => String(route.query.microphoneDeviceId || ''));

  /** 声网 RTC 客户端（响应式，方便外部 hook 监听就绪时机） */
  const client = shallowRef<IAgoraRTCClient | null>(null);

  /** 本地麦克风音频轨道（内部使用） */
  let localAudioTrack: IMicrophoneAudioTrack | null = null;
  /** 本地摄像头视频轨道（内部使用） */
  let localVideoTrack: ICameraVideoTrack | null = null;
  /** 本地屏幕共享视频轨道（内部使用） */
  let localScreenTrack: ILocalVideoTrack | null = null;
  let screenClient: IAgoraRTCClient | null = null;

  /** 是否已加入频道 */
  const isJoined = ref(false);
  /** 是否静音 */
  const isMuted = ref(false);
  /** 是否关闭视频 */
  const isVideoOff = ref(false);
  /** 静音操作加载状态 */
  const muteLoading = ref(false);
  /** 视频操作加载状态 */
  const videoLoading = ref(false);
  /** 离开操作加载状态 */
  const leaveLoading = ref(false);
  /** 网络质量等级 */
  const networkQuality = ref<NetworkQualityLevel>('good');
  /** 远程用户列表 */
  const remoteUsers = ref<IAgoraRTCRemoteUser[]>([]);
  /** 当前选中的主视频用户 ID */
  const selectedUserUid = ref<number | string | null>(null);
  /** Token 管理器 */
  const tokenManagerRef = ref<TokenManager | null>(null);

  /** 本地用户对象 */
  const localUser = reactive<LocalUser>({
    uid: 0, // 初始为 0，会通过 watch 同步 shortUidRef
    isLocal: true,
    videoTrack: null,
    audioTrack: null,
    userName: userName.value,
  });

  /** 是否正在共享屏幕 */
  const isScreenSharing = ref(false);
  const localScreenUid = ref<number | null>(null);
  /** 是否禁用本地音视频轨道 */
  const disableLocalTracks = computed(() => Boolean(unref(options?.disableLocalTracks ?? false)));

  // 同步本地用户名称
  watchEffect(() => {
    localUser.userName = userName.value;
  });

  // 同步外部传入的短 UID 到 localUser.uid（确保响应式更新）
  watch(
    shortUidRef,
    (newVal) => {
      if (newVal && newVal !== 0) {
        localUser.uid = newVal;
        console.log('[Agora] 短 UID 已更新:', newVal);
      }
    },
    { immediate: true }
  );

  /**
   * 监听主视频用户变化，动态调整所有远程用户的流类型
   * 双流模式优化：主视频使用高流(0)，其他使用低流(1)节省流量
   */
  watch(selectedUserUid, async (newUid) => {
    if (!client.value) {
      return;
    }
    const remoteUsersList = client.value.remoteUsers || [];
    const promises = remoteUsersList.map(async (user) => {
      const isMainVideo = user.uid === newUid;
      const streamType: 0 | 1 = isMainVideo ? 0 : 1;
      try {
        await client.value?.setRemoteVideoStreamType(user.uid, streamType);
        console.log(`用户 ${user.uid} 流类型已调整为:`, isMainVideo ? '高流(主视频)' : '低流');
      } catch (error) {
        console.error(`调整用户 ${user.uid} 流类型失败:`, error);
      }
    });
    await Promise.all(promises);
  });

  /**
   * 初始化 Token管理器
   */
  function initTokenManager() {
    try {
      // 创建 Token 管理器
      tokenManagerRef.value = new TokenManager({
        channelName: courseRoomId,
        uid: shortUidRef,
        onWillExpire: (willExpireAt) => {
          console.warn('[Agora] Token 即将过期，时间戳:', new Date(willExpireAt).toLocaleString());
          callbacks?.onTokenWillExpire?.();
        },
        onExpired: () => {
          console.error('[Agora] Token 已过期！');
          callbacks?.onTokenExpired?.();
        },
        onRefreshed: (_newToken) => {
          console.log('[Agora] Token 刷新成功');
          console.log('[Agora] 客户端 Token 已更新');
        },
        onError: (error) => {
          console.error('[Agora] Token 刷新失败:', error);
          callbacks?.onError?.(error as Error);
        },
      });
    } catch (error) {
      console.error('[Agora] 初始化 Token 管理器失败:', error);
      throw error;
    }
  }

  /**
   * 清理 Token管理器
   */
  function cleanupTokenManager(): void {
    if (tokenManagerRef.value) {
      tokenManagerRef.value.destroy();
      tokenManagerRef.value = null;
    }
  }

  /**
   * 将声网网络质量转换为本地等级
   * @param {number} quality - 声网网络质量值 (0-5)
   * @returns {NetworkQualityLevel} 网络质量等级
   */
  function convertNetworkQuality(quality: number): NetworkQualityLevel {
    if (quality >= 4) {
      return 'good';
    }
    if (quality >= 2) {
      return 'fair';
    }
    return 'poor';
  }

  /**
   * 初始化声网 RTC 客户端并注册事件监听
   */
  function initClient(): void {
    try {
      // ✅ 先清理旧 client 的监听器，防止重复注册
      if (client.value) {
        client.value.removeAllListeners?.();
      }

      client.value = AgoraRTC.createClient({ mode: 'rtc', codec: 'vp8' });
      if (tokenManagerRef.value) {
        tokenManagerRef.value.bindClient(client.value);
      }

      /**
       * 播放远程视频到指定播放器
       * @deprecated 学生端使用 autoPlayRemoteVideo=false，由业务层自行处理
       */
      const playRemoteVideo = (user: IAgoraRTCRemoteUser, playerId: string) => {
        console.log(`【声网】准备播放远程视频 ${playerId}:`, user.uid);
        setTimeout(() => {
          const playerDiv = document.getElementById(playerId);
          console.log('【声网】视频播放元素:', playerDiv, 'videoTrack:', user.videoTrack);
          if (playerDiv && user.videoTrack) {
            try {
              user.videoTrack.play(playerDiv);
              console.log('【声网】远程视频已播放:', user.uid);
            } catch (error) {
              console.warn('【声网】远程视频播放异常:', error);
            }
          } else {
            console.warn('【声网】视频播放失败：元素或轨道不存在');
          }
        }, 100);
      };

      client.value.on('user-published', async (user: IAgoraRTCRemoteUser, mediaType: 'audio' | 'video') => {
        console.log('【声网事件】user-published:', user.uid, '媒体类型:', mediaType);
        console.log('【声网事件】user 对象:', user);

        await client.value?.subscribe(user, mediaType);

        // 双流模式优化：默认使用低流 (1) 节省流量，只有主视频使用高流 (0)
        const isMainVideo = selectedUserUid.value === user.uid;
        const streamType: 0 | 1 = isMainVideo ? 0 : 1;
        if (mediaType === 'video') {
          await client.value?.setRemoteVideoStreamType(user.uid, streamType);
        }
        console.log('【声网】订阅成功:', user.uid, '类型:', mediaType, isMainVideo ? '主视频 (高流)' : '小视频 (低流)');

        // ✅ 播放远程视频到普通播放器（默认使用 player-${uid}，可通过 options 关闭）
        if (mediaType === 'video' && (options?.autoPlayRemoteVideo ?? true)) {
          playRemoteVideo(user, `player-${user.uid}`);
        }

        // ✅ 播放远程音频（声网音频轨道需要手动播放）
        if (mediaType === 'audio') {
          console.log('【声网】收到远程音频，audioTrack:', user.audioTrack);
          if (user.audioTrack) {
            try {
              user.audioTrack.play();
              console.log('【声网】✅ 远程音频已播放:', user.uid);
            } catch (error) {
              console.error('【声网】❌ 远程音频播放失败:', error);
            }
          } else {
            console.warn('【声网】❌ user.audioTrack 不存在!');
          }
        }

        // ✅ 只在第一次添加用户到 remoteUsers，防止网络波动导致的重复触发
        const isNewUser = !remoteUsers.value.find((u) => u.uid === user.uid);
        if (isNewUser) {
          remoteUsers.value.push(user);
          console.log('[声网] 新用户加入，当前用户数:', remoteUsers.value.length);
        }
        callbacks?.onUserPublished?.(user, mediaType);
      });

      /** 订阅的视频流类型发生改变回调 （（高码率、高分辨率）变为视频小流（低码率、低分辨率），或视频小流变为视频大流。） */
      client.value.on('stream-type-changed', (uid: number | string, streamType: RemoteStreamType) => {
        console.log(' 订阅的视频流类型:', streamType);
      });

      client.value.on('user-unpublished', async (user: IAgoraRTCRemoteUser, mediaType: 'audio' | 'video') => {
        await client.value?.unsubscribe(user, mediaType);
        console.log('取消订阅:', user.uid);
        callbacks?.onUserUnpublished?.(user, mediaType);
      });

      client.value.on('user-left', (user: IAgoraRTCRemoteUser) => {
        console.log('用户离开:', user.uid);
        remoteUsers.value = remoteUsers.value.filter((u) => u.uid !== user.uid);
        if (selectedUserUid.value === user.uid) {
          selectedUserUid.value = null;
        }
        callbacks?.onUserLeft?.(user);
      });

      // 推流发生错误
      client.value.on('live-streaming-error', (url: string, err: IAgoraRTCError) => {
        console.log('[Agora] 推流发生错误:', err);
      });

      client.value.on('connection-state-change', (oldState: string, newState: string, reason: string) => {
        console.log('连接状态变化:', oldState, '->', newState, reason);
        callbacks?.onConnectionStateChange?.(newState);
      });

      client.value.on('network-quality', (stats: NetworkQuality) => {
        if (stats) {
          const quality = convertNetworkQuality(stats.uplinkNetworkQuality || 5);
          networkQuality.value = quality;
          callbacks?.onNetworkQuality?.(quality);
          console.log('网络质量:', quality);
        }
      });
    } catch (error) {
      console.error('初始化客户端失败:', error);
      callbacks?.onError?.(error as Error);
    }
  }

  /**
   * 加入 RTC 频道并发布本地音视频轨道
   * @param restoredState - 恢复的状态（从后端返回）
   */
  async function joinChannel(roomData: OnJoinRoomData): Promise<void> {
    try {
      FullLoading.show('正在加入会议...');

      if (!disableLocalTracks.value) {
        // 初始化本地麦克风
        try {
          localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack({
            microphoneId: microphoneDeviceId.value || undefined,
            encoderConfig: { sampleRate: 16000, bitrate: 16 },
          });
        } catch (error) {
          console.error('麦克风初始化失败:', error);
          const err = error as { code?: string; name?: string; message?: string };
          if (err.code === 'NOT_READABLE' || err.name === 'NotReadableError' || err.message?.includes('Device in use')) {
            throw new Error('麦克风被占用，请关闭其他使用麦克风的程序后重试', { cause: error });
          } else {
            throw new Error('麦克风初始化失败，请检查设备连接', { cause: error });
          }
        }

        // 初始化本地摄像头
        try {
          localVideoTrack = await AgoraRTC.createCameraVideoTrack({
            cameraId: cameraDeviceId.value || undefined,
            encoderConfig: { width: 640, height: 480, frameRate: 15, bitrateMin: 300, bitrateMax: 600 },
          });
        } catch (error) {
          console.error('摄像头初始化失败:', error);
          const err = error as { code?: string; name?: string; message?: string };
          if (err.code === 'NOT_READABLE' || err.name === 'NotReadableError' || err.message?.includes('Device in use')) {
            throw new Error('摄像头被占用，请关闭其他使用摄像头的程序后重试', { cause: error });
          } else {
            throw new Error('摄像头初始化失败，请检查设备连接', { cause: error });
          }
        }

        localUser.videoTrack = localVideoTrack;
        localUser.audioTrack = localAudioTrack;
      } else {
        localUser.videoTrack = null;
        localUser.audioTrack = null;
      }

      // join 返回声网实际分配的 uid（传 0 时声网会自动分配）
      // 更新本地用户 UID
      localUser.uid = shortUidRef.value;
      console.log('[Agora] 准备加入，当前 shortUid:', shortUidRef.value, 'localUser.uid:', localUser.uid);

      // 先加入频道
      await client.value?.join(roomData.tokenInfo.appid, courseRoomId.value, roomData.tokenInfo.rtcToken, shortUidRef.value || 0);
      console.log('加入会议成功，使用短 UID:', shortUidRef.value || '自动分配');
      if (tokenManagerRef.value) {
        tokenManagerRef.value.setCurrentToken(roomData.tokenInfo);
      }

      if (!disableLocalTracks.value) {
        // ✅ 根据恢复的状态决定是否发布轨道（如果被禁麦/禁视频，只发布另一个）
        const tracksToPublish: (ICameraVideoTrack | IMicrophoneAudioTrack)[] = [];

        // 如果没有被禁麦，发布音频
        if (!roomData?.isAudioMuted && localAudioTrack) {
          tracksToPublish.push(localAudioTrack);
        }

        // 如果没有被禁视频，发布视频
        if (!roomData?.isVideoMuted && localVideoTrack) {
          tracksToPublish.push(localVideoTrack);
        }

        console.log('[Agora] 准备发布的轨道:', {
          audio: !roomData?.isAudioMuted,
          video: !roomData?.isVideoMuted,
          tracksCount: tracksToPublish.length,
        });

        if (tracksToPublish.length > 0) {
          await client.value?.publish(tracksToPublish);
          console.log('[Agora] 轨道已发布，准备播放视频');
        } else {
          console.log('[Agora] 用户被禁麦/禁视频，暂不发布任何轨道');
        }

        // 加入并发布成功后再播放本地视频（确保 player-local 元素已存在）
        if (localVideoTrack) {
          // 使用 nextTick 等待 Vue 响应式更新完成
          await nextTick();
          const el = document.getElementById('player-local');
          console.log('[Agora] 查找 player-local 元素:', el ? '找到' : '未找到');
          if (el && !el.querySelector('video')) {
            localVideoTrack?.play(el);
            console.log('[Agora] 本地视频已播放');
          } else {
            console.warn('[Agora] 未找到 player-local 元素或已有视频', el ? '元素存在' : '元素不存在');
          }
        }
      }

      isJoined.value = true;
      FullLoading.hide();
    } catch (error) {
      console.error('加入频道失败:', error);
      FullLoading.hide();
      callbacks?.onError?.(error as Error);
      throw error;
    }
  }

  /**
   * 切换麦克风静音状态
   */
  async function toggleMute(): Promise<void> {
    if (localAudioTrack && !muteLoading.value) {
      muteLoading.value = true;
      try {
        const nextMuted = !isMuted.value;
        const currentClient = client.value;
        if (nextMuted) {
          try {
            await currentClient?.unpublish(localAudioTrack);
          } catch {}
          try {
            await localAudioTrack.setEnabled(false);
          } catch {}
          isMuted.value = true;
        } else {
          try {
            await localAudioTrack.setEnabled(true);
          } catch {}
          try {
            await currentClient?.publish(localAudioTrack);
          } catch {}
          isMuted.value = false;
        }
      } catch (error) {
        console.error('切换静音失败:', error);
        callbacks?.onError?.(error as Error);
      } finally {
        muteLoading.value = false;
      }
    }
  }

  /**
   * 切换摄像头开启状态
   */
  async function toggleVideo(): Promise<void> {
    if (localVideoTrack && !videoLoading.value) {
      videoLoading.value = true;
      try {
        const nextVideoOff = !isVideoOff.value;
        const currentClient = client.value;
        if (nextVideoOff) {
          try {
            await currentClient?.unpublish(localVideoTrack);
          } catch {}
          try {
            await localVideoTrack.setEnabled(false);
          } catch {}
          isVideoOff.value = true;
        } else {
          try {
            await localVideoTrack.setEnabled(true);
          } catch {}
          try {
            await currentClient?.publish(localVideoTrack);
          } catch {}
          isVideoOff.value = false;
        }
      } catch (error) {
        console.error('切换摄像头失败:', error);
        callbacks?.onError?.(error as Error);
      } finally {
        videoLoading.value = false;
      }
    }
  }

  /**
   * 强制关闭本地音频（被创建者禁麦时使用）
   */
  async function forceMuteAudio(): Promise<void> {
    if (localAudioTrack && !isMuted.value) {
      try {
        await client.value?.unpublish(localAudioTrack);
        try {
          await localAudioTrack.setEnabled(false);
        } catch {}
        isMuted.value = true;
        console.log('[Agora] 已被禁麦，已停止发布音频流');
      } catch (error) {
        console.error('强制静音失败:', error);
      }
    }
  }

  /**
   * 强制关闭本地视频（被创建者禁视频时使用）
   */
  async function forceMuteVideo(): Promise<void> {
    if (localVideoTrack && !isVideoOff.value) {
      try {
        await client.value?.unpublish(localVideoTrack);
        try {
          await localVideoTrack.setEnabled(false);
        } catch {}
        isVideoOff.value = true;
        console.log('[Agora] 已被禁视频，已停止发布视频流');
      } catch (error) {
        console.error('强制关闭视频失败:', error);
      }
    }
  }

  /**
   * 强制开启本地音频（被创建者解除禁麦时使用）
   */
  async function forceUnmuteAudio(): Promise<void> {
    if (localAudioTrack && isMuted.value) {
      try {
        try {
          await localAudioTrack.setEnabled(true);
        } catch {}
        await client.value?.publish(localAudioTrack);
        isMuted.value = false;
        console.log('[Agora] 已被解除禁麦，已重新发布音频流');
      } catch (error) {
        console.error('强制开启音频失败:', error);
      }
    }
  }

  /**
   * 强制开启本地视频（被创建者解除禁视频时使用）
   */
  async function forceUnmuteVideo(): Promise<void> {
    if (localVideoTrack && isVideoOff.value) {
      try {
        try {
          await localVideoTrack.setEnabled(true);
        } catch {}
        await client.value?.publish(localVideoTrack);
        isVideoOff.value = false;
        console.log('[Agora] 已被解除禁视频，已重新发布视频流');
      } catch (error) {
        console.error('强制开启视频失败:', error);
      }
    }
  }

  /**
   * 初始化并加入会议
   * @param restoredState - 恢复的状态（从后端返回）
   */
  async function initAndJoin(roomData: OnJoinRoomData): Promise<void> {
    await initTokenManager(); // 初始化 Token管理器
    await initClient();
    await joinChannel(roomData);
  }

  /**
   * 清理 Agora 客户端资源
   * @param teardownOptions.toastSuccess - 是否显示成功提示
   */
  async function teardownAgoraClient(teardownOptions: { toastSuccess?: boolean }): Promise<void> {
    cleanupTokenManager();
    const currentClient = client.value;
    client.value = null;

    if (currentClient) {
      const tracksToUnpublish: Array<ICameraVideoTrack | IMicrophoneAudioTrack> = [];
      localAudioTrack && tracksToUnpublish.push(localAudioTrack);
      localVideoTrack && tracksToUnpublish.push(localVideoTrack);
      if (tracksToUnpublish.length > 0) {
        try {
          await currentClient.unpublish(tracksToUnpublish);
        } catch {}
      }
    }

    if (localAudioTrack) {
      localAudioTrack.stop();
      localAudioTrack.close();
      localAudioTrack = null;
    }
    if (localVideoTrack) {
      localVideoTrack.stop();
      localVideoTrack.close();
      localVideoTrack = null;
    }
    if (currentClient) {
      try {
        currentClient.removeAllListeners?.();
        await currentClient.leave();
      } catch {}
    }

    isJoined.value = false;
    remoteUsers.value = [];
    selectedUserUid.value = null;
    localUser.videoTrack = null;
    localUser.audioTrack = null;

    if (teardownOptions.toastSuccess) {
      callbacks?.onLeft?.();
    }
  }

  /**
   * 停止屏幕共享轨道
   * 停止后会重新发布摄像头视频（如果摄像头视频轨道存在且未被禁用）
   */
  async function stopScreenTrack(): Promise<void> {
    const track = localScreenTrack;
    const currentScreenClient = screenClient;
    localScreenTrack = null;
    screenClient = null;
    isScreenSharing.value = false;
    localScreenUid.value = null;
    if (track) {
      try {
        await currentScreenClient?.unpublish(track);
      } catch {}
      try {
        track.stop();
      } catch {}
      try {
        track.close();
      } catch {}
    }
    if (currentScreenClient) {
      try {
        currentScreenClient.removeAllListeners?.();
      } catch {}
      try {
        await currentScreenClient.leave();
      } catch {}
    }
  }

  /**
   * 开始屏幕共享
   * 默认选择当前网页所在的屏幕，获取不到就使用第一个屏幕
   * 注意：声网不允许同时发布多个视频轨道，所以发布屏幕共享前需要先取消发布摄像头视频
   */
  async function startScreenShare(): Promise<number> {
    console.log('[屏幕共享] 开始执行 startScreenShare');

    if (!client.value || !isJoined.value) {
      console.error('[屏幕共享] 未加入会议，无法共享屏幕');
      throw new Error('未加入会议，无法共享屏幕');
    }

    // 先停止之前的屏幕共享（如果有）
    console.log('[屏幕共享] 准备停止之前的屏幕共享');
    await stopScreenTrack();

    try {
      console.log('[屏幕共享] 显示 FullLoading');
      FullLoading.show('正在开启屏幕共享...');

      const baseUid = Number(shortUidRef.value || 0);
      if (!Number.isFinite(baseUid) || baseUid <= 0) {
        FullLoading.hide();
        throw new Error('用户信息未就绪，无法开启屏幕共享');
      }

      const nextScreenUid = baseUid + 1000000;
      if (!Number.isFinite(nextScreenUid) || nextScreenUid <= 0 || nextScreenUid > 4294967295) {
        FullLoading.hide();
        throw new Error('生成投屏 UID 失败');
      }

      const tokenRes = await getMeetingTokenAxios(courseRoomId.value, nextScreenUid);
      const tokenInfo = tokenRes.data;
      if (!tokenInfo?.appid || !tokenInfo?.rtcToken) {
        FullLoading.hide();
        throw new Error('获取投屏 Token 失败');
      }

      const nextClient = AgoraRTC.createClient({ mode: 'rtc', codec: 'vp8' });
      await nextClient.join(tokenInfo.appid, courseRoomId.value, tokenInfo.rtcToken, nextScreenUid);

      const trackResult = await AgoraRTC.createScreenVideoTrack(
        {
          encoderConfig: '1080p',
        },
        'auto'
      );

      const screenVideoTrack = Array.isArray(trackResult) ? trackResult[0] : trackResult;

      await nextClient.publish(screenVideoTrack);
      localScreenTrack = screenVideoTrack;
      screenClient = nextClient;
      isScreenSharing.value = true;
      localScreenUid.value = nextScreenUid;

      FullLoading.hide();

      screenVideoTrack.on('track-ended', () => {
        stopScreenTrack()
          .then(() => {
            callbacks?.onLocalScreenShareEnded?.();
          })
          .catch(() => {});
      });

      console.log('[屏幕共享] startScreenShare 执行完毕');
      return nextScreenUid;
    } catch (error) {
      console.error('[屏幕共享] ❌ 屏幕共享失败:', error);
      FullLoading.hide();
      const err = error as Error & { code?: string };
      if (err.name === 'NotAllowedError' || err.message?.includes('Permission')) {
        const errorWithCause = new Error('您拒绝了屏幕共享权限，无法共享屏幕');
        errorWithCause.cause = error;
        throw errorWithCause;
      }
      if (err.name === 'NotFoundError' || err.message?.includes('cancel')) {
        // 用户取消了选择，不显示错误
        const errorWithCause = new Error('已取消屏幕共享');
        errorWithCause.cause = error;
        throw errorWithCause;
      }
      const errorWithCause = new Error('屏幕共享失败，请重试');
      errorWithCause.cause = error;
      throw errorWithCause;
    }
  }

  /**
   * 清理所有资源
   */
  async function cleanup(): Promise<void> {
    try {
      // 先停止屏幕共享
      await stopScreenTrack();
      await teardownAgoraClient({ toastSuccess: false });
    } catch (error) {
      console.error('清理资源失败:', error);
    }
  }

  /**
   * 离开会议并清理所有资源
   */
  async function leaveChannel(): Promise<void> {
    if (leaveLoading.value) {
      return;
    }
    leaveLoading.value = true;
    try {
      await teardownAgoraClient({ toastSuccess: true });
    } catch (error) {
      console.error('离开会议失败:', error);
      callbacks?.onError?.(error as Error);
    } finally {
      leaveLoading.value = false;
    }
  }

  return {
    /** 是否已加入频道 */
    isJoined,
    /** 是否静音 */
    isMuted,
    /** 是否关闭视频 */
    isVideoOff,
    /** 静音操作加载状态 */
    muteLoading,
    /** 视频操作加载状态 */
    videoLoading,
    /** 离开操作加载状态 */
    leaveLoading,
    /** 网络质量等级 */
    networkQuality,
    /** 远程用户列表 */
    remoteUsers: remoteUsers as Ref<IAgoraRTCRemoteUser[]>,
    /** 本地用户 */
    localUser: localUser as LocalUser,
    /** 当前选中的主视频用户 ID */
    selectedUserUid,
    /** 声网 RTC 客户端 */
    client,
    /** 本地音频轨道 */
    localAudioTrack,
    /** 本地视频轨道 */
    localVideoTrack,
    /** 是否正在共享屏幕 */
    isScreenSharing,
    localScreenUid,
    /** 初始化并加入会议 */
    initAndJoin,
    /** 加入频道 */
    joinChannel,
    /** 离开频道 */
    leaveChannel,
    /** 切换静音 */
    toggleMute,
    /** 切换视频 */
    toggleVideo,
    /** 强制静音 */
    forceMuteAudio,
    /** 强制关闭视频 */
    forceMuteVideo,
    /** 强制解除禁麦 */
    forceUnmuteAudio,
    /** 强制解除禁视频 */
    forceUnmuteVideo,
    /** 开始屏幕共享 */
    startScreenShare,
    /** 停止屏幕共享 */
    stopScreenTrack,
    /** 清理资源 */
    cleanup,
  };
}
