<template>
  <v-container fluid>
    <v-row>
      <v-col>
        <v-dialog
          max-width="600px"
          :value="dialog"
          @input="closeDialog"
        >
          <template v-slot:activator="{ on, attrs }">
            <v-btn v-if="writeaccess()"
              small
              color="primary"
              v-bind="attrs"
              v-on="on"
            >Add</v-btn>
          </template>
          <v-card>
            <v-card-title v-if="dialogMode=='new'">Add new item</v-card-title>
            <v-card-title v-else>Edit item</v-card-title>
            <v-card-text>
              <v-container>
                <v-row>
                  <v-col cols="12">
                    <v-text-field
                      label="Kind"
                      required
                      v-model="item.kind"
                      :disabled="dialogMode == 'edit'"
                    >
                    </v-text-field>
                  </v-col>
                  <v-col cols="12">
                    <v-textarea
                      class="markdown"
                      label="Description"
                      dense
                      auto-grow
                      rows="1"
                      v-model="item.description"
                    >
                    </v-textarea>
                  </v-col>
                  <v-col cols="6">
                    <v-text-field
                      label="Date"
                      type="date"
                      step="1"
                      v-model="item.date"
                    >
                    </v-text-field>
                  </v-col>
                  <v-col cols="6">
                    <v-text-field
                      label="Time"
                      type="time"
                      step="60"
                      v-model="item.time"
                    >
                    </v-text-field>
                  </v-col>
                  <template v-for="(attr, idx) in item.attributes">
                    <v-col cols="4">
                      <v-text-field
                        label="Attribute"
                        v-model="attr.key"
                      >
                      </v-text-field>
                    </v-col>
                    <v-col cols="8">
                      <v-textarea
                        label="Value"
                        class="markdown"
                        auto-grow
                        rows="1"
                        v-model="attr.value"
                      >
                      <template v-slot:append-outer>
                        <v-btn
                          fab
                          x-small
                          dark
                          color="red"
                          title="Remove this attribute / value pair"
                          @click="removeAttribute(idx)"
                        >
                          <v-icon>mdi-minus</v-icon>
                        </v-btn>
                      </template>
                      </v-textarea>
                    </v-col>
                  </template>
                  <v-col cols="12" class="text-right">
                    <v-btn
                      fab
                      x-small
                      color="primary"
                      title="Add a new attribute / value pair to further describe the equipment"
                      @click="addAttribute"
                    >
                      <v-icon>mdi-plus</v-icon>
                    </v-btn>
                  </v-col>
                </v-row>
              </v-container>
            </v-card-text>
            <v-card-actions>
              <v-btn
                color="warning"
                @click="closeDialog"
              >
              Cancel
              </v-btn>
              <v-spacer></v-spacer>
              <v-btn
                color="success"
                :loading="loading"
                :disabled="!canSave || loading"
                @click="saveItem"
              >
              Save
              </v-btn>
            </v-card-actions>
          </v-card>
        </v-dialog>
      </v-col>
    </v-row>
    <v-row>
      <v-col cols="4">
        <v-toolbar
          dense
          flat
        >
          <v-toolbar-title>
            Equipment
          </v-toolbar-title>
        </v-toolbar>

        <v-list dense two-line>
          <v-subheader v-if="!latest.length">
            There are no items of equipment
          </v-subheader>
          <v-list-item-group
            v-model="selectedIndex"
            color="primary"
          >
            <v-list-item v-for="(item, idx) in latest" :key="idx">
              <v-list-item-content>
                <v-list-item-title>
                  {{item.kind}}
                </v-list-item-title>
                <v-list-item-subtitle>
                  Last updated: {{item.tstamp.substring(0,16)}}Z
                </v-list-item-subtitle>
              </v-list-item-content>
            </v-list-item>
          </v-list-item-group>
        </v-list>
      </v-col>

      <v-col cols="8">
        <v-card v-if="selectedItem">
          <v-card-title>{{selectedItem.kind}}</v-card-title>
          <v-card-subtitle class="text-caption">{{selectedItem.tstamp}}</v-card-subtitle>
          <v-card-text>
            <v-container>
              <v-row>
                <div v-html="$options.filters.markdown(selectedItem.description||'')"></div>
              </v-row>
              <v-row>
                <v-simple-table>
                  <template v-slot:default>
                    <tbody>
                      <tr v-for="(attr, idx) in selectedItem.attributes" :key="idx">
                        <td>{{attr.key}}</td>
                        <td v-html="$options.filters.markdown(attr.value||'')"></td>
                      </tr>
                    </tbody>
                  </template>
                </v-simple-table>
              </v-row>
            </v-container>
          </v-card-text>
          <v-card-actions>
            <v-btn v-if="writeaccess()"
              small
              text
              color="primary"
              title="Make a change to this item"
              @click="editItem(selectedItem)"
            >
            Update
            </v-btn>
            <v-btn-toggle
              group
              v-model="historyMode"
            >
              <v-btn
                small
                text
                :disabled="false"
                title="View item's full history of changes"
              >
              History
              </v-btn>
            </v-btn-toggle>
            <v-spacer></v-spacer>
            <v-btn v-if="writeaccess()"
            small
            dark
            color="red"
            title="Remove this instance from the item's history"
            @click="confirmDelete(selectedItem)"
            >
            Delete
            </v-btn>
          </v-card-actions>
        </v-card>
        <v-subheader v-else-if="latest.length" class="justify-center">Select an item from the list</v-subheader>

        <v-expand-transition v-if="selectedItem">
          <div v-if="historyMode===0">
            <v-subheader v-if="!selectedItemHistory || !selectedItemHistory.length"
              class="justify-center"
            >No more history</v-subheader>
            <v-card v-for="(item, key) in selectedItemHistory" class="mt-5" :key="key">
              <v-card-title>{{selectedItem.kind}}</v-card-title>
              <v-card-subtitle class="text-caption">{{item.tstamp}}</v-card-subtitle>
              <v-card-text>
                <v-container>
                  <v-row>
                    <div v-html="$options.filters.markdown(item.description||'')"></div>
                  </v-row>
                  <v-row>
                    <v-simple-table>
                      <template v-slot:default>
                        <tbody>
                          <tr v-for="(attr, idx) in item.attributes" :key="idx">
                            <td>{{attr.key}}</td>
                            <td v-html="$options.filters.markdown(attr.value||'')"></td>
                          </tr>
                        </tbody>
                      </template>
                    </v-simple-table>
                  </v-row>
                </v-container>
              </v-card-text>
              <v-card-actions>
                <v-spacer></v-spacer>
                <v-btn v-if="writeaccess()"
                small
                dark
                color="red"
                title="Remove this instance from the item's history"
                @click="confirmDelete(item)"
                >
                Delete
                </v-btn>
              </v-card-actions>
            </v-card>
          </div>
        </v-expand-transition>
      </v-col>

    </v-row>

  <v-dialog
    :value="confirm.message"
    max-width="500px"
    persistent
  >
    <v-sheet
      class="px-7 pt-7 pb-4 mx-auto text-center d-inline-block"
      color="blue-grey darken-3"
      dark
    >
      <div class="grey--text text--lighten-1 text-body-2 mb-4" v-html="confirm.message"></div>

      <v-btn
        :disabled="loading"
        class="ma-1"
        color="grey"
        plain
        @click="cancelConfirmAction"
      >
        {{ confirm.no || "Cancel" }}
      </v-btn>

      <v-btn
        :loading="loading"
        class="ma-1"
        color="error"
        plain
        @click="doConfirmAction"
      >
        {{ confirm.yes || "Delete" }}
      </v-btn>
    </v-sheet>
  </v-dialog>

  </v-container>
</template>

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

export default {
  name: "Equipment",

  mixins: [
    AccessMixin
  ],

  data () {
    return {
      latest: [],
      all: [],
      item: {
        kind: null,
        description: null,
        tstamp: null,
        date: null,
        time: null,
        attributes: []
      },
      dialogMode: null,
      selectedIndex: null,
      historyMode: false,
      confirm: {
        message: null,
        action: null,
        yes: null,
        no: null
      }
    }
  },

  watch: {

    dialog (newVal, oldVal) {
      if (newVal) {
        const tstamp = new Date();
        this.item.date = tstamp.toISOString().substr(0, 10);
        this.item.time = tstamp.toISOString().substr(11, 5);
      }
    },

    "item.date": function (newVal) {
      if (newVal) {
        this.item.tstamp = new Date(this.item.date+"T"+this.item.time);
      }
    },

    "item.time": function (newVal) {
      if (newVal) {
        this.item.tstamp = new Date(this.item.date+"T"+this.item.time);
      }
    },

    async serverEvent (event) {
      if (event.payload.schema == "public") {
        if (event.channel == "info") {
          if (!this.loading) {
            this.getEquipment();
          }
        }
      }
    }

  },

  computed: {

    dialog () {
      return !!this.dialogMode;
    },

    canSave () {
      return this.item.kind &&
        this.item.date && this.item.time &&
        (this.item.attributes.length
          ? this.item.attributes.every(i => i.key && i.value)
          : (this.item.description ||"").trim());
    },

    selectedItem () {
      return this.selectedIndex !== null
        ? this.latest[this.selectedIndex]
        : null;
    },

    selectedItemHistory () {
      if (this.selectedItem && this.historyMode === 0) {
        const items = this.all
        .filter(i => i.kind == this.selectedItem.kind && i.tstamp != this.selectedItem.tstamp)
        .sort( (a, b) => new Date(b.tstamp) - new Date(a.tstamp) );
        return items;
      }
      return null;
    },

    ...mapGetters(['user', 'loading', 'serverEvent'])

  },

  methods: {

    async cancelConfirmAction () {
      this.confirm.action = null;
      this.confirm.message = null;
      this.confirm.yes = null;
      this.confirm.no = null;
    },

    async doConfirmAction () {
      await this.confirm.action();
      this.cancelConfirmAction();
    },

    async getEquipment () {
      const url = `/info/equipment`;

      const items = await this.api([url]) || [];
      this.all = [...items];
      this.latest = this.all.filter(i =>
        !this.all.find(j => i.kind == j.kind && i.tstamp < j.tstamp)
      )
      .sort( (a, b) => a.kind < b.kind ? -1 : a.kind > b.kind ? 1 : 0 );
    },

    addAttribute () {
      this.item.attributes.push({key: undefined, value: undefined});
    },

    removeAttribute (idx) {
      this.item.attributes.splice(idx, 1);
    },

    async deleteItem (item) {
      const idx = this.all.findIndex(i => i.kind == item.kind && i.tstamp == item.tstamp);
      if (idx == -1) {
        return;
      }
      const url = `/info/equipment/${idx}`;
      const init = {
        method: "DELETE"
      };
      await this.api([url, init]);
      await this.getEquipment();
    },

    confirmDelete (item) {
      this.confirm.action = () => this.deleteItem(item);
      this.confirm.message = "Are you sure? <b>This action is irreversible.</b>";
    },

    clearItem () {
      this.item.kind = null;
      this.item.description = null;
      this.item.date = null;
      this.item.time = null;
      this.item.attributes = [];
    },

    editItem (item) {
      this.item.kind = item.kind;
      this.item.description = item.description;
      this.item.tstamp = new Date();
      this.item.attributes = [...item.attributes];
      this.dialogMode = "edit";
      this.dialog = true;
    },

    async saveItem () {
      const item = {};
      item.kind = this.item.kind;
      item.description = this.item.description;
      item.tstamp = this.item.tstamp.toISOString();
      item.attributes = [...this.item.attributes.filter(i => i.key && i.value)];
      if (this.dialogMode == "edit") {
        this.latest.splice(this.selectedIndex, 1, item);
      } else {
        this.latest.push(item);
      }

      const url = `/info/equipment`;
      const init = {
        method: "POST",
        body: item
      };
      await this.api([url, init]);

      this.closeDialog();
      await this.getEquipment();
    },

    clearItem () {
      this.item.kind = null;
      this.item.description = null;
      this.item.attributes = [];
      this.item.tstamp = null;
    },

    closeDialog (state = false) {
      this.clearItem();
      this.dialogMode = state===true ? "new" : null;
    },

    ...mapActions(["api"])

  },

  async mounted () {
    await this.getEquipment();
  }
}
</script>
