<script>
  import { Link, useNavigate } from "svelte-navigator";
  import { onMount } from "svelte";
  import Spinner from "./components/Spinner.svelte";
  const navigate = useNavigate();

  export let audioId;
  export let videoId;

  // @ts-ignore
  let ytReady = Boolean(window.YT);

  let videoUrl = "";
  let audioUrl = "";

  let videoReady = false;
  let audioReady = false;

  let videoEl;
  let audioEl;

  let videoPlayer;
  let audioPlayer;

  function extract(url) {
    const match = url.match(/(youtu\.be\/|v=)([\w-]+)/);
    if (match) {
      return match[2];
    } else {
      return "???";
    }
  }

  function synchronize(what) {
    if (what == "audio") {
      audioPlayer.seekTo(videoPlayer.getCurrentTime(), true);
    } else {
      videoPlayer.seekTo(audioPlayer.getCurrentTime(), true);
    }
  }

  async function init() {
    const currentResult = await fetch("grid.php");
    if (!currentResult.ok) {
      alert(currentResult.status);
      return;
    }
    const current = await currentResult.json();
    videoUrl = current.find((link) => link.id == videoId).url;
    audioUrl = current.find((link) => link.id == audioId).url;

    videoEl.innerHTML = "";
    let videoPlayerEl = document.createElement("div");
    videoEl.appendChild(videoPlayerEl);

    // @ts-ignore
    videoPlayer = new YT.Player(videoPlayerEl, {
      videoId: extract(videoUrl),
      events: {
        onReady: () => {
          videoReady = true;
        },
        onStateChange: (ev) => {
          // Paused
          if (ev.data == 2) {
            synchronize("audio");
          }
        },
      },
    });

    audioEl.innerHTML = "";
    let audioPlayerEl = document.createElement("div");
    audioEl.appendChild(audioPlayerEl);

    // @ts-ignore
    audioPlayer = new YT.Player(audioPlayerEl, {
      videoId: extract(audioUrl),
      events: {
        onReady: () => {
          audioReady = true;
        },
        onStateChange: (ev) => {
          // Paused
          if (ev.data == 2) {
            synchronize("video");
          }
        },
      },
    });
  }

  onMount(() => {
    const tag = document.createElement("script");
    tag.src = "https://www.youtube.com/iframe_api";
    const firstScriptTag = document.getElementsByTagName("script")[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

    // @ts-ignore
    window.onYouTubeIframeAPIReady = () => {
      ytReady = true;
    };
  });

  $: {
    audioId;
    videoId;

    if (ytReady) {
      init();
    }
  }

  function go() {
    videoPlayer.playVideo();
    videoPlayer.mute();
    audioPlayer.playVideo();
  }

  async function onBroken(id) {
    const result = await fetch(`grid.php?id=${id}`, {
      method: "DELETE",
    });
    if (result.ok) {
      alert(`ID ${id} marked as broken, thanks!`);
      navigate("/");
    } else {
      alert(`ERR: ${result.status} ${result.statusText}`);
    }
  }
</script>

<main>
  <a
    class="link"
    class:disabled={!videoReady || !audioReady}
    href="javascript:;"
    on:click={go}>START</a
  >

  <div id="player">
    <h2 title={videoUrl}>Video</h2>
    {#if !videoReady}<Spinner />{/if}
    <div id="videoPlayer" bind:this={videoEl} />
    <a class="broken" href="javascript:;" on:click={() => onBroken(videoId)}
      >broken?</a
    >
    <h2 title={audioUrl}>Audio</h2>
    {#if !audioReady}<Spinner />{/if}
    <div id="audioPlayer" bind:this={audioEl} />
    <a class="broken" href="javascript:;" on:click={() => onBroken(audioId)}
      >broken?</a
    >
  </div>

  <Link class="link" to="/">BACK</Link>
</main>

<style>
  main {
    text-align: center;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
  }

  :global(.link) {
    font-family: inherit;
    font-size: inherit;
    padding: 1em 2em;
    margin: 2rem;
    color: white;
    background-color: rgba(255, 255, 255, 0.25);
    border-radius: 2em;
    border: 2px solid rgba(255, 255, 255, 0);
    outline: none;
    width: 200px;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
    text-decoration: none;
  }

  :global(#audioPlayer > *) {
    height: 128px;
  }

  a {
    color: red;
    opacity: 0.5;
    font-size: 80%;
  }

  .disabled {
    color: gray;
    cursor: not-allowed;
  }
</style>
