import WorldCollection from "../abstract/world-collection.mjs";

/**
 * @import Playlist from "../playlist.mjs";
 * @import Scene from "../scene.mjs";
 */

/**
 * The singleton collection of Playlist documents which exist within the active World.
 * This Collection is accessible within the Game object as game.playlists.
 * @extends {WorldCollection<Playlist>}
 * @category Collections
 *
 * @see {@link foundry.documents.Playlist}: The Playlist document
 * @see {@link foundry.applications.sidebar.tabs.PlaylistDirectory}: The PlaylistDirectory sidebar
 *   directory
 */
export default class Playlists extends WorldCollection {

  /** @override */
  static documentName = "Playlist";

  /* -------------------------------------------- */

  /**
   * Return the subset of Playlist documents which are currently playing
   * @type {Playlist[]}
   */
  get playing() {
    return this.filter(s => s.playing);
  }

  /* -------------------------------------------- */

  /**
   * The playlist / playlist sound of the active scene.
   * @type {{playlistId: string|null; playlistSoundId: string|null}}
   */
  #sceneState = {playlistId: null, playlistSoundId: null};

  /* -------------------------------------------- */

  /**
   * Perform one-time initialization to begin playback of audio.
   * @returns {Promise<void>}
   */
  async initialize() {
    const activeScene = game.scenes.active;
    if ( activeScene ) {
      this.#sceneState.playlistId = activeScene.playlist?.id ?? null;
      this.#sceneState.playlistSoundId = activeScene.playlistSound?.id ?? null;
    }
    await game.audio.unlock;
    for ( const playlist of this ) {
      for ( const sound of playlist.sounds ) sound.sync();
    }
    ui.playlists?.render();
  }

  /* -------------------------------------------- */

  /**
   * Handle changes to a Scene to determine whether to trigger changes to Playlist documents.
   * @param {Scene|null} scene   The new active Scene
   * @internal
   */
  async _onChangeScene(scene) {
    const {playlist, playlistSound} = scene ?? {};
    const playlistId = playlist?.id ?? null;
    const playlistSoundId = playlistSound?.id ?? null;
    const {playlistId: priorPlaylistId, playlistSound: priorPlaylistSoundId} = this.#sceneState;
    const soundChange = (playlistId !== priorPlaylistId) || (playlistSoundId !== priorPlaylistSoundId);
    if ( !soundChange ) return;
    this.#sceneState.playlistId = playlistId;
    this.#sceneState.playlistSoundId = playlistSoundId;
    const priorPlaylist = this.get(priorPlaylistId);
    if ( priorPlaylist ) {
      const priorPlaylistSound = priorPlaylist.sounds.get(priorPlaylistSoundId);
      if ( priorPlaylistSound ) await priorPlaylistSound.update({playing: false});
      else if ( !priorPlaylistSoundId ) await priorPlaylist.stopAll();
    }
    if ( playlistSound ) await playlistSound.update({playing: true});
    else if ( playlist ) await playlist.playAll();
  }
}
