/**
 * 双流模式管理 Hook
 * 优化视频流量消耗，根据视频大小设置不同的流类型
 * 声网双流模式：
 * - 0 = 高流（高清视频，适合大窗口播放）
 * - 1 = 低流（低分辨率视频，适合小窗口，节省流量）
 * 计费策略：低流分辨率低，费用更低
 */

import type { IAgoraRTCClient, IAgoraRTCRemoteUser } from 'agora-rtc-sdk-ng';
import { type Ref, ref } from 'vue';
import type { StreamType } from './types';

/**
 * 双流模式管理 Hook
 * @param {Ref<IAgoraRTCClient | null>} clientRef - 声网 RTC 客户端（响应式）
 * @returns {UseStreamTypeReturn} 双流控制方法和状态
 */
export function useStreamType(clientRef: Ref<IAgoraRTCClient | null>) {
  /** 主视频用户 ID（大窗口显示的用户） */
  const mainVideoUid = ref<number | string | null>(null);
  /** 用户流类型映射 */
  const userStreamTypes = ref<Map<number | string, StreamType>>(new Map());

  /**
   * 设置用户的视频流类型
   * @param {number | string} uid - 用户 ID
   * @param {StreamType} streamType - 流类型（0=高流，1=低流）
   */
  async function setUserStreamType(uid: number | string, streamType: StreamType): Promise<void> {
    const client = clientRef.value;
    if (!client) {
      return;
    }
    try {
      await client.setRemoteVideoStreamType(uid, streamType);
      userStreamTypes.value.set(uid, streamType);
      console.log(`设置用户 ${uid} 的流类型为:`, streamType === 0 ? '高流' : '低流');
    } catch (error) {
      console.error(`设置用户 ${uid} 流类型失败:`, error);
    }
  }

  /**
   * 设置主视频用户（大窗口用户用高流，其他用户用低流节省流量）
   * @param {number | string | null} uid - 主视频用户 ID，null 表示没有主视频
   */
  async function setMainVideo(uid: number | string | null): Promise<void> {
    mainVideoUid.value = uid;

    const client = clientRef.value;
    if (!client) {
      return;
    }

    // 获取所有远程用户
    const remoteUsers = client.remoteUsers || [];

    // 为每个用户设置合适的流类型
    const promises = remoteUsers.map(async (user) => {
      if (user.uid === uid) {
        // 主视频用户使用高流
        await setUserStreamType(user.uid, 0);
      } else {
        // 其他用户使用低流节省流量
        await setUserStreamType(user.uid, 1);
      }
    });

    await Promise.all(promises);
  }

  /**
   * 切换主视频用户
   * 如果传入的用户已经是主视频，则取消主视频（所有用户都用低流）
   * 如果传入的用户不是主视频，则设置为主视频（该用户用高流，其他用低流）
   * @param {number | string} uid - 用户 ID
   */
  async function toggleMainVideo(uid: number | string): Promise<void> {
    if (mainVideoUid.value === uid) {
      // 取消主视频，所有用户都用低流
      await setMainVideo(null);
    } else {
      // 设置新的主视频
      await setMainVideo(uid);
    }
  }

  /**
   * 为新加入的用户设置默认流类型
   * 如果有主视频且不是该用户，则使用低流
   * @param {IAgoraRTCRemoteUser} user - 新加入的远程用户
   */
  async function handleNewUser(user: IAgoraRTCRemoteUser): Promise<void> {
    const client = clientRef.value;
    if (!client) {
      return;
    }
    // 如果有主视频且不是该用户，则使用低流
    const streamType: StreamType = mainVideoUid.value && mainVideoUid.value !== user.uid ? 1 : 0;
    await setUserStreamType(user.uid, streamType);
  }

  /**
   * 更新所有用户的流类型
   * 通常在主视频变化时调用
   */
  async function updateAllStreamTypes(): Promise<void> {
    await setMainVideo(mainVideoUid.value);
  }

  /**
   * 获取用户的当前流类型
   * @param {number | string} uid - 用户 ID
   * @returns {StreamType} 流类型，默认为低流
   */
  function getUserStreamType(uid: number | string): StreamType {
    return userStreamTypes.value.get(uid) ?? 1;
  }

  /**
   * 重置所有流类型设置
   * 通常在离开会议时调用
   */
  function reset(): void {
    mainVideoUid.value = null;
    userStreamTypes.value.clear();
  }

  return {
    /** 主视频用户 ID */
    mainVideoUid,
    /** 用户流类型映射 */
    userStreamTypes,
    /** 设置用户流类型 */
    setUserStreamType,
    /** 设置主视频用户 */
    setMainVideo,
    /** 切换主视频用户 */
    toggleMainVideo,
    /** 处理新用户加入 */
    handleNewUser,
    /** 更新所有用户流类型 */
    updateAllStreamTypes,
    /** 获取用户流类型 */
    getUserStreamType,
    /** 重置 */
    reset,
  };
}

export type UseStreamTypeReturn = ReturnType<typeof useStreamType>;
