/**
 * Platform playback capabilities, read from Rust.
 *
 * TRACES: UR-003, UR-005 | DR-004, DR-152
 *
 * "Which backend does this platform have" is a *backend* fact, so Rust owns it
 * (`player_get_capabilities`, gated on the same `cfg!` the backends are built
 * under). This module is a thin cache over that command.
 *
 * It exists because the frontend used to re-derive the answer by sniffing
 * `navigator.userAgent` for "android"/"linux" — a second, silently drifting copy
 * of a decision Rust already makes. Consume the value; never re-derive it.
 */

import { commands } from "$lib/api/bindings";

export interface PlaybackCapabilities {
  /** Audio renders through a webview `<audio>` element, not a native backend. */
  usesWebviewAudio: boolean;
  /** Video can render on a native surface behind a transparent webview. */
  supportsNativeVideo: boolean;
}

/**
 * Conservative defaults for when the backend cannot be reached (very early
 * startup, or a command failure). Both false = "assume no special platform
 * facilities": no stray `<audio>` element is mounted, and video stays on the
 * HTML5 path, which is the safe behaviour everywhere.
 */
const FALLBACK: PlaybackCapabilities = {
  usesWebviewAudio: false,
  supportsNativeVideo: false,
};

let cached: PlaybackCapabilities | null = null;
let inflight: Promise<PlaybackCapabilities> | null = null;

/**
 * Fetch (and memoize) this platform's capabilities. Cached because the answer is
 * compile-time constant in Rust — it cannot change during a session.
 */
export async function getPlaybackCapabilities(): Promise<PlaybackCapabilities> {
  if (cached) return cached;
  if (inflight) return inflight;

  inflight = (async () => {
    try {
      const caps = (await commands.playerGetCapabilities()) as PlaybackCapabilities;
      cached = {
        usesWebviewAudio: !!caps?.usesWebviewAudio,
        supportsNativeVideo: !!caps?.supportsNativeVideo,
      };
      return cached;
    } catch (err) {
      console.warn("[capabilities] player_get_capabilities failed:", err);
      // Do NOT cache the fallback — a later call should get the real answer.
      return FALLBACK;
    } finally {
      inflight = null;
    }
  })();

  return inflight;
}

/** Reset the cache. Test-only. */
export function __resetPlaybackCapabilitiesCache(): void {
  cached = null;
  inflight = null;
}
