import {
  Room,
  RoomEvent,
  createLocalTracks,
  createLocalAudioTrack,
  createLocalVideoTrack,
} from 'livekit-client'

console.log("Room 构造函数:", Room)

class Trtc {
  constructor() {
    this.room = null
    this.localTracks = []
  }

  // 安全 attach 远端轨道
  attachTrack(track, participant) {
    const container = document.getElementById('video-' + participant.identity)
    if (!container) return

    // 已经 attach 过就跳过，避免闪屏
    if (track.attachedElements.length > 0) return

    const element = track.attach()
    element.style.width = '100%'
    element.style.height = '100%'
    element.style.objectFit = 'cover'
    container.appendChild(element)
  }

  async joinRoom(token, url, userId, onRemoteTrack) {
    try {
      // 如果已有房间，先退出
      if (this.room) {
        await this.leaveRoom()
      }

      this.room = new Room()

      // 监听远端轨道
      this.room.on(RoomEvent.TrackSubscribed, (track, publication, participant) => {
        console.log('📡 TrackSubscribed:', track.kind, participant.identity)
        if (track.kind === 'video' || track.kind === 'audio') {
          this.attachTrack(track, participant)
          if (typeof onRemoteTrack === 'function') {
            onRemoteTrack(track, participant)
          }
        }
      })

      // 检查设备
      this.localTracks = []
      if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {
        const devices = await navigator.mediaDevices.enumerateDevices()
        const hasMic = devices.some(d => d.kind === 'audioinput')
        const hasCam = devices.some(d => d.kind === 'videoinput')

        if (hasMic || hasCam) {
          this.localTracks = await createLocalTracks({
            audio: hasMic,
            video: hasCam,
          })
          console.log('本地轨道列表:', this.localTracks)
        } else {
          console.warn('未检测到摄像头或麦克风，将以静默方式加入房间')
        }
      } else {
        console.warn('当前环境不支持 mediaDevices，将以纯接收模式加入房间')
      }

      console.log('发起连接到 LiveKit ...', url)

      // 监听连接状态
      const connectedPromise = new Promise((resolve, reject) => {
        const timeout = setTimeout(() => {
          reject(new Error('连接 LiveKit 超时'))
        }, 15000)

        try {
          this.room.once(RoomEvent.Connected, () => {
            clearTimeout(timeout)
            console.log('成功连接到 LiveKit 房间')
            resolve()

            // 主动挂载已有轨道
            if (this.room.participants && typeof this.room.participants.values === 'function') {
              for (const participant of this.room.participants.values()) {
                participant.tracks.forEach(publication => {
                  if (publication.isSubscribed && publication.track) {
                    this.attachTrack(publication.track, participant)
                    if (typeof onRemoteTrack === 'function') {
                      onRemoteTrack(publication.track, participant)
                    }
                  }
                })
              }
            }
          })

          this.room.once(RoomEvent.ConnectionError, (err) => {
            clearTimeout(timeout)
            console.error('LiveKit 连接错误:', err)
            reject(err)
          })
        } catch (e) {
          console.error('LiveKit连接失败:', e)
        }
      })

      this.room.on(RoomEvent.Disconnected, () => {
        console.warn('与 LiveKit 断开连接')
      })

      // 发起连接
      await this.room.connect(url, token, {
        autoSubscribe: true,
      })

      await connectedPromise

      // 发布本地轨道
      for (const track of this.localTracks) {
        console.log('正在发布轨道:', track.kind)
        await this.room.localParticipant.publishTrack(track)
      }

      return this.room
    } catch (err) {
      console.error('joinRoom 出错:', err)
      throw err
    }
  }

  getLocalVideoTrack() {
    return this.localTracks.find(t => t.kind === 'video') || null
  }

  async leaveRoom() {
    if (this.room) {
      console.log("Trtc 离开房间")

      // 停止并释放本地轨道
      this.localTracks.forEach(track => {
        try {
          track.stop()
          track.detach()
        } catch (e) {
          console.warn("轨道释放失败:", e)
        }
      })

      try {
        await this.room.disconnect()
      } catch (e) {
        console.error("房间断开异常:", e)
      }

      this.room = null
      this.localTracks = []
    } else {
      this.room = null
      console.warn("离开房间 时 room 为 null")
    }
  }
}

export {
  createLocalAudioTrack,
  createLocalVideoTrack,
}
export default new Trtc()
