<template>
  <v-container fluid>

    <v-data-table
    :headers="headers"
    :items="displayItems"
    item-key="group"
    :options.sync="options"
    :expanded.sync="expanded"
    show-expand
    :loading="loading"
    >

      <template v-slot:item.group="{item, value}">
        <v-chip
          label
          small
          :href="`./${value}`"
        >{{ value }}</v-chip>
      </template>

      <template v-slot:item.shots_total="{item, value}">
        <div>{{ item.prime + item.other }}</div>
        <v-progress-linear
          background-color="secondary"
          color="primary"
          :value="item.prime/(item.prime+item.other)*100"
        ></v-progress-linear>
      </template>

      <template v-slot:item.prime="{item, value}">
        {{ value }}
        ({{ (value / (item.prime + item.other) * 100).toFixed(1) }}%)
      </template>

      <template v-slot:item.other="{item, value}">
        {{ value }}
        ({{ (value / (item.prime + item.other) * 100).toFixed(1) }}%)
      </template>

      <template v-slot:item.prod_duration="{item, value}">
        <span v-if="value.days > 2" :title="`${value.days} d ${value.hours} h ${value.minutes} m ${(value.seconds + value.milliseconds/1000).toFixed(3)} s`">
          {{ value.days }} d
        </span>
        <span v-else>
          {{ value.days }} d {{ value.hours }} h {{ value.minutes }} m {{ (value.seconds + value.milliseconds/1000).toFixed(1) }} s
        </span>
      </template>

      <template v-slot:item.prod_distance="{item, value}">
        {{ (value/1000).toFixed(1) }} km
      </template>

      <template v-slot:item.shooting_rate_mean="{item, value}">
        {{ (value).toFixed(2) }} s ±{{ (item.shooting_rate_sd).toFixed(3) }} s
      </template>

      <template v-slot:item.shots_per_point="{item, value}">
        <div>
          {{ ((item.prime + item.other)/item.points).toFixed(1) }}
          ({{ ((((item.prime + item.other)/item.points) / item.num_projects)*100).toFixed(2) }}%)
        </div>
        <v-progress-linear
          :value="((((item.prime + item.other)/item.points) / item.num_projects)*100)"
        ></v-progress-linear>
      </template>

      <template v-slot:expanded-item="{ headers, item }">
        <td :colspan="headers.length">
          <v-data-table class="ma-1"
            :headers="projectHeaders"
            :items="item.projects"
            dense
            hide-default-footer
          >

            <template v-slot:item.pid="{item, value}">
              <a :href="`/projects/${value}`" title="Go to project">{{ value }}</a>
            </template>

            <template v-slot:item.fsp="{item, value}">
              <span title="First production shot">{{value.tstamp.substr(0, 10)}}</span>
            </template>

            <template v-slot:item.lsp="{item, value}">
              <span title="Last production shot">{{value.tstamp.substr(0, 10)}}</span>
            </template>

            <template v-slot:item.prod_duration="{item, value}">
              <span v-if="value.days > 2" :title="`${value.days} d ${value.hours} h ${value.minutes} m ${(value.seconds + value.milliseconds/1000).toFixed(3)} s`">
                {{ value.days }} d
              </span>
              <span v-else>
                {{ value.days }} d {{ value.hours }} h {{ value.minutes }} m {{ (value.seconds + value.milliseconds/1000).toFixed(1) }} s
              </span>
            </template>

            <template v-slot:item.prod_distance="{item, value}">
              {{ (value/1000).toFixed(1) }} km
            </template>

          </v-data-table>
        </td>
      </template>

    </v-data-table>

  </v-container>
</template>

<style>
td p:last-of-type {
  margin-bottom: 0;
}
</style>

<script>
import { mapActions, mapGetters } from 'vuex';
import AccessMixin from '@/mixins/access';


// FIXME send to lib/utils or so
/*
function duration_to_ms(v) {
  if (v instanceof Object) {
    return (
      (v.days || 0) * 86400000 +
      (v.hours || 0) * 3600000 +
      (v.minutes || 0) * 60000 +
      (v.seconds || 0) * 1000 +
      (v.milliseconds || 0)
    );
  } else {
    return {
      days: 0,
      hours: 0,
      minutes: 0,
      seconds: 0,
      milliseconds: 0
    }
  }
}

function ms_to_duration(v) {
  const days = Math.floor(v / 86400000);
  v %= 86400000;
  const hours = Math.floor(v / 3600000);
  v %= 3600000;
  const minutes = Math.floor(v / 60000);
  v %= 60000;
  const seconds = Math.floor(v / 1000);
  const milliseconds = v % 1000;
  return { days, hours, minutes, seconds, milliseconds };
}

function normalise_duration (v) {
  return ms_to_duration(duration_to_ms(v));
}

function add_durations(a, b) {
  return ms_to_duration(duration_to_ms(a) + duration_to_ms(b));
}
*/

export default {
  name: "GroupList",

  components: {
  },

  mixins: [
    AccessMixin
  ],

  data () {
    return {
      headers: [
        {
          value: "group",
          text: "Group name"
        },
        {
          value: "num_projects",
          text: "Number of campaigns"
        },
        {
          value: "lines",
          text: "Preplot lines"
        },
        {
          value: "points",
          text: "Preplot points"
        },
        {
          value: "sequences",
          text: "Total sequences"
        },
        {
          value: "shots_total",
          text: "Total shots"
        },
        {
          value: "prime",
          text: "Total prime"
        },
        {
          value: "other",
          text: "Total reshoot + infill"
        },
        /*
        {
          value: "ntba",
          text: "Total NTBA"
        },
        */
        {
          value: "prod_duration",
          text: "Total duration"
        },
        {
          value: "prod_distance",
          text: "Total distance"
        },
        {
          value: "shooting_rate_mean",
          text: "Shooting rate (mean)"
        },
        {
          value: "shots_per_point",
          text: "Shots per point"
        },
      ],
      items: [],
      expanded: [],
      options: { sortBy: ["group"], sortDesc: [false] },

      projectHeaders: [
        {
          value: "pid",
          text: "ID"
        },
        {
          value: "name",
          text: "Name"
        },
        {
          value: "fsp",
          text: "Start"
        },
        {
          value: "lsp",
          text: "Finish"
        },
        {
          value: "lines",
          text: "Preplot lines"
        },
        {
          value: "seq_final",
          text: "Num. of sequences"
        },
        {
          value: "prod_duration",
          text: "Duration"
        },
        {
          value: "prod_distance",
          text: "Distance"
        },
      ],

      // Context menu stuff
      contextMenuShow: false,
      contextMenuX: 0,
      contextMenuY: 0,
      contextMenuItem: null,

      /*
      // FIXME Eventually need to move this into Vuex
      groups: []
      */
    }
  },

  computed: {
    displayItems () {
      return this.items.filter(i => i.prod_distance);
    },

    ...mapGetters(['loading', 'groups'])
  },

  methods: {

    /*
    async prepareGroups () {
      //const groups = await this.api(["/prospects"]);
      //console.log("groups", groups);
      const groups = {};

      for (const project of this.projects) {

        if (!project.prod_distance) {
          // This project has no production data (either not started yet
          // or production data has not been imported) so we skip it.
          continue;
        }

        if (!project.prod_duration.days) {
          project.prod_duration = normalise_duration(project.prod_duration);
        }

        for (const name of project.groups) {
          if (!(name in groups)) {
            groups[name] = {
              group: name,
              num_projects: 0,
              lines: 0,
              points: 0,
              sequences: 0,
              // Shots:
              prime: 0,
              other: 0,
              ntba: 0,
              prod_duration: {
                days: 0,
                hours: 0,
                minutes: 0,
                seconds: 0,
                milliseconds: 0
              },
              prod_distance: 0,
              shooting_rate: [],
              projects: []
            };
          }
          const group = groups[name];

          group.num_projects++;
          group.lines = Math.max(group.lines, project.lines); // In case preplots changed
          group.points = Math.max(group.points, project.total); // Idem
          group.sequences += project.seq_final;
          group.prime += project.prime;
          group.other += project.other;
          //group.ntba += project.ntba;
          group.prod_duration = add_durations(group.prod_duration, project.prod_duration);
          group.prod_distance += project.prod_distance;
          group.shooting_rate.push(project.shooting_rate);
          group.projects.push(project);
        }
      }

      this.groups = [];
      for (const group of Object.values(groups)) {
        group.shooting_rate_mean = d3a.mean(group.shooting_rate);
        group.shooting_rate_sd = d3a.deviation(group.shooting_rate);
        delete group.shooting_rate;

        this.groups.push(group);
      }

    },
    */

    async list () {
      this.items = [...this.groups];
    },

    async load () {
      await this.refreshProjects();
      //await this.prepareGroups();
      await this.list();
    },

    registerNotificationHandlers () {
      this.$store.dispatch('registerHandler', {
        table: 'project`',

        handler: (context, message) => {
          if (message.payload?.table == "public") {
            this.load();
          }
        }
      });
    },

    ...mapActions(["api", "showSnack", "refreshProjects"])
  },

  mounted () {
    this.registerNotificationHandlers();
    this.load();
  }
}

</script>
