import {
  ConnectionQuality,
  RoomConfig,
  RoomInfo,
  Session,
  SessionState,
  Track,
  TranscriptionConfig,
  VirtualBackgroundConfig,
  VirtualBackgroundType,
} from '@zocks-communications/client-sdk-js'
import { ChatAttachmentModel } from '../chat'
import { ErrorResponse } from '../../components'

export interface SessionModel {
  roomId: string | null
  roomName: string | null
  sessionState: SessionState
  isConnecting: boolean
  localParticipant: ParticipantModel
  remoteParticipants: { [id: string]: ParticipantModel }
  speakers: SpeakersModel
}

export interface ParticipantModel {
  id: string | null
  name: string | null
  tracks: ParticipantTracksModel
  connectionQuality: ConnectionQuality
}

export interface ParticipantTracksModel {
  videoTracks: TrackModel[]
  audioTracks: TrackModel[]
  screenShareTrack: TrackModel | null
}

export interface StreamModel {
  id: string
  isMuted: boolean
}

export interface TrackModel extends StreamModel {
  isSubscribed: boolean
}

export interface SpeakersModel {
  activeSpeakers: string[]
  lastSpeakers: string[]
}

export interface SessionView {
  readonly roomId: string | null
  readonly roomName: string | null
  readonly sessionState: SessionState
  readonly isConnecting: boolean
  readonly localParticipant: ParticipantModel
  readonly remoteParticipants: ParticipantModel[]
  readonly localParticipantIsConnected: boolean
}

export interface ParticipantView {
  readonly id: string | null
  readonly name: string | null
  readonly tracks: ParticipantTracksView
  readonly isLocal: boolean
  readonly connectionQuality: ConnectionQuality
  readonly isSpeaking: boolean
  readonly isScreenSharing: boolean
}

export interface ParticipantTracksView {
  readonly videoTracks: TrackView[]
  readonly audioTracks: TrackView[]
  readonly primaryVideoTrack: TrackView | null
  readonly primaryAudioTrack: TrackView | null
  readonly screenShareTrack: TrackView | null
}

export interface TrackView {
  readonly track: Track
  readonly isSubscribed: boolean
  readonly isMuted: boolean
}

export interface JoinOptions {
  readonly roomId?: string
  readonly roomName?: string
  readonly roomConfig?: RoomConfig
  readonly password?: string
  readonly autoCreate?: boolean
  readonly audioDeviceSettings?: MediaTrackSettings
  readonly videoDeviceSettings?: MediaTrackSettings
  readonly virtualBackground?: VirtualBackgroundType | null
  readonly virtualBackgroundConfig?: VirtualBackgroundConfig
  readonly afterJoinCallback?: () => void
  readonly joinErrorCallback?: (e: ErrorResponse | string) => void
  readonly autoSubscribe?: boolean
}

export interface ZocksActions {
  session?: Session
  sessionActions: ZocksSessionActions
  localMediaActions: ZocksMediaActions
  chatActions: ZocksChatActions
  transcriptionActions: ZocksTranscriptionActions
}

export interface ZocksSessionActions {
  createRoom: () => Promise<RoomInfo>
  join: (joinOptions: JoinOptions) => Promise<void>
  leave: () => void
}

export interface ZocksMediaActions {
  publishVideo: (mediaTrackSettings?: MediaTrackSettings) => void
  unPublishVideo: (mediaTrackSettings?: MediaTrackSettings) => void
  publishAudio: (mediaTrackSettings?: MediaTrackSettings) => void
  unPublishAudio: (mediaTrackSettings?: MediaTrackSettings) => void
  publishScreenShare: () => void
  unPublishScreenShare: () => void
  switchActiveDevice: (kind: MediaDeviceKind, deviceId: string) => void
  setVirtualBackground: (
    type: VirtualBackgroundType,
    config?: VirtualBackgroundConfig,
    mediaTrackSettings?: MediaTrackSettings
  ) => Promise<void>
  clearVirtualBackground: (mediaTrackSettings?: MediaTrackSettings) => Promise<void>
}

export interface ZocksChatActions {
  sendPublicMessage: (message: string, attachment?: ChatAttachmentModel) => void
  sendPrivateMessage: (message: string, remoteParticipant: ParticipantModel, attachment?: ChatAttachmentModel) => void
  uploadAttachment: (file: File, remoteParticipant?: ParticipantModel) => Promise<string | undefined>
  getAttachmentLocation: (attachmentFileId: string) => Promise<string | undefined>
}

export interface ZocksTranscriptionActions {
  enableTranscription: (config?: TranscriptionConfig) => Promise<void>
  disableTranscription: () => Promise<void>
  startTranscription: (audioConstraints?: MediaTrackConstraints) => Promise<void>
  stopTranscription: () => Promise<void>
}
