/**
 * 会议室权限管理 Hook
 * 实现创建者的控制功能：踢人、禁麦、禁视频
 * 通过 WebSocket 消息通道发送控制指令
 */

import { type Ref, computed, reactive, ref } from 'vue';
import { useRoute } from 'vue-router';
import type { ControlCommandType, MeetingClientSocket, UserPermission } from './types';

/**
 * 会议室权限管理 Hook
 * @param {Ref<IAgoraRTCClient | null>} clientRef - 声网 RTC 客户端（响应式，client 就绪后自动注册监听）
 * @param {Ref<number | string | null>} localUidRef - 本地用户 ID（声网分配的真实 uid）
 * @param { Socket } socket - Socket.IO 客户端实例（用于发送控制消息）
 * @param {Ref<string>} roomIdRef - 房间 ID
 */
export function usePermissions(socket: MeetingClientSocket, roomIdRef: Ref<string>) {
  /** 用户权限状态映射 */
  const userPermissions = reactive<Map<number | string, UserPermission>>(new Map());
  /** 是否正在发送消息 */
  const isSending = ref(false);
  const route = useRoute();
  /** 用户角色 */
  const role = ref<'student' | 'teacher'>(String(route.query.role) === 'student' ? 'student' : 'teacher');
  /** 是否为创建者 */
  const isHost = computed(() => role.value === 'teacher');

  /**
   * 发送控制消息给指定用户（通过 WebSocket）
   * @param {AllowedControlEvent} type - 控制类型
   * @param {number | string} targetUid - 目标用户 ID（声网的短 UID，后端也使用短 UID 存储）
   */
  function sendControlMessage(type: ControlCommandType, targetUid: number | string) {
    if (!socket || !isHost.value) {
      console.warn('无法发送控制消息：WebSocket 未连接或非创建者');
      return;
    }

    try {
      isSending.value = true;

      // 确保 targetUid 是数字类型（后端使用数字类型匹配）
      const numericTargetUid = typeof targetUid === 'string' ? Number(targetUid) : targetUid;

      // 直接使用声网的短 UID（后端也使用短 UID 存储）
      console.log(`[权限] 发送控制消息：type=${type}, targetUid=${numericTargetUid}, roomId=${roomIdRef.value}`);

      // 通过 WebSocket 发送控制消息
      socket.emit(type, { targetUid: numericTargetUid, roomId: roomIdRef.value });
      console.log('控制消息已发送:', type, { targetUid: numericTargetUid, roomId: roomIdRef.value });

      // 更新本地权限状态
      updateLocalPermission(numericTargetUid, type);
    } catch (error) {
      console.error('发送控制消息失败:', error);
    } finally {
      isSending.value = false;
    }
  }

  /**
   * 更新本地权限状态
   * @param {number | string} uid - 用户 ID
   * @param {ControlCommandType} type - 控制类型
   */
  function updateLocalPermission(uid: number | string, type: ControlCommandType): void {
    const permission = userPermissions.get(uid) || {
      uid,
      isAudioMuted: false,
      isVideoMuted: false,
      isKicked: false,
    };

    switch (type) {
      case 'client_mute_audio':
        permission.isAudioMuted = true;
        break;
      case 'client_unmute_audio':
        permission.isAudioMuted = false;
        break;
      case 'client_mute_video':
        permission.isVideoMuted = true;
        break;
      case 'client_unmute_video':
        permission.isVideoMuted = false;
        break;
      case 'client_kick_user':
        permission.isKicked = true;
        break;
      default:
        break;
    }

    userPermissions.set(uid, permission);
  }

  /**
   * 禁麦指定用户
   * @param {number | string} uid - 目标用户 ID
   */
  async function muteUserAudio(uid: number | string): Promise<void> {
    await sendControlMessage('client_mute_audio', uid);
  }

  /**
   * 解除禁麦指定用户
   * @param {number | string} uid - 目标用户 ID
   */
  async function unmuteUserAudio(uid: number | string): Promise<void> {
    await sendControlMessage('client_unmute_audio', uid);
  }

  /**
   * 禁视频指定用户
   * @param {number | string} uid - 目标用户 ID
   */
  async function muteUserVideo(uid: number | string): Promise<void> {
    await sendControlMessage('client_mute_video', uid);
  }

  /**
   * 解除禁视频指定用户
   * @param {number | string} uid - 目标用户 ID
   */
  async function unmuteUserVideo(uid: number | string): Promise<void> {
    await sendControlMessage('client_unmute_video', uid);
  }

  /**
   * 踢出指定用户
   * @param {number | string} uid - 目标用户 ID
   */
  async function kickUser(uid: number | string): Promise<void> {
    await sendControlMessage('client_kick_user', uid);
  }

  /**
   * 设置某个用户为全员主屏（仅创建者）
   * @param {number | string} uid - 目标用户 ID（短 UID）
   */
  async function setMainVideoGlobal(uid: number | string): Promise<void> {
    await sendControlMessage('client_set_main_video', uid);
  }

  /**
   * 获取用户的权限状态
   * @param {number | string} uid - 用户 ID
   * @returns {UserPermission | undefined} 权限状态
   */
  function getUserPermission(uid: number | string): UserPermission | undefined {
    return userPermissions.get(uid);
  }

  /**
   * 检查用户是否被禁麦
   * @param {number | string} uid - 用户 ID
   * @returns {boolean} 是否被禁麦
   */
  function isUserAudioMuted(uid: number | string): boolean {
    return userPermissions.get(uid)?.isAudioMuted ?? false;
  }

  /**
   * 检查用户是否被禁视频
   * @param {number | string} uid - 用户 ID
   * @returns {boolean} 是否被禁视频
   */
  function isUserVideoMuted(uid: number | string): boolean {
    return userPermissions.get(uid)?.isVideoMuted ?? false;
  }

  /**
   * 重置权限状态
   */
  function reset(): void {
    userPermissions.clear();
  }

  return {
    /** 用户权限状态映射 */
    userPermissions,
    /** 是否正在发送消息 */
    isSending,
    /** 禁麦用户 */
    muteUserAudio,
    /** 解除禁麦 */
    unmuteUserAudio,
    /** 禁视频 */
    muteUserVideo,
    /** 解除禁视频 */
    unmuteUserVideo,
    /** 踢出用户 */
    kickUser,
    /** 设置全员主屏 */
    setMainVideoGlobal,
    /** 获取用户权限 */
    getUserPermission,
    /** 检查用户是否被禁麦 */
    isUserAudioMuted,
    /** 检查用户是否被禁视频 */
    isUserVideoMuted,
    /** 重置 */
    reset,
  };
}

export type UsePermissionsReturn = ReturnType<typeof usePermissions>;
