<template>
  <main class="container is-fluid">
    <template v-if="model">
      <router-link class="button is-pulled-right" :to="{ name: 'models-list' }">
        <i class="icon-arrow-left"></i>
        Models
      </router-link>
      <div class="title">
        <span v-if="model.archived" class="tag">Archived</span> {{ model.name }}
        <EditForm class="ml-2 is-primary" :model-instance="model" mode="edit" />
      </div>
      <div class="subtitle is-5">
        <p>Model <ItemId :item-id="model.id" /></p>
        <button
          v-if="!model.archived"
          class="button is-danger mt-2"
          v-on:click="archiveModal = canAdmin"
          :disabled="!canAdmin || undefined"
          :title="archiveButtonTitle"
        >
          Archive model
        </button>
      </div>

      <div class="columns">
        <div class="column">
          <div class="field">
            <label class="label">Created</label>
            <div class="control">
              <p>{{ creationDate }}</p>
            </div>
          </div>
        </div>
        <div class="column">
          <div class="field">
            <label class="label">Last updated</label>
            <div class="control">
              <p>{{ updateDate }}</p>
            </div>
          </div>
        </div>
      </div>

      <div class="field">
        <label class="label">Description</label>
        <div class="control">
          <!-- eslint-disable-next-line vue/no-v-html -->
          <p v-if="model.description" class="content" v-html="md.render(model.description)"></p>
          <p v-else>—</p>
        </div>
      </div>

      <hr />
      <ModelDetails :model-id="modelId" />
    </template>
    <div v-else-if="error" class="notification is-danger">{{ error }}</div>
    <div v-else class="loader is-size-2 mx-auto"></div>
    <ArchivalModal
      v-if="canAdmin"
      :instance="model"
      instance-type="model"
      v-model="archiveModal"
      :update-function="updateModel"
    />
  </main>
</template>

<script lang="ts">
import MarkdownIt from 'markdown-it'
import { defineComponent } from 'vue'
import { mapState, mapActions } from 'pinia'
import { UUID_REGEX } from '@/config'
import { ago, errorParser } from '@/helpers'
import { UUID } from '@/types'
import { Model } from '@/types/model'
import ModelDetails from '@/components/Model'
import EditForm from '@/components/Model/EditForm.vue'
import { useModelStore, useNotificationStore } from '@/stores'
import ItemId from '@/components/ItemId.vue'
import ArchivalModal from '@/components/ArchivalModal.vue'

export default defineComponent({
  props: {
    modelId: {
      type: String,
      required: true,
      validator: value => typeof value === 'string' && UUID_REGEX.test(value)
    }
  },
  components: {
    ModelDetails,
    EditForm,
    ItemId,
    ArchivalModal
  },
  data: () => ({
    loading: false,
    error: null as string | null,
    archiveModal: false,
    md: new MarkdownIt({ breaks: true })
  }),
  computed: {
    ...mapState(useModelStore, ['models']),
    model (): Model {
      return this.models[this.modelId]
    },
    creationDate (): string | null {
      if (!this.model) return null
      return ago(new Date(this.model.created))
    },
    updateDate (): string | null {
      if (!this.model) return null
      return ago(new Date(this.model.updated))
    },
    canAdmin () {
      return this.model?.rights.includes('admin')
    },
    archiveButtonTitle () {
      if (this.canAdmin) return 'Archive model'
      return 'You need administrator rights on a model to archive it'
    }
  },
  methods: {
    ...mapActions(useNotificationStore, ['notify']),
    ...mapActions(useModelStore, ['retrieveModel', 'updateModel']),
    async loadModel (modelId: UUID) {
      this.loading = true
      try {
        await this.retrieveModel(modelId)
      } catch (err) {
        this.error = errorParser(err)
      } finally {
        this.loading = false
      }
    }
  },
  watch: {
    modelId: {
      immediate: true,
      handler (newValue: UUID) {
        if (!this.models[newValue]) this.loadModel(newValue)
      }
    }
  }
})
</script>