<template>
  <div id="uploads">
    <div v-if="uploads !== null" class="list">
      <div v-for="group in groupedUploads">
        <template v-for="(upload, index) in group.uploads">
          <div class="properties" v-if="index == 0">
            <div class="pure-g">
              <div class="pure-u-1-1"><span class="text codedescription">{{ upload.codedescription || upload.codeId }}</span></div>
              <div class="pure-u-1-3"><span class="text">{{ upload.codeId }}</span></div>
              <div class="pure-u-1-3">
                <span class="text" v-if="hasAuth('viewAllUploads')" :class="{ userDeleted: !upload.username }">
                  {{ upload.username || $t('admin.uploads.userDeleted') }}
                </span>
              </div>
              <div class="pure-u-1-3 right"><span class="text">{{ upload.created | formatDateTime }}</span></div>
            </div>
          </div>

          <div class="pure-menu pure-menu-horizontal" v-if="index == 0">
            <ul class="pure-menu-list">
              <li class="pure-menu-item"><a href="#" class="pure-menu-link" @click.prevent="showAssign = !showAssign"><fa icon="user"></fa> {{ $t('admin.uploads.assign') }}</a></li>
              <li class="pure-menu-item" v-if="confirmDelete == upload.codeId"><a href="#" class="pure-menu-link" @click.prevent="cancelDelete"><fa icon="ban"></fa> {{ $t('admin.cancel') }}</a></li>
              <li class="pure-menu-item"><a href="#" class="pure-menu-link" :class="{ confirmDelete: confirmDelete == upload.codeId }" @click.prevent="deleteClick(upload.codeId)"><fa icon="trash-alt"></fa> {{ $t('admin.delete') }}</a></li>
            </ul>
          </div>

          <div v-if="showAssign" class="assign pure-form pure-form-horizontal">
            <select v-model="assignUser">
              <option v-for="user in assignUsers" v-if="user.id !== upload.userId" :value="user.id">{{ user.name }}</option>
            </select>

            <button class="pure-button pure-button-primary" @click.prevent="assignCode(upload.codeId)">{{ $t('admin.uploads.assignApply') }}</button>
            <button class="pure-button" @click.prevent="showAssign = false">{{ $t('admin.cancel') }}</button>
          </div>

          <div class="file" v-for="file in upload.files" :title="file.name">
            <a :href="getDownloadUrl(file)">
              <img :src="getFileIconUrl(file.name)" class="icon">
              <span class="filename">{{ file.name }}</span>
              <span class="size">{{ file.size | formatSizeSI }}</span>
            </a>
          </div>
        </template>
      </div>

      <div v-if="uploads.length == 0" class="nodata">
        {{ $t('admin.empty') }}
      </div>
    </div>

    <div v-else class="loading">
      {{ $t('admin.loading') }}
    </div>
  </div>
</template>

<script>
import orderBy from 'lodash/orderBy';
import findIndex from 'lodash/findIndex';
import forEach from 'lodash/forEach';
import axios from 'axios';
import shared from '../../shared';

export default {
  data()
  {
    return {
      uploads: null,
      confirmDelete: null,
      showAssign: false,
      assignUser: null,
      assignUsers: []
    };
  },

  created()
  {
    var self = this;

    if (!shared.adminToken)
    {
      self.$router.push('/admin');
      return;
    }


    axios.get('/admin/uploads', {
      headers: {
        Authorization: 'Bearer ' + shared.adminToken
      }
    })
    .then((response) =>
    {
      self.uploads = orderBy(response.data, ['created'], ['desc']);
    })
    .catch((error) => { shared.$emit('apiError', error, this.$router) });


    axios.get('/admin/assign/users', {
      headers: {
        Authorization: 'Bearer ' + shared.adminToken
      }
    })
    .then((response) =>
    {
      self.assignUsers = orderBy(response.data, ['name'], ['asc']);
    })
    .catch((error) => { shared.$emit('apiError', error, this.$router) });
  },


  computed: {
    groupedUploads()
    {
      let self = this;
      let codes = {};

      // Get unique codes and their highest upload time
      forEach(self.uploads, (upload) =>
      {
        if (!codes.hasOwnProperty(upload.codeId))
        {
          codes[upload.codeId] = {
            maxCreated: upload.created,
            uploads: [upload]
          };
        }
        else
          // uploads is sorted by created descending, so no need to update maxCreated
          codes[upload.codeId].uploads.push(upload);
      });

      return orderBy(codes, ['maxCreated'], ['desc']);
    }
  },


  methods: {
    hasAuth(token)
    {
      return shared.user !== null && shared.user.auth.indexOf(token) > -1;
    },


    getFileIconUrl(filename)
    {
      var ext = this.getExtension(filename);
      if (ext == '')
         ext = '_blank';

      return '/images/fileicons/32px/' + ext + '.png';
    },


    getExtension(filename)
    {
      var parts = filename.split('.');
      return parts.length > 0 ? parts.pop() : '';
    },


    getDownloadUrl(file)
    {
      return '/admin/download/' + encodeURIComponent(file.id) + '/' + encodeURIComponent(file.name);
    },


    deleteClick(codeId)
    {
      var self = this;

      if (self.confirmDelete == codeId)
      {
        self.confirmDelete = null;

        axios.delete('/admin/codeuploads/' + encodeURIComponent(codeId), {
          headers: {
            Authorization: 'Bearer ' + shared.adminToken
          }})
          .then((response) =>
          {
          })
          .catch((error) => { shared.$emit('apiError', error, this.$router) });
      }
      else
      {
        self.confirmDelete = codeId;
      }
    },

    cancelDelete()
    {
      var self = this;
      self.confirmDelete = null;
    },


    assignCode(codeId)
    {
      var self = this;

      let userId = self.assignUser;
      if (!userId)
        return;

      self.assignUser = null;
      self.showAssign = false;

      axios.post('/admin/assign/code', {
        id: codeId,
        userId: userId
      }, {
        headers: {
          Authorization: 'Bearer ' + shared.adminToken
        }
      })
      .then((response) =>
      {
        if (self.hasAuth('viewAllUploads'))
        {
          let username = null;
          forEach(self.assignUsers, (user) =>
          {
            if (user.id == userId)
              username = user.name;
          })

          self.updateCodeUser(codeId, userId, username);
        }
        else
          self.removeCodeUploads(codeId);
      })
      .catch((error) => { shared.$emit('apiError', error, this.$router) })
    },


    removeCodeUploads(codeId)
    {
      var self = this;

      for (let i = self.uploads.length - 1; i >= 0; i--)
      {
        if (self.uploads[i].codeId == codeId)
          self.uploads.splice(i, 1);
      }
    },


    updateCodeUser(codeId, userId, username)
    {
      var self = this;

      forEach(self.uploads, (upload) =>
      {
        if (upload.codeId == codeId)
        {
          upload.userId = userId;
          upload.username = username;
        }
      });
    }
  }
}
</script>

<style lang="scss">
.file
{
  display: inline-block;
  width: 10rem;
  padding: .5rem;
  margin-top: .5rem;
  border: solid 1px transparent;

  font-size: 75%;

  text-align: center;

  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;

  a
  {
    color: black;
    text-decoration: none;
  }

  .icon
  {
    display: block;
    margin-bottom: .5rem;
    margin-left: auto;
    margin-right: auto;
  }


  .filename, .size
  {
    display: block;
  }

  .size
  {
    color: #808080;
  }


  &:hover
  {
    background-color: #d3e9f8;
    border: solid 1px #a7d3f1;
  }
}


.properties
{
  background-color: #f4f4f4;
  padding: .2rem;
}


.codedescription
{
  font-weight: bold;
}


.assign
{
  margin-top: .5rem;
}
</style>