/**
 * Choosing between a downloaded file and a server stream for video playback.
 *
 * Audio has preferred local files since the queue is built (the Rust queue
 * resolves `MediaSource::Local`), but video asks the repository for a stream URL
 * and never consults `downloads` — so a downloaded film was streamed anyway,
 * spending bandwidth that had already been spent and failing outright offline.
 *
 * Pure so it can be unit-tested: the component only supplies the two inputs and
 * the asset-URL converter.
 *
 * TRACES: UR-071 | DR-123 | UT-118
 */

export interface VideoSourceInputs {
  /** Absolute on-disk path of a completed download, or null to stream. */
  localPath: string | null;
  /** Stream URL the repository resolved (already transcoded if it had to be). */
  remoteUrl: string;
  /** Whether the *remote* stream is a transcode. */
  remoteNeedsTranscoding: boolean;
  /** Usually Tauri's `convertFileSrc`; injected so this module stays pure. */
  toAssetUrl: (path: string) => string;
}

export interface VideoSourceDecision {
  /** What to hand the `<video>` element. */
  url: string;
  /**
   * Local files are never transcodes, so this is always false for them. It
   * matters because the transcoded path re-requests a whole new stream URL on
   * every seek; a local file seeks natively and must not go down that route.
   */
  needsTranscoding: boolean;
  /** True when playing from disk — for logging and the offline badge. */
  isLocal: boolean;
}

/** Absolute on POSIX (`/…`), Windows (`C:\…`, `C:/…`) or a UNC share (`\\…`). */
function isAbsolute(path: string): boolean {
  return path.startsWith("/") || path.startsWith("\\") || /^[A-Za-z]:[\\/]/.test(path);
}

/**
 * The on-disk path of a row in the `downloads` store.
 *
 * `downloads.file_path` is stored relative to the storage root while a download
 * is queued, but the worker rewrites it to the absolute path it actually wrote
 * once the transfer completes — so a *completed* row is already rooted. Joining
 * it onto the storage root a second time produced
 * `/data/user/0/app//data/user/0/app/videos/x.mp4`; the asset protocol could not
 * open that, so offline video failed with `MEDIA_ERR_SRC_NOT_SUPPORTED` while
 * audio, which resolves the same column through Rust, played fine.
 *
 * TRACES: UR-071 | DR-133 | UT-124
 */
export function downloadedFilePath(storageRoot: string, filePath: string): string {
  return isAbsolute(filePath) ? filePath : `${storageRoot}/${filePath}`;
}

export function resolveVideoSource(inputs: VideoSourceInputs): VideoSourceDecision {
  const { localPath, remoteUrl, remoteNeedsTranscoding, toAssetUrl } = inputs;

  // Treat blank/whitespace paths as absent — a malformed `downloads` row must
  // not produce an asset URL pointing at nothing.
  if (localPath && localPath.trim() !== "") {
    return { url: toAssetUrl(localPath), needsTranscoding: false, isLocal: true };
  }

  return { url: remoteUrl, needsTranscoding: remoteNeedsTranscoding, isLocal: false };
}
