<template>
  <div>
    <!-- Modal for adding new shows -->
    <b-modal
      ref="modalAddShow"
      title="Create a new show"
      size="lg"
      @ok="addShow"
    >
      <b-container fluid>
        <b-row>
          <b-col cols="3">
            Name of the show:
          </b-col>
          <b-col cols="9">
            <b-form-input
              v-model="newShow.name"
              type="text"
              placeholder="Enter a title for this new show"
            />
          </b-col>
          <b-col cols="3" />
          <b-col cols="9">
            <small class="slug">Slug: {{ temporarySlug }}</small>
          </b-col>
        </b-row>
        <br>

        <b-row>
          <b-col cols="3">
            Short description:
          </b-col>
          <b-col cols="9">
            <b-form-input
              v-model="newShow.short_description"
              type="text"
              placeholder="Enter a short description for this show"
            />
          </b-col>
        </b-row>
        <br>

        <b-row>
          <b-col cols="3">
            Show type:
          </b-col>
          <b-col cols="9">
            <div v-if="!loaded.types">
              <img
                src="../assets/radio.gif"
                alt="loading data"
              >
            </div>
            <div v-else>
              <b-form-select
                v-model="newShow.type"
                :options="showTypeSelector"
              />
            </div>
          </b-col>
        </b-row>

        <b-row>
          <b-col cols="3">
            Funding category:
          </b-col>
          <b-col cols="9">
            <div v-if="!loaded.fundingcategories">
              <img
                src="../assets/radio.gif"
                alt="loading data"
              >
            </div>
            <div v-else>
              <b-form-select
                v-model="newShow.fundingcategory"
                :options="showFundingCategorySelector"
              />
            </div>
          </b-col>
        </b-row>
      </b-container>
    </b-modal>

    <!-- Modal to confirm and delete a show -->
    <b-modal
      ref="modalDeleteShow"
      title="Delete a show"
      size="lg"
      @ok="deleteShow"
    >
      <b-alert
        variant="danger"
        show
      >
        You are about to delete the show <b>{{ deletedShow.name }}</b>!
      </b-alert>
      <div align="center">
        Are you sure you want to continue?
      </div>
    </b-modal>

    <!-- Modal to edit show owners -->
    <b-modal
      ref="modalOwners"
      title="Edit owners of the show"
      size="lg"
      @ok="updateOwners"
    >
      <div v-if="loaded.users">
        <p>
          Users with access to <b>{{ show.name }}</b>:
        </p>
        <div v-if="owners.length === 0">
          <ul>
            <li>
              <small><i>(none set)</i></small>
            </li>
          </ul>
        </div>
        <div v-else>
          <b-table
            striped
            hover
            :items="owners"
            :fields="ownersTableFields"
          >
            <template v-slot:cell(name)="data">
              {{ data.item.first_name }} {{ data.item.last_name }}
            </template>
            <template v-slot:cell(username)="data">
              <small>{{ data.value }}</small>
            </template>
            <template v-slot:cell(email)="data">
              <small>{{ data.value }}</small>
            </template>
            <template v-slot:cell(options)="data">
              <b-button
                variant="danger"
                size="sm"
                @click="deleteOwner(data.item.id)"
              >
                Delete
              </b-button>
            </template>
          </b-table>
        </div>

        <hr>

        <!-- TODO: as the list of users might be quite large we need some sort
          of pagination and/or a search box. also those users who already have
          access should not be listed (or at least the add button should be disabled)
        -->
        <p>
          You can
          <b-badge variant="success">
            add new users
          </b-badge>
          from the table below:
        </p>
        <b-table
          striped
          hover
          :items="users"
          :fields="ownersTableFields"
        >
          <template v-slot:cell(name)="data">
            {{ data.item.first_name }} {{ data.item.last_name }}
          </template>
          <template v-slot:cell(username)="data">
            <small>{{ data.value }}</small>
          </template>
          <template v-slot:cell(email)="data">
            <small>{{ data.value }}</small>
          </template>
          <template v-slot:cell(options)="data">
            <b-button
              variant="success"
              size="sm"
              @click="addOwner(data.item.id)"
            >
              Add
            </b-button>
          </template>
        </b-table>
      </div>
      <div v-else>
        <img
          src="../assets/radio.gif"
          height="32px"
          alt="loading user data"
        >
      </div>
    </b-modal>
  </div>
</template>

<script>
import axios from 'axios'
import slugify from '../mixins/slugify.js'

export default {
  mixins: [ slugify ],
  data () {
    return {
      newShow: {
        name: "",
        slug: "",
        short_description: "",
        type: 0,
        fundingcategory: 0,
        category: [],
        hosts: [],
        owners: [],
        language: [],
        topic: [],
        musicfocus: [],
      },
      deletedShow: {
        id: null,
        name: '',
      },
      show: null,
      loaded: {
        types: false,
        fundingcategories: false,
        users: false,
      },
      types: [],
      fundingcategories: [],
      users: [],
      owners: [],
      ownersTableFields: ['name', 'username', 'email', 'options']
    }
  },

  computed: {
    temporarySlug: function () {
      return this.slugify(this.newShow.name)
    },

    showTypeSelector: function () {
      let options = []
      for (let i in this.types) {
        options.push({
          value: this.types[i].id,
          text: this.types[i].type
        })
      }
      return options
    },

    showFundingCategorySelector: function () {
      let options = []
      for (let i in this.fundingcategories) {
        options.push({
          value: this.fundingcategories[i].id,
          text: this.fundingcategories[i].abbrev + ' (' + this.fundingcategories[i].fundingcategory + ')'
        })
      }
      return options
    },
  },

  methods: {
    // create a new show and POST it to the steering API
    // new shows have to at least contain a name, a slug and a short-description.
    // also a valide show type and funding category have to be choosen.
    // for all other categories we can use an empty array and let the user fill
    // it out through the existing show manager modals, after the show is created
    addShow (event) {
      // prevent the modal from closing automatically on click
      event.preventDefault()

      // only try to add a new show if name and short description are filled out
      if (this.newShow.name.trim() === '' || this.newShow.short_description.trim() === '' ) {
        // TODO: make this nicer UI-wise (red text annotations next to input fields instead of simple alert)
        alert('Please provide at least a title and a short description for this show.')
        return
      }
      // also the type and funding category have to be set
      if (this.types.findIndex(type => type.id === this.newShow.type) === -1) {
        // TODO: make this nicer UI-wise (red text annotations next to input fields instead of simple alert)
        alert('Please choose a type for this show.')
        return
      }
      if (this.fundingcategories.findIndex(cat => cat.id === this.newShow.fundingcategory) === -1) {
        // TODO: make this nicer UI-wise (red text annotations next to input fields instead of simple alert)
        alert('Please choose a funding category for this show.')
        return
      }

      // as the slug is a computed property we have to assign it to the new show's slug property
      this.newShow.slug = this.temporarySlug

      // ready to go, let's POST this new show
      let uri = process.env.VUE_APP_API_STEERING_SHOWS
      axios.post(uri, this.newShow, {
        withCredentials: true,
        headers: { 'Authorization': 'Bearer ' + this.$parent.$parent.user.access_token }
      }).then(response => {
        // everything was fine, we can close the modal now
        this.$refs.modalAddShow.hide()
        this.$parent.loadAndSwitch(response.data.id)
      }).catch(error => {
        this.$log.error(error.response.status + ' ' + error.response.statusText)
        this.$log.error(error.response)
        alert('Error: could not add new show. See console for details.')
        // and we leave the modal open, so no call to its .hide function here
      })
    },

    // delete a show by sending a DELETE to the steering API
    deleteShow (event) {
      // prevent the modal from closing automatically on click
      event.preventDefault()
      let uri = process.env.VUE_APP_API_STEERING_SHOWS + this.deletedShow.id
      axios.delete(uri, {
        withCredentials: true,
        headers: { 'Authorization': 'Bearer ' + this.$parent.$parent.user.access_token }
      }).then(() => {
        this.$refs.modalDeleteShow.hide()
        this.$parent.loadAndSwitch(null)
      }).catch(error => {
        this.$log.error(error.response.status + ' ' + error.response.statusText)
        this.$log.error(error.response)
        alert('Error: could not delete show. See console for details.')
        // and we leave the modal open, so no call to its .hide function here
      })
    },

    // remove an owner from the list of show owners
    deleteOwner (id) {
      // we only have to find the item in our array and splice it out
      // saving is done when the updateOwners method is called
      let i = this.owners.findIndex(o => o.id === id)
      this.owners.splice(i, 1)
    },

    // add a user as an owner to the list of show owners
    addOwner (id) {
      // we only have to push the user object to our owners array, if it is
      // not already there. saving is done by the updateOwners method.
      if (this.owners.findIndex(o => o.id === id) >= 0) {
        alert('This user already has access to the show.')
      } else {
        this.owners.push(this.users.find(u => u.id === id))
      }
    },

    // set new list of show owners by updating the show
    updateOwners (event) {
      // prevent the modal from closing automatically on click
      event.preventDefault()
      // now we have to fill the show's owner list anew with the selected owners
      this.show.owners = []
      for (let i in this.owners) {
        this.show.owners.push(this.owners[i].id)
      }
      // ready to update the show
      let uri = process.env.VUE_APP_API_STEERING_SHOWS + this.show.id + '/'
      axios.put(uri, this.show, {
        withCredentials: true,
        headers: { 'Authorization': 'Bearer ' + this.$parent.$parent.user.access_token }
      }).then(() => {
        this.$refs.modalOwners.hide()
        this.$parent.loadAndSwitch(this.show.id)
      }).catch(error => {
        this.$log.error(error.response.status + ' ' + error.response.statusText)
        this.$log.error(error.response)
        alert('Error: could not update show owners. See console for details.')
        // and we leave the modal open, so no call to its .hide function here
      })
    },

    // clear and fetch modal data and open the modal to add new shows
    showModalAddShow () {
      this.newShow.name = ''
      this.newShow.slug = ''
      this.newShow.short_description = ''
      this.loadTypes()
      this.loadFundingCategories()
      this.$refs.modalAddShow.show()
    },

    // open the deletion confirmation modal
    showModalDeleteShow (id, name) {
      this.deletedShow.id = id
      this.deletedShow.name = name
      this.$refs.modalDeleteShow.show()
    },

    // open the modal to edit a show's owners
    showModalOwners (show) {
      this.show = show
      this.owners = []
      this.loadUsers()
      this.$refs.modalOwners.show()
    },

    // fetch all available (that is: active) show type from steering
    loadTypes () {
      this.loaded.types = false
      axios.get(process.env.VUE_APP_API_STEERING + 'types/?active=true', {
        withCredentials: true,
        headers: { 'Authorization': 'Bearer ' + this.$parent.$parent.user.access_token }
      }).then(response => {
        this.types = response.data
        this.loaded.types = true
      }).catch(error => {
        this.$log.error(error.response.status + ' ' + error.response.statusText)
        this.$log.error(error.response)
        alert('Error: could not load available show types. See console for details.')
      })
    },

    // fetch all available (that is: active) funding categories from steering
    loadFundingCategories () {
      this.loaded.fundingcategories = false
      axios.get(process.env.VUE_APP_API_STEERING + 'fundingcategories/?active=true', {
        withCredentials: true,
        headers: { 'Authorization': 'Bearer ' + this.$parent.$parent.user.access_token }
      }).then(response => {
        this.fundingcategories = response.data
        this.loaded.fundingcategories = true
      }).catch(error => {
        this.$log.error(error.response.status + ' ' + error.response.statusText)
        this.$log.error(error.response)
        alert('Error: could not load available funding categories. See console for details.')
      })
    },

    // fetch all users from steering
    loadUsers () {
      this.loaded.users = false
      axios.get(process.env.VUE_APP_API_STEERING + 'users', {
        withCredentials: true,
        headers: { 'Authorization': 'Bearer ' + this.$parent.$parent.user.access_token }
      }).then(response => {
        this.users = response.data
        for (let i in this.show.owners) {
          this.owners.push(this.users.find(user => user.id === this.show.owners[i]))
        }
        this.loaded.users = true
      }).catch(error => {
        this.$log.error(error.response.status + ' ' + error.response.statusText)
        this.$log.error(error.response)
        alert('Error: could not load users. See console for details.')
      })
    },
  }
}
</script>

<style scoped>
.slug {
  color: gray;
}
</style>