<template>
  <div>
    <div class="dams-container" @contextmenu="initRightClick">
      <div id="dams-container-top"></div>

      <div class="dams-top-sticky actions">
        <div class="d-flex justify-content-between mb-20">
          <div>
            <div class="btn-actions" v-if="mode === 'edit'">
              <DamsActions
                :actionExpand="actionExpand"
                :folders="folders"
                :files="files"
                @dropdownChange="dropdownChange"
              />
              <el-button type="info" @click="onUploadFiles" v-if="folderId > 0">
                <em class="el-icon-upload mr-2"></em>
                {{ $t('dams.uploadFiles') }}
              </el-button>

              <el-button
                class="el-btn-primary-outline"
                type="primary"
                @click="onDeleteFile"
                v-if="showDeleteFileButton"
              >
                <em class="el-icon-delete mr-2"></em>
                {{ $t('dams.deleteFile') }}
                ({{ activeFolderFile.length }})
              </el-button>

              <el-button
                class="el-btn-info-outline"
                type="info"
                @click="onMoveFolderFile"
                v-if="activeFolderFile.length"
              >
                <em class="el-icon-folder-opened mr-2"></em>
                {{ $t('dams.move') }}
                ({{ activeFolderFile.length }})
              </el-button>
            </div>
          </div>
          <div class="pt-12">
            <el-radio-group v-model="display" size="small">
              <el-radio-button label="list">
                {{ $t('dams.list') }}
              </el-radio-button>
              <el-radio-button label="preview">
                {{ $t('general.preview') }}
              </el-radio-button>
            </el-radio-group>
          </div>
        </div>

        <div style="min-height: 20px" v-if="breadcrumbs && breadcrumbs.length">
          <BreadcrumbDams
            :breadcrumbs="breadcrumbs"
            @breadcrumbUpate="breadcrumbUpate"
          />
        </div>

        <hr />
      </div>

      <RowDams
        ref="folderRef"
        :items="folders"
        :mode="mode"
        :type="'folder'"
        :display="display"
        :ratio="ratio"
        :allowFileType="allowFileType"
        :activeFolderFile="activeFolderFile"
        :edit="edit"
        @nextLayer="nextLayer"
        @onAssetRename="initAssetRename"
      />

      <div>
        <RowDams
          ref="fileRef"
          :items="files"
          :mode="mode"
          :type="'file'"
          :display="display"
          :ratio="ratio"
          :allowFileType="allowFileType"
          :body="body"
          :activeFolderFile="activeFolderFile"
          :folderId="folderId"
          :filesTotalCount="totalCount"
          :edit="edit"
          @nextLayer="nextLayer"
          @updateData="updateData"
          @search="(val) => (fileSearch = val)"
          @onAssetRename="initAssetRename"
        />
        <infinite-loading
          ref="infiniteLoading"
          spinner="spiral"
          @infinite="load"
        >
          <div slot="no-results"></div>
          <div slot="no-more"></div>
        </infinite-loading>
      </div>

      <div
        class="mt-30"
        v-if="!folders.length && !files.length && loaded && !fileSearch"
      >
        <div class="text-center" v-if="mode === 'view'">
          <h3>
            {{ $t('general.noData') }}
          </h3>
        </div>
        <div v-else>
          <DamsUpload
            :accept="''"
            :multiple="true"
            :folderId="folderId"
            @uploaded="resetInifiniteAndLoad()"
          />
        </div>
      </div>

      <DamsRightClick
        ref="rightClickRef"
        :actionExpand="actionExpand"
        :folders="folders"
        :files="files"
        :folderId="folderId"
        @dropdownChange="dropdownChange"
      />
    </div>

    <el-dialog
      width="30%"
      :title="$t(editName ? 'dams.editFolder' : 'dams.newFolder')"
      :visible.sync="showNewFolder"
      :destroy-on-close="true"
      append-to-body
    >
      <NewFolderDams
        ref="newFolderRef"
        :parentId="folderId"
        :folderId="editFolderId"
        :editName="editName"
        @folderCreated="folderCreated"
      />
    </el-dialog>

    <el-dialog
      width="80%"
      :title="$t('dams.pcUpload')"
      :visible.sync="showUploadFiles"
      :destroy-on-close="true"
      :close-on-click-modal="false"
    >
      <DamsUpload
        :accept="''"
        :multiple="true"
        :folderId="folderId"
        @uploaded="resetInifiniteAndLoad()"
      />
    </el-dialog>

    <el-dialog
      :title="$t('dams.move')"
      :visible.sync="showMove"
      :destroy-on-close="true"
    >
      <MoveFolderFileDams
        ref="damsMoveRef"
        :activeFolderFile="activeFolderFile"
        @moved="moved"
      />
    </el-dialog>

    <el-dialog
      width="30%"
      :title="$t('dams.rename')"
      :visible.sync="showRenameAsset"
      :destroy-on-close="true"
      append-to-body
    >
      <AssetRenameDams
        ref="renameAssetsRef"
        :folderId="renameFolderId"
        :assetId="renameAssetId"
        :fileName="renameName"
        @assetRenamed="assetRenamed"
      />
    </el-dialog>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator'
import { DamsItem, BreadcrumbItem } from '../../model/dams/dams-item.model'
import { dataToModel } from '../../utils/data-to-model'
import { Subscription } from 'rxjs'
import { DamsSubscription } from '../../subscription/dams'
import BreadcrumbDams from './components/breadcrumb-dams.vue'
import RowDams from './components/row-dams.vue'
import NewFolderDams from './components/new-folder-dams.vue'
import MoveFolderFileDams from './components/move-folder-file.dams.vue'
import DamsActions from './components/actions.vue'
import DamsRightClick from './components/right-click.vue'
import AssetRenameDams from './components/assets-rename-dams.vue'

import DamsUpload from './dams-upload.vue'
import { getFolderTable, deleteAsset } from '../../api/dams'
import { confirmMsg } from '../../utils/message'
import { checkFileType } from '../../utils/check-file-type'
import { DatatableModel } from '../../model/datatable/datatable.model'
import { damsItemSelect } from '../../utils/dams-output'
import { downloadFileFromURL } from '../../utils/download-file'

@Component({
  name: 'DamsStructure',
  components: {
    BreadcrumbDams,
    RowDams,
    NewFolderDams,
    DamsUpload,
    MoveFolderFileDams,
    DamsActions,
    DamsRightClick,
    AssetRenameDams
  }
})
export default class extends Vue {
  @Prop({ default: '0:0' }) ratio!: string
  @Prop({ default: 'view' }) mode!: 'view' | 'edit'
  @Prop({ default: false }) initLoad!: boolean
  @Prop({ default: () => [] }) allowFileType!: Array<
    '' | 'VIDEO' | 'IMAGE' | 'PDF'
  >

  @Prop({ default: true }) edit!: boolean
  @Prop({ default: false }) singleSelect!: boolean

  display: 'list' | 'preview' = 'list'

  breadcrumbs: BreadcrumbItem[] = []
  setbreadcrumb = true

  actionExpand = false
  filterExpand = false

  body: DatatableModel = new DatatableModel()
  totalCount = 0

  folderId = 0
  loaded = false
  loading = false

  folders: DamsItem[] = []
  files: DamsItem[] = []

  selectedFile: DamsItem = new DamsItem()

  private editFolderSub: Subscription = new Subscription()
  showNewFolder = false
  editFolderId = 0
  editName = ''

  activeFolderFile: DamsItem[] = []

  showUploadFiles = false
  showMove = false

  preventInifiniteLoad = true
  fileSearch = false

  showRenameAsset = false
  renameFolderId = 0
  renameAssetId = 0
  renameName = ''
  renameFromPreview = false

  isInfiniteLoadTriggered = false

  created() {
    this.body.order_by = [
      {
        column: 'last_updated_time',
        sort_type: 'DESC'
      }
    ]
    this.body.start = 0
    this.body.limit = 20

    this.editFolderSub = DamsSubscription.getDamsState().subscribe(
      (result: any) => {
        if (result && 'type' in result) {
          if (result.type === 'GET_DATA') {
            this.resetInifiniteAndLoad()
          } else if (result.type === 'EDIT_FOLDER') {
            this.editFolder(result.data)
          } else {
            this.activeFolderFile = damsItemSelect(
              result,
              this.activeFolderFile,
              false
            )

            if (this.singleSelect && this.activeFolderFile.length > 1) {
              this.activeFolderFile = [this.activeFolderFile[0]]

              this.$message({
                message: `${this.$t('general.onlyOne') as string}`,
                type: 'error'
              })
            }
          }
        }
      }
    )
  }

  beforeDestroy() {
    this.unsubscribe()
  }

  unsubscribe() {
    if (this.editFolderSub) {
      this.editFolderSub.unsubscribe()
    }
  }

  init() {
    this.preventInifiniteLoad = false

    if (!this.loaded) {
      // this.getData()
      this.resetInifiniteAndLoad(true)
    }
  }

  reset() {
    this.breadcrumbs = []
    this.folders = []
    this.files = []
    this.selectedFile = new DamsItem()
    this.unsubscribe()
  }

  breadcrumbUpate(breadcrumb: BreadcrumbItem, index: number) {
    this.folderId = breadcrumb.id
    this.body.search_str = ''
    this.breadcrumbs.splice(index, this.breadcrumbs.length - index)
    this.resetInifiniteAndLoad(true)
  }

  updateData() {
    this.resetInifiniteAndLoad()
  }

  async getData() {
    if (this.loading) {
      return
    }

    const infinite: any = this.$refs.infiniteLoading

    if (this.files.length !== this.totalCount || !this.loaded) {
      if (!this.folders.length) {
        this.folders = []
      }

      this.body.other_params.folder_id = this.folderId

      this.loading = true
      const response: any = await getFolderTable(this.body, !this.loaded)
      this.loading = false

      if (response) {
        let isNextlayer = false

        if (this.setbreadcrumb) {
          const breadcrumb = new BreadcrumbItem()
          breadcrumb.id = this.folderId
          breadcrumb.name = response.folder.name || 'DAMS'
          this.breadcrumbs.push(breadcrumb)

          isNextlayer = true
          this.setbreadcrumb = false

          this.body.search_str = ''

          const fileRef: any = this.$refs.fileRef
          if (fileRef) {
            fileRef.reset()
          }
        }

        if (response.sub_folder && response.sub_folder.length) {
          for (const sub of response.sub_folder) {
            sub.type = 'FOLDER'
          }
        }

        this.totalCount = Number(response.result.count)

        let assets = response.result.data
        if (assets && assets.length) {
          assets = checkFileType(assets)
        }

        const data = response.sub_folder.concat(assets)

        const _data: any = dataToModel(DamsItem, data)
        this.filterDataType(_data, isNextlayer)

        if (this.showUploadFiles) {
          this.showUploadFiles = false
        }
      }

      if (infinite) {
        this.body.start += this.body.limit
        infinite.stateChanger.loaded()
      }

      this.loaded = true
    } else {
      if (infinite) {
        infinite.stateChanger.complete()
      }
    }

    // this.activeFolderFile = []
  }

  filterDataType(data: DamsItem[], isNextlayer = false) {
    const folders = []

    for (const d of data) {
      const type = d.type
      if (type) {
        if (type === 'FOLDER') {
          folders.push(d)
        } else if (type === 'FILE') {
          this.files.push(d)
        }
      }
    }

    if (this.folders.length !== folders.length || isNextlayer) {
      this.folders = folders
    }
  }

  nextLayer(data: DamsItem) {
    this.body.search_str = ''
    this.folderId = data.id
    this.resetInifiniteAndLoad(true)
  }

  resetInifiniteAndLoad(setbreadcrumb = false) {
    this.setbreadcrumb = setbreadcrumb
    this.activeFolderFile = []

    this.totalCount = 0
    this.body.start = 0
    this.files = []
    this.loaded = false

    const infinite: any = this.$refs.infiniteLoading
    if (infinite) {
      this.isInfiniteLoadTriggered = false
      infinite.stateChanger.reset()

      setTimeout(() => {
        if (!this.isInfiniteLoadTriggered) {
          this.load()
        }
      })
    }
  }

  onNew() {
    this.editFolderId = 0
    this.getFolderRef('', 0)
  }

  folderCreated() {
    this.folders = []
    this.showNewFolder = false
    this.resetInifiniteAndLoad()
  }

  assetRenamed() {
    this.showRenameAsset = false
    this.renameFolderId = this.renameAssetId = 0
    this.renameName = ''
    this.resetInifiniteAndLoad()

    setTimeout(() => {
      if (this.renameFromPreview) {
        const folderRef: any = this.$refs.folderRef
        if (folderRef) {
          folderRef.showPreview = false
        }

        const fileRef: any = this.$refs.fileRef
        if (fileRef) {
          fileRef.showPreview = false
        }
      }
      this.renameFromPreview = false
    })
  }

  editFolder(item: DamsItem) {
    this.editFolderId = item.id
    this.getFolderRef(item.name, item.id)
  }

  getFolderRef(name: string, id: number) {
    this.showNewFolder = true

    setTimeout(() => {
      const folder: any = this.$refs.newFolderRef
      if (folder) {
        folder.name = this.editName = name
        folder.folderId = this.editFolderId = id
      }
    })
  }

  get showDeleteFileButton() {
    let show = false

    let count = 0
    for (const folder of this.activeFolderFile) {
      if (folder.type === 'FILE') {
        count++
      }
    }
    if (count === this.activeFolderFile.length) {
      show = true
    }

    if (!this.activeFolderFile.length) {
      show = false
    }

    return show
  }

  async onDeleteFile() {
    if (await confirmMsg('general.confirmRemove', true, true)) {
      const list = []
      for (const folder of this.activeFolderFile) {
        list.push(folder.id)
      }
      const response = await deleteAsset({ asset_id: list })
      if (response) {
        this.resetInifiniteAndLoad()
      }
    }
  }

  onUploadFiles() {
    this.showUploadFiles = true
  }

  dropdownChange(
    command:
      | 'newFolder'
      | 'selectAll'
      | 'unselectAll'
      | 'selectAllFolders'
      | 'unselectAllFolders'
      | 'selectAllFiles'
      | 'unselectAllFiles'
      | 'upload'
      | 'open'
      | 'edit'
      | 'remove'
      | 'rename'
      | 'history'
      | 'download',
    dom?: any
  ) {
    if (command === 'newFolder') {
      this.onNew()
    } else if (
      command === 'open' ||
      command === 'edit' ||
      command === 'remove' ||
      command === 'rename' ||
      command === 'history' ||
      command === 'download'
    ) {
      if (
        dom &&
        dom.dataset &&
        dom.dataset.id &&
        dom.dataset.type
      ) {
        this.locateSingleItemAndTriggerAction(command, dom)
      }
    } else if (command === 'upload') {
      this.onUploadFiles()
    } else {
      const cloneFolders: DamsItem[] = JSON.parse(JSON.stringify(this.folders))
      const cloneFiles: DamsItem[] = JSON.parse(JSON.stringify(this.files))

      const _folders: DamsItem[] = this.activeFolderFile.filter(
        (dams: DamsItem) => dams.type === 'FOLDER'
      )
      const _files: DamsItem[] = this.activeFolderFile.filter(
        (dams: DamsItem) => dams.type === 'FILE'
      )

      if (command === 'selectAll') {
        this.activeFolderFile = []
        this.activeFolderFile = cloneFolders.concat(cloneFiles)
      } else if (command === 'unselectAll') {
        this.activeFolderFile = []
      } else if (command === 'selectAllFolders') {
        this.activeFolderFile = []
        this.activeFolderFile = cloneFolders.concat(_files)
      } else if (command === 'unselectAllFolders') {
        this.activeFolderFile = []
        this.activeFolderFile = _files
      } else if (command === 'selectAllFiles') {
        this.activeFolderFile = []
        this.activeFolderFile = cloneFiles.concat(_folders)
      } else if (command === 'unselectAllFiles') {
        this.activeFolderFile = []
        this.activeFolderFile = _folders
      }
    }

    this.$nextTick()
  }

  onMoveFolderFile() {
    this.showMove = true
    setTimeout(() => {
      const damsMoveRef: any = this.$refs.damsMoveRef
      if (damsMoveRef) {
        damsMoveRef.init()
      }
    })
  }

  moved() {
    this.showMove = false
    this.activeFolderFile = [new DamsItem()]

    this.resetInifiniteAndLoad()
  }

  load() {
    this.isInfiniteLoadTriggered = true
    if (!this.preventInifiniteLoad || this.initLoad) {
      this.getData()
    }
  }

  initRightClick(event: any) {
    if (!this.edit) {
      return
    }
    const rightClickRef: any = this.$refs.rightClickRef
    if (rightClickRef) {
      rightClickRef.openMenu(event)
    }
  }

  async locateSingleItemAndTriggerAction(
    commad: 'open' | 'edit' | 'remove' | 'rename' | 'history' | 'download',
    dom: any
  ) {
    const data: {
      id: ''
      type: 'file' | 'folder'
    } = dom.dataset

    let items: DamsItem[] = []
    let rowDamsRef: any

    if (data.type === 'file') {
      items = this.files
      rowDamsRef = this.$refs.fileRef
    } else if (data.type === 'folder') {
      items = this.folders
      rowDamsRef = this.$refs.folderRef
    }

    if (items && items.length) {
      const find = items.find(
        (d: DamsItem) => d.id.toString() === data.id.toString()
      )
      if (find) {
        if (rowDamsRef) {
          rowDamsRef.onSelect(find)
          if (commad === 'open') {
            rowDamsRef.onPreview()
          } else if (commad === 'rename') {
            this.initAssetRename(find)
          } else if (commad === 'history') {
            rowDamsRef.onHistory(find)
          } else if (commad === 'download') {
            await downloadFileFromURL(find.url, find.file_name)
          } else {
            // look for single item
            if (
              rowDamsRef.$refs &&
              rowDamsRef.$refs.singleRef &&
              rowDamsRef.$refs.singleRef.length
            ) {
              let single: any
              for (const i of rowDamsRef.$refs.singleRef) {
                if (
                  i.id.toString() === find.id.toString() &&
                  i.type === data.type
                ) {
                  single = i
                  break
                }
              }
              if (single) {
                if (commad === 'remove') {
                  single.onDelete(data.type)
                } else if (commad === 'edit') {
                  single.onEdit()
                }
              }
            }
          }
        }
      }
    }

    this.$nextTick()
  }

  initAssetRename(data: DamsItem, fromPreview = false) {
    this.renameFolderId = data.parent_folder_id || data.folder_id
    this.renameAssetId = data.id
    this.renameName = data.file_name
    this.renameFromPreview = fromPreview

    this.showRenameAsset = true
  }
}
</script>

<style lang="scss">
.dams-container {
  max-height: 76vh;
  overflow-y: auto;
  overflow-x: hidden;
  width: 100%;
  height: 100%;

  .el-breadcrumb {
    min-height: 15px;
  }

  .dams-top-sticky {
    position: sticky;
    z-index: 99;
    background-color: white;

    &.actions {
      padding-bottom: 10px;
      top: 0px;
    }

    &.row-label {
      top: 100px;
      z-index: 98;

      &.file {
        padding: 15px 0px;
      }
    }
  }

  .btn-actions {
    ~ div,
    button {
      margin-top: 10px;
      margin-right: 10px;
    }

    .el-button + .el-button {
      margin-left: 0px;
    }
  }

  .el-radio-group {
    width: 130px;
  }

  .single-card {
    padding: 10px 0px 0px 0px !important;

    .active {
      .box-card {
        border: 1px solid #a6192e;
        color: #a6192e;

        .folder-icon {
          filter: invert(25%) sepia(94%) saturate(4872%) hue-rotate(340deg)
            brightness(66%) contrast(94%);
        }

        .footer {
          background-color: rgba(166, 25, 46, 0.1);
        }
      }
    }
  }
}

.no-preview {
  background-color: grey;
  padding: 0px 20px;
  color: white;
  text-align: center;

  :not(.p-absolute-middle) {
    padding: 10px 0px 25px 0px;
    height: 20px;
  }
}
</style>
