<template>
  <div>
    <div id="my-queries-content">
      <div id="my-queries-toolbar">
        <div id="toolbar-buttons">
          <input
            ref="importFile"
            type="file"
            accept=".json"
            id="import-file"
            @change="importQueries"
          />
            <button class="toolbar">
              <label for="import-file">
                Import
              </label>
            </button>
          <button class="toolbar" v-show="selectedQueries.length > 0">Export</button>
          <button class="toolbar" v-show="selectedQueries.length > 0">Delete</button>
        </div>
        <div id="toolbar-search">
          <text-field placeholder="Search query by name" width="300px"/>
        </div>
      </div>
      <div class="rounded-bg">
      <div class="header-container">
        <div>
          <div class="fixed-header" ref="name-th">
            Name
          </div>
          <div class="fixed-header">
            Created at
          </div>
        </div>
      </div>
      <div
        class="table-container"
        ref="table-container"
      >
        <table ref="table">
          <tbody>
            <tr v-for="(query, index) in queries" :key="query.id" @click="openQuery(index)">
              <td ref="name-td">
                  {{ query.name }}
              </td>
              <td>
                <div class="second-column">
                  <div class="date-container">{{ query.createdAt | date }}</div>
                  <div class="icons-container">
                    <rename-icon @click="showRenameDialog(index)" />
                    <copy-icon @click="duplicateQuery(index)"/>
                    <export-icon @click="exportQuery(index)"/>
                    <delete-icon @click="showDeleteDialog(index)"/>
                  </div>
                </div>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>

  <!--Rename Query dialog  -->
  <modal name="rename" classes="dialog" height="auto">
    <div class="dialog-header">
      Rename query
      <close-icon @click="$modal.hide('rename')"/>
    </div>
    <div class="dialog-body">
      <text-field
        label="New query name"
        :error-msg="errorMsg"
        v-model="newName"
        width="100%"
      />
    </div>
    <div class="dialog-buttons-container">
      <button class="secondary" @click="$modal.hide('rename')">Cancel</button>
      <button class="primary" @click="renameQuery">Rename</button>
    </div>
  </modal>

  <!--Delete Query dialog  -->
  <modal name="delete" classes="dialog" height="auto">
    <div class="dialog-header">
      Delete query
      <close-icon @click="$modal.hide('delete')"/>
    </div>
    <div
      v-if="
        currentQueryIndex !== null
        && currentQueryIndex >= 0
        && currentQueryIndex < queries.length
      "
      class="dialog-body"
    >
      Are you sure you want to delete
      "{{ queries[currentQueryIndex].name }}"?
    </div>
    <div class="dialog-buttons-container">
      <button class="secondary" @click="$modal.hide('delete')">Cancel</button>
      <button class="primary" @click="deleteQuery">Delete</button>
    </div>
  </modal>
  <a ref="downloader" />
</div>
</template>

<script>
import RenameIcon from '@/components/svg/rename'
import CopyIcon from '@/components/svg/copy'
import ExportIcon from '@/components/svg/export'
import DeleteIcon from '@/components/svg/delete'
import CloseIcon from '@/components/svg/close'
import TextField from '@/components/TextField'
import { nanoid } from 'nanoid'

export default {
  name: 'MyQueries',
  components: {
    RenameIcon,
    CopyIcon,
    ExportIcon,
    DeleteIcon,
    CloseIcon,
    TextField
  },
  data () {
    return {
      queries: [],
      newName: null,
      currentQueryIndex: null,
      errorMsg: null,
      selectedQueries: []
    }
  },
  created () {
    this.queries = JSON.parse(localStorage.getItem('myQueries'))
  },
  mounted () {
    new ResizeObserver(this.calcNameWidth).observe(this.$refs.table)
    this.calcNameWidth()
  },
  filters: {
    date (value) {
      if (!value) {
        return ''
      }
      const dateOptions = { year: 'numeric', month: 'long', day: 'numeric' }
      const timeOptions = {
        hour12: false,
        hour: '2-digit',
        minute: '2-digit'
      }
      return new Date(value).toLocaleDateString('en-GB', dateOptions) + ' ' +
             new Date(value).toLocaleTimeString('en-GB', timeOptions)
    }
  },
  methods: {
    calcNameWidth () {
      this.$refs['name-th'].style = `width: ${this.$refs['name-td'][0].offsetWidth}px`
    },
    openQuery (index) {
      const tab = this.queries[index]
      tab.isUnsaved = false
      this.$store.commit('addTab', tab)
      this.$store.commit('setCurrentTabId', tab.id)
      this.$router.push('/editor')
    },
    showRenameDialog (index) {
      this.errorMsg = null
      this.currentQueryIndex = index
      this.newName = this.queries[this.currentQueryIndex].name
      this.$modal.show('rename')
    },
    renameQuery () {
      if (!this.newName) {
        this.errorMsg = 'Query name can\'t be empty'
        return
      }
      const currentQuery = this.queries[this.currentQueryIndex]
      currentQuery.name = this.newName
      this.$set(this.queries, this.currentQueryIndex, currentQuery)
      this.$modal.hide('rename')
      this.saveQueriesInLocalStorage()
      const tabIndex = this.findTabIndex(currentQuery.id)
      if (tabIndex >= 0) {
        this.$store.commit('updateTabName', { index: tabIndex, newName: this.newName })
      }
    },
    duplicateQuery (index) {
      const newQuery = JSON.parse(JSON.stringify(this.queries[index]))
      newQuery.name = newQuery.name + ' Copy'
      newQuery.id = nanoid()
      newQuery.createdAt = new Date()
      this.queries.push(newQuery)
      this.saveQueriesInLocalStorage()
    },
    showDeleteDialog (index) {
      this.currentQueryIndex = index
      this.$modal.show('delete')
    },
    deleteQuery () {
      this.$modal.hide('delete')
      const id = this.queries[this.currentQueryIndex].id
      this.queries.splice(this.currentQueryIndex, 1)
      this.saveQueriesInLocalStorage()
      const tabIndex = this.findTabIndex(id)
      if (tabIndex >= 0) {
        this.$store.commit('deleteTab', tabIndex)
      }
    },
    findTabIndex (id) {
      return this.$store.state.tabs.findIndex(tab => tab.id === id)
    },
    exportQuery (index) {
      this.currentQueryIndex = index
      const downloader = this.$refs.downloader
      const currentQuery = JSON.parse(JSON.stringify(this.queries[this.currentQueryIndex]))
      delete currentQuery.id
      delete currentQuery.createdAt
      const json = JSON.stringify(currentQuery)
      const blob = new Blob([json], { type: 'octet/stream' })
      const url = window.URL.createObjectURL(blob)
      downloader.href = url
      downloader.download = `${currentQuery.name}.json`
      downloader.click()
      window.URL.revokeObjectURL(url)
    },
    importQueries () {
      const file = this.$refs.importFile.files[0]
      const reader = new FileReader()
      reader.onload = () => {
        let importedQueries = JSON.parse(event.target.result)

        if (!Array.isArray(importedQueries)) {
          importedQueries = [importedQueries]
        }

        importedQueries.forEach(query => {
          query.id = nanoid()
          query.createdAt = new Date()
        })

        this.queries = this.queries.concat(importedQueries)
        this.saveQueriesInLocalStorage()
        this.$refs.importFile.value = null
      }
      reader.readAsText(file)
    },
    saveQueriesInLocalStorage () {
      localStorage.setItem('myQueries', JSON.stringify(this.queries))
    }
  }
}
</script>

<style scoped>
#my-queries-content {
  padding: 52px;
}

#my-queries-toolbar {
  display: flex;
  justify-content: space-between;
  margin-bottom: 18px;
  margin: 0 auto 8px;
  max-width: 1500px;
  width: 100%;
}

.rounded-bg {
  margin: 0 auto;
  max-width: 1500px;
  width: 100%;
}
table {
  margin-top: 0;
}
tbody tr td {
  overflow: hidden;
  min-width: 0;
  text-overflow: ellipsis;
  padding: 0 24px;
  line-height: 40px;
}

tbody tr td:first-child {
  width: 70%;
  max-width: 0;
}
tbody tr td:last-child {
  width: 30%;
  max-width: 0;
}

tbody tr:hover td {
  cursor: pointer;
}

tbody tr:hover td {
  color: var(--color-text-active);
}

.second-column {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  max-width: 100%;
}

.icons-container {
  display: none;
}
.date-container {
  flex-shrink: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
tbody tr:hover .icons-container {
  display: block;
}
.dialog input {
  width: 100%;
}
a, #import-file {
  display: none;
}
button.toolbar {
  margin-right: 16px;
}
button label {
  display: block;
  line-height: 36px;
}
button label:hover {
  cursor: pointer;
}
</style>
