import { jellyfinClient, getPlaystateApi } from '../api/jellyfin'

/**
 * Returns the API client + userId, or null if either is missing. We never
 * throw synchronously from this path - the report* functions are fire-and-
 * forget from useEffect, and a synchronous throw escapes the .catch() on
 * the returned promise, surfacing in the React ErrorBoundary instead of
 * being silently dropped.
 */
function tryGetApi() {
  const api = jellyfinClient.getApi()
  const userId = jellyfinClient.getAuthState()?.userId
  if (!api || !userId) return null
  return { api, userId }
}

/**
 * Common payload bits the server uses to track an active session. Mirrors
 * the fields the official jellyfin-web client sends - in particular the
 * `PlaySessionId` is what lets the server clean up an orphaned transcode
 * when the user closes the window mid-playback, and `PlayMethod` is what
 * the Active Devices dashboard groups on.
 */
export interface PlaybackContext {
  itemId: string
  mediaSourceId?: string
  positionTicks?: number
  playSessionId?: string
  playMethod?: 'DirectPlay' | 'DirectStream' | 'Transcode'
  audioStreamIndex?: number
  subtitleStreamIndex?: number
  isPaused?: boolean
  isMuted?: boolean
  volumeLevel?: number
}

export async function reportPlaybackStart(ctx: PlaybackContext) {
  const conn = tryGetApi()
  if (!conn) return
  await getPlaystateApi(conn.api).reportPlaybackStart({
    playbackStartInfo: {
      ItemId: ctx.itemId,
      MediaSourceId: ctx.mediaSourceId,
      PositionTicks: ctx.positionTicks,
      PlaySessionId: ctx.playSessionId,
      PlayMethod: ctx.playMethod,
      AudioStreamIndex: ctx.audioStreamIndex,
      SubtitleStreamIndex: ctx.subtitleStreamIndex,
      VolumeLevel: ctx.volumeLevel,
      IsMuted: ctx.isMuted,
      CanSeek: true,
    },
  })
}

export async function reportPlaybackProgress(ctx: PlaybackContext) {
  const conn = tryGetApi()
  if (!conn) return
  await getPlaystateApi(conn.api).reportPlaybackProgress({
    playbackProgressInfo: {
      ItemId: ctx.itemId,
      MediaSourceId: ctx.mediaSourceId,
      PositionTicks: ctx.positionTicks,
      PlaySessionId: ctx.playSessionId,
      PlayMethod: ctx.playMethod,
      AudioStreamIndex: ctx.audioStreamIndex,
      SubtitleStreamIndex: ctx.subtitleStreamIndex,
      VolumeLevel: ctx.volumeLevel,
      IsMuted: ctx.isMuted,
      IsPaused: ctx.isPaused ?? false,
      CanSeek: true,
    },
  })
}

export async function reportPlaybackStop(ctx: PlaybackContext) {
  const conn = tryGetApi()
  if (!conn) return
  await getPlaystateApi(conn.api).reportPlaybackStopped({
    playbackStopInfo: {
      ItemId: ctx.itemId,
      MediaSourceId: ctx.mediaSourceId,
      PositionTicks: ctx.positionTicks,
      PlaySessionId: ctx.playSessionId,
    },
  })
}
