(function main() {
  'use strict';

  // Captions
  let captionsActive = false;
  if (data.settings.subtitles_mode === 2 || (data.settings.subtitles_mode === 1 && data.has_manual_captions)) {
    captionsActive = true;
  }

  // AutoPlay
  let autoplayActive = data.settings.autoplay_videos || false;

  let qualityOptions = [];
  let qualityDefault;

  // Collect uni sources (integrated)
  for (let src of data.uni_sources) {
    qualityOptions.push(src.quality_string);
  }

  // Collect pair sources (av-merge)
  for (let src of data.pair_sources) {
    qualityOptions.push(src.quality_string);
  }

  if (data.using_pair_sources) {
    qualityDefault = data.pair_sources[data.pair_idx].quality_string;
  } else if (data.uni_sources.length !== 0) {
    qualityDefault = data.uni_sources[data.uni_idx].quality_string;
  } else {
    qualityDefault = 'None';
  }

  // Current av-merge instance
  let avMerge = null;

  // Change quality: handles both uni (integrated) and pair (av-merge)
  function changeQuality(selection) {
    let currentVideoTime = video.currentTime;
    let videoPaused = video.paused;
    let videoSpeed = video.playbackRate;
    let srcInfo;

    // Close previous av-merge if any
    if (avMerge && typeof avMerge.close === 'function') {
      avMerge.close();
    }

    if (selection.type == 'uni') {
      srcInfo = data.uni_sources[selection.index];
      video.src = srcInfo.url;
      avMerge = null;
    } else {
      srcInfo = data.pair_sources[selection.index];
      avMerge = new AVMerge(video, srcInfo, currentVideoTime);
    }

    video.currentTime = currentVideoTime;
    if (!videoPaused) {
      video.play();
    }
    video.playbackRate = videoSpeed;
  }

  // Fix plyr refusing to work with qualities that are strings
  Object.defineProperty(Plyr.prototype, 'quality', {
    set: function (input) {
      const config = this.config.quality;
      const options = this.options.quality;
      let quality = input;
      let updateStorage = true;

      if (!options.length) {
        return;
      }

      if (!options.includes(quality)) {
        return;
      }

      // Update config
      config.selected = quality;

      // Set quality
      this.media.quality = quality;

      // Save to storage
      if (updateStorage) {
        this.storage.set({ quality });
      }
    },
  });

  const playerOptions = {
    autoplay: autoplayActive,
    disableContextMenu: false,
    captions: {
      active: captionsActive,
      language: data.settings.subtitles_language,
    },
    controls: [
      'play-large',
      'play',
      'progress',
      'current-time',
      'duration',
      'mute',
      'volume',
      'captions',
      'settings',
      'pip',
      'airplay',
      'fullscreen',
    ],
    iconUrl: '/youtube.com/static/modules/plyr/plyr.svg',
    blankVideo: '/youtube.com/static/modules/plyr/blank.webm',
    debug: false,
    storage: { enabled: false },
    quality: {
      default: qualityDefault,
      options: qualityOptions,
      forced: true,
      onChange: function (quality) {
        if (quality == 'None') {
          return;
        }
        // Check if it's a uni source (integrated)
        if (quality.includes('(integrated)')) {
          for (let i = 0; i < data.uni_sources.length; i++) {
            if (data.uni_sources[i].quality_string == quality) {
              changeQuality({ type: 'uni', index: i });
              return;
            }
          }
        } else {
          // It's a pair source (av-merge)
          for (let i = 0; i < data.pair_sources.length; i++) {
            if (data.pair_sources[i].quality_string == quality) {
              changeQuality({ type: 'pair', index: i });
              return;
            }
          }
        }
      },
    },
    previewThumbnails: {
      enabled: storyboard_url !== null,
      src: [storyboard_url],
    },
    settings: ['captions', 'quality', 'speed', 'loop'],
    tooltips: {
      controls: true,
    },
  };

  const video = document.getElementById('js-video-player');
  const player = new Plyr(video, playerOptions);

  // Hide audio track selector (DASH doesn't support multi-audio)
  const audioContainer = document.getElementById('plyr-audio-container');
  if (audioContainer) audioContainer.style.display = 'none';

  // disable double click to fullscreen
  player.eventListeners.forEach(function(eventListener) {
    if(eventListener.type === 'dblclick') {
        eventListener.element.removeEventListener(eventListener.type, eventListener.callback, eventListener.options);
    }
  });

  // Add .started property
  player.started = false;
  player.once('playing', function(){ this.started = true; });

  // Set initial time
  if (data.time_start != 0) {
    video.addEventListener('loadedmetadata', function() {
      video.currentTime = data.time_start;
    });
  }
})();
