<script>
  import wt from '$/client/wt.js';
  import { onMount, onDestroy } from 'svelte';
  import { defer, random_numbers } from '$/client/helpers.js';
  import { inject_remote } from "./Source.svelte";
  import Spinner from './Spinner.svelte';
  import ProgressMeter from './ProgressMeter.svelte';
  import { log } from "$/client/logging.js";

  export let media;
  // whether to add a download link to download the video
  export let aspect_ratio = "16/9";
  export let autoplay = false;
  export let muted = false;
  export let controls = true;

  let video_ready = false;
  let video_done = false;
  let progress = 0;
  let peers = 0;
  let up_rate = 0;
  let down_rate = 0;
  let time_remaining = 0;
  let activated = false;
  let loading_promise = defer("wt loading promise");

  class VideoEvents extends wt.WTEvents {
    done() {
      video_done = true;
    }

    videoReady(file) {
      super.videoReady(file);
      video_ready = true;

      this.intervalId = setInterval(() => {
        down_rate = (this.torrent.downloadSpeed / 1024 / 1024).toFixed(2);
        up_rate = (this.torrent.uploadSpeed / 1024 / 1024).toFixed(2);
        time_remaining = (this.torrent.timeRemaining / 1000).toFixed(0);
        peers = this.torrent.numPeers;
      }, 1000);
    }

    download_available(url) {
      media.download_url = url;
    }

    download(bytes) {
      let count = Math.floor(this.torrent.progress * 100);

      // don't want to overload svelte with tons of updates, it kind of eats it
      if(count % 2 == 0 || count % 5 == 0) {
        progress = count;
        peers = this.torrent.numPeers;
      }
    }

    wire(wire) {
      log.debug("wire", wire);
      peers = this.torrent.numPeers;
    }

    noPeers(announceType) {
      log.debug("announce", announceType);
      peers = this.torrent.numPeers;
    }
  }

  onDestroy(() => {
    if(activated) wt.remove(media)
  });


  const load_media = async () => {
    if(await wt.fetch_torrent_file(media)) {
      await inject_remote(document, "/js/webtorrent.js", () => {
        // generate a temporary target for the loader div
        media.target_id = random_numbers(1)[0];
        wt.load(media, new VideoEvents(media, {autoplay, controls, muted}));
        activated = true;
        loading_promise.resolve();
      });
    } else {
      log.debug("Failure loading torrent file.");
    }
  }

  onMount(async () => {
    // BUG: this "guard" is here because svelte will load this component
    // twice when its inside an await block. First time it loads it but
    // doesn't set any properties, then the second time it sets the properties.
    if(media && media.torrent_url) {
      await load_media();
    }
  });
</script>

<style>
  video {
    width: 100%;
  }

  card {
    min-width: unset;
    box-shadow: unset;
    border-radius: unset;
    border: unset;
    max-height: calc(95vh - var(--fixed-header-height));
  }

  card top {
    max-height: calc(95vh - var(--fixed-header-height));
  }

  card bottom {
    padding: 0px;
  }
</style>

{#await loading_promise}
  <Spinner color="var(--value4)" aspect_ratio="16/9" />
{:then}
  <card data-testid="video-torrent-body">
    <top style="--aspect-ratio: { aspect_ratio };">
    <video id="append-{media.target_id}"
           muted={muted}
           autoplay={autoplay}
           controls={ controls}
           preload={ media.preload }
           poster={media.poster}>
      </video>
    </top>

    <bottom>
      <ProgressMeter percent={ progress } show_percent={ false } />
    </bottom>
  </card>
{/await}
