<template>
  <table class="table is-fullwidth is-striped">
    <thead>
      <tr>
        <th>title</th>
        <th>year</th>
        <th>type</th>
        <th>rating</th>
        <th>runtime</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="item in items" :data-unwind-id="item.id">
        <td v-if="item.original_title">
          <a :href="`https://www.imdb.com/title/${item.imdb_id}/`">
            <span>{{ item.original_title }}</span>
          </a>
          <span v-if="item.title != item.original_title"> ({{ item.title }})</span>
        </td>
        <td v-else>
          <a :href="`https://www.imdb.com/title/${item.imdb_id}/`">
            <span>{{ item.title }}</span>
          </a>
        </td>
        <td>
          <span class="year">{{ item.release_year }}</span>
        </td>
        <td>
          <span class="mediatype">{{ item.media_type }}</span>
        </td>
        <td>
          <span
            class="score imdb-score tag is-large"
            :title="`IMDb rating (1-10) / ${item.imdb_votes} votes`"
            >{{ imdb_rating(item.imdb_score) }}</span
          >
          <span
            class="score tag is-info is-large"
            :title="`User rating (1-10) / ${
              item.user_scores.length
            } votes / σ = ${imdb_stdev(item.user_scores)}`"
            >{{ avg_imdb_rating(item.user_scores) }}</span
          >
        </td>
        <td>
          <span>{{ duration(item.runtime) }}</span>
        </td>
      </tr>
    </tbody>
  </table>

  <div ref="sentinel"></div>
</template>

<script lang="ts">
import { defineComponent } from "vue"
import { mean, pstdev } from "../utils.ts"

function avg_imdb_rating(scores) {
  return imdb_rating(scores.length === 0 ? null : mean(scores))
}

function imdb_stdev(scores) {
  return pstdev(scores.map(imdb_rating_from_score))
}

function imdb_rating_from_score(score) {
  return Math.round((score * 9) / 10 + 10) / 10
}

function imdb_rating(score) {
  if (score == null) {
    return "-"
  }

  const deci = 10 * imdb_rating_from_score(score)
  return `${(deci / 10) | 0}.${deci % 10}`
}

function duration(minutes_total) {
  if (minutes_total == null) {
    return "-"
  }

  const m = minutes_total % 60
  const h = (minutes_total / 60) | 0
  return `${h} h ${m} m`
}

export default defineComponent({
  props: {
    items: {
      type: Array,
      required: true,
    },
  },
  emits: ["reach-bottom"],
  mounted() {
    const options = {
      rootMargin: "500px",
    }
    const observer = new IntersectionObserver(([e]) => {
      if (!e.isIntersecting) {
        return
      }
      this.$emit("reach-bottom")
    }, options)
    observer.observe(this.$refs.sentinel)
  },
  methods: {
    avg_imdb_rating,
    imdb_rating,
    imdb_stdev,
    duration,
  },
})
</script>

<style scoped>
.year {
  color: grey;
}
.mediatype {
  color: grey;
}
.score {
  width: 2em;
  height: 2em;
}
.score + .score {
  margin-left: 1em;
}
.imdb-score {
  background-color: rgb(245, 197, 24);
}
.user-score {
}
</style>
