<template>
  <div class="container pt-4 2xl:max-w-none">
    <!-- Recently Used & Performance Comparison -->
    <div>
      <!-- Performance Comparison -->
      <section v-if="filesTag === 'COMPARE'">
        <h2 class="h-12 font-bold py-4 mb-4 border-b border-neutral-500">Performance Comparison</h2>
        <div class="flex justify-start items-center gap-4 w-full h-[184px] scrollbar pb-4">
          <!-- primaryDrag -->
          <div class="relative w-[216px] min-w-[216px] h-full" id="primaryDragCard">
            <div v-if="primaryDragData.length === 0" class="w-full h-full p-4 border rounded border-neutral-300 duration-300 text-neutral-500 absolute">
              <div class="h-full flex flex-col justify-center items-center gap-4">
                <p class="text-4xl font-black">1</p>
                <p class="text-sm font-medium">Drag and drop a file here</p>
              </div>
            </div>
            <draggable
              v-model="primaryDragData" :group="{name: 'files', pull: false, put: primaryDragData.length < 1 }" item-key="id" class="w-full h-full">
              <template #item="{element}">
                <div class="w-full h-full p-4 border rounded border-neutral-300  hover:bg-primary/10 hover:border-primary duration-300 flex flex-col justify-between cursor-pointer" :title="element.name" >
                  <div class="h-full">
                    <span class="material-symbols-outlined mb-2 !text-[32px] block">
                      {{element.icon}}
                    </span>
                    <h3 class="text-sm font-medium mb-2 whitespace-nowrap break-keep overflow-hidden text-ellipsis  leading-tight">
                      {{element.name}}
                    </h3>
                    <p class="text-sm text-neutral-500 whitespace-nowrap break-keep text-ellipsis overflow-hidden  leading-tight">
                      {{element.parentLog}}
                    </p>
                  </div>
                  <p class="text-sm text-neutral-500">
                    {{element.updated_at}}
                  </p>
                </div>
              </template>
            </draggable>
            <!-- delete icon -->
            <span v-show="primaryDragData.length > 0" class="material-symbols-outlined material-fill text-neutral-500 bg-neutral-10 block rounded-full absolute -top-[5%] -right-[5%] z-50 cursor-pointer hover:text-danger" @click="primaryDragDelete">do_not_disturb_on</span>
          </div>
          <!-- secondaryDrag -->
          <div class="relative w-[216px] min-w-[216px] h-full" id="secondaryDragCard">
            <div v-show="secondaryDragData.length === 0" class="w-full h-full p-4 border rounded border-neutral-300 duration-300 text-neutral-500 absolute">
              <div class="h-full flex flex-col justify-center items-center gap-4">
                <p class="text-4xl font-black">2</p>
                <p class="text-sm font-medium">Drag and drop a file here</p>
              </div>
            </div>
            <draggable
              v-model="secondaryDragData" :group="{name: 'files', pull: false, put: secondaryDragData.length < 1 }"  item-key="id" class="w-full h-full">
              <template #item="{element}">
                <div class="w-full h-full p-4 border rounded border-neutral-300  hover:bg-primary/10 hover:border-primary duration-300 flex flex-col justify-between cursor-pointer" :title="element.name" >
                  <div>
                    <span class="material-symbols-outlined mb-2 !text-[32px] block">
                      {{element.icon}}
                    </span>
                    <h3 class="text-sm font-medium mb-2 whitespace-nowrap break-keep overflow-hidden text-ellipsis leading-tight">
                      {{element.name}}
                    </h3>
                    <p class="text-sm text-neutral-500 whitespace-nowrap break-keep text-ellipsis overflow-hidden leading-tight">
                      {{element.parentLog}}
                    </p>
                  </div>
                  <p class="text-sm text-neutral-500">
                    {{element.updated_at}}
                  </p>
                </div>
              </template>
            </draggable>
            <!-- delete icon -->
            <span v-show="secondaryDragData.length > 0" class="material-symbols-outlined material-fill bg-neutral-10 text-neutral-500 block rounded-full absolute -top-[5%] -right-[5%] cursor-pointer hover:text-danger" @click="secondaryDragDelete
            ">do_not_disturb_on</span>
          </div>
          <button class="btn btn-sm" :class="this.isCompareDisabledButton ? 'btn-disable' : 'btn-c-primary'" :disabled="isCompareDisabledButton" @click="compareSubmit">Compare</button>
        </div>
      </section>
      <!-- Recently Used -->
      <section v-else>
        <h2 class="h-12 font-bold py-4 mb-4 border-b border-neutral-500">Recently Used</h2>
        <!-- card group 最多六個-->
        <ul class="flex justify-start items-center gap-4 overflow-x-auto w-full h-[184px] scrollbar pb-4">
          <!-- card item v-for -->
          <li class="w-[216px] min-w-[216px] h-full p-4 border rounded border-neutral-300  hover:bg-primary/10 hover:border-primary duration-300 flex flex-col justify-between cursor-pointer" v-for="(file, index) in recentlyUsedFiles.slice(0, 6)" :key="file.id" @dblclick="enterDiscover(file)" :title="file.name" @contextmenu="onRightClick($event, file)" >
            <div>
              <span class="material-symbols-outlined mb-2 !text-[32px] block">
                {{ file.icon }}
              </span>
              <h3 class="text-sm font-medium mb-2 whitespace-nowrap break-keep overflow-hidden text-ellipsis leading-tight">
                {{ file.name }}
              </h3>
              <p class="text-sm text-neutral-500 whitespace-nowrap break-keep text-ellipsis overflow-hidden leading-tight">
                {{ file.parentLog }}
              </p>
            </div>
            <p class="text-sm text-neutral-500">
              {{ file.accessed_at }}
            </p>
          </li>
        </ul>
      </section>
    </div>
    <!-- All Files -->
    <div>
      <!-- Compare -->
      <section v-if="filesTag === 'COMPARE'">
        <!-- All Files header -->
        <div class="h-12 mb-4 border-b flex justify-between items-center border-neutral-500">
          <h2 class="font-bold">All Files</h2>
          <ul class="flex items-center gap-x-4">
            <li>
              <Dropdown v-model="gridSort" :options="columnType" optionLabel="name" placeholder="Sort" class="w-full !border-neutral-500" inputClass="!text-sm" @change="getGridSortData($event)"></Dropdown>
            </li>
            <li>
              <IconGrid class="hover:bg-neutral-50 duration-300"></IconGrid>
            </li>
          </ul>
        </div>
        <!-- All Files type of grid -->
        <draggable tag="ul" :list="compareData" :group="{ name: 'files' }" itemKey="name" class="flex justify-start items-start gap-4 flex-wrap overflow-y-scroll overflow-x-hidden max-h-[calc(100vh_-_440px)] scrollbar" id="compareGridCards">
          <template #item="{ element, index }">
            <li class="w-[216px] h-[168px] p-4 border rounded border-neutral-300 hover:bg-primary/10 hover:border-primary duration-300 flex flex-col justify-between cursor-pointer" :title="element.name" :id="'compareFile' + index">
              <div>
                <span class="material-symbols-outlined mb-2 !text-[32px] block">
                  {{ element.icon }}
                </span>
                <h3 class="text-sm font-medium mb-2 whitespace-nowrap break-keep overflow-hidden text-ellipsis leading-tight">
                  {{ element.name }}
                </h3>
                <p class="text-sm text-neutral-500 whitespace-nowrap break-keep text-ellipsis overflow-hidden leading-tight">
                  {{ element.parentLog }}
                </p>
              </div>
              <p class="text-sm text-neutral-500">
                {{ element.updated_at }}
              </p>
            </li>
          </template>
        </draggable>
      </section>
      <!-- All & Discover -->
      <section v-else>
        <!-- All Files header -->
        <div class="h-12 mb-4 border-b flex justify-between items-center border-neutral-500">
          <h2 class="font-bold">All Files</h2>
          <ul class="flex items-center gap-x-4">
            <li v-show="isActive !== null" class="animate-fadein">
              <ul class="flex justify-center items-center gap-x-4 px-4 py-1 rounded-full bg-neutral-200 text-neutral-700">
                <li><span class="material-symbols-outlined align-bottom cursor-pointer hover:text-primary" @click="rename">edit_square</span></li>
                <li><span class="material-symbols-outlined align-bottom cursor-pointer hover:text-primary" @click="download">download</span></li>
                <li><span class="material-symbols-outlined align-bottom cursor-pointer hover:text-primary" @click="deleteFile">delete</span></li>
              </ul>
            </li>
            <li class="cursor-pointer" @click="switchListOrGrid = false">
              <IconList class="hover:fill-primary hover:bg-neutral-50 duration-300"></IconList>
            </li>
            <li class="cursor-pointer" @click="switchListOrGrid = true">
              <IconGrid class="hover:fill-primary hover:bg-neutral-50 duration-300"></IconGrid>
            </li>
          </ul>
        </div>
        <!-- All Files type of List -->
        <div v-if="!switchListOrGrid">
          <DataTable :value="allFiles" dataKey="id" tableClass="w-full text-sm cursor-pointer relative table-fixed" :rowClass="setRowClass" breakpoint="0" @row-dblclick="enterDiscover($event.data)" contextmenu v-model:contextMenuSelection="selectedTableFile" @row-contextmenu="onRightClickTable" >
            <Column field="name" header="Name" bodyClass="font-medium fileName"  sortable></Column>
            <Column field="parentLog" header="Dependency" bodyClass="text-neutral-500" sortable></Column>
            <Column field="fileType" header="File Type" bodyClass="text-neutral-500 fileType" sortable></Column>
            <Column field="owner.name" header="Owner" bodyClass="text-neutral-500" sortable></Column>
            <Column field="updated_at" header="Last Update" bodyClass="text-neutral-500" sortable></Column>
            <Column bodyClass="text-neutral-500">
              <template #body="slotProps">
                <ul class="opacity-0 group-hover:opacity-100  flex justify-end items-center gap-x-2 text-neutral-700">
                  <li><span class="material-symbols-outlined align-bottom cursor-pointer hover:text-primary" @click="rename(slotProps.data.type, slotProps.data.id, 'list-hover', slotProps.data.name)">edit_square</span></li>
                  <li><span class="material-symbols-outlined align-bottom cursor-pointer hover:text-primary" @click="download(slotProps.data.type, slotProps.data.id, 'list-hover', slotProps.data.name)">download</span></li>
                  <li><span class="material-symbols-outlined align-bottom cursor-pointer hover:text-primary" @click="deleteFile(slotProps.data.type, slotProps.data.id, slotProps.data.name, 'list-hover')">delete</span></li>
                </ul>
              </template>
            </Column>
          </DataTable>
        </div>
        <!-- All Files type of grid -->
        <ul class="flex justify-start items-start gap-4 flex-wrap overflow-y-scroll overflow-x-hidden max-h-[calc(100vh_-_440px)] scrollbar" v-else>
          <li class="w-[216px] h-[168px] p-4 border rounded border-neutral-300 hover:bg-primary/10 hover:border-primary duration-300 flex flex-col justify-between cursor-pointer" v-for="(file, index) in allFiles" :key="file.id" :class="{ 'bg-primary/10 border-primary': isActive === index}" @dblclick="enterDiscover(file)" :title="file.name" @contextmenu="onRightClick($event, file)" @click="onGridCardClick(file, index)" :id="'li' + index">
            <div>
              <span class="material-symbols-outlined mb-2 !text-[32px] block">
                {{ file.icon }}
              </span>
              <h3 class="text-sm font-medium mb-2 whitespace-nowrap break-keep overflow-hidden text-ellipsis leading-tight">
                {{ file.name }}
              </h3>
              <p class="text-sm text-neutral-500 whitespace-nowrap break-keep text-ellipsis overflow-hidden leading-tight">
                {{ file.parentLog }}
              </p>
            </div>
            <p class="text-sm text-neutral-500">
              {{ file.updated_at }}
            </p>
          </li>
        </ul>
      </section>
    </div>
    <!-- ContextMenu -->
    <ContextMenu ref="fileRightMenu" :model="items" @hide="selectedFile = null" class="cursor-pointer">
      <template #item="{ item }">
        <a class="flex align-items-center px-4 py-2 duration-300 hover:bg-primary/20">
          <span class="material-symbols-outlined">{{ item.icon }}</span>
          <span class="ml-2 text-sm inline-flex items-center">{{ item.label }}</span>
          <span v-if="item.shortcut" class="border border-round p-1">{{ item.shortcut }}</span>
        </a>
      </template>
    </ContextMenu>
  </div>
</template>

<script>
  import { storeToRefs } from 'pinia';
  import LoginStore from '@/stores/login.js';
  import filesStore from '@/stores/files.js';
  import AllMapDataStore from '@/stores/allMapData.js';
  import LoadingStore from '@/stores/loading.js';
  import IconDataFormat from '@/components/icons/IconDataFormat.vue';
  import IconRule from '@/components/icons/IconRule.vue';
  import IconsFilter from '@/components/icons/IconsFilter.vue';
  import IconFlowChart from '@/components/icons/IconFlowChart.vue';
  import IconVector from '@/components/icons/IconVector.vue';
  import IconList from '@/components/icons/IconList.vue';
  import IconGrid from '@/components/icons/IconGrid.vue';
  import { renameModal, deleteFileModal } from '@/module/alertModal.js';

  export default {
    data() {
      return {
        isActive: null,
        isHover: null,
        switchListOrGrid: false,
        selectedTableFile: null, // table 右鍵選單 item
        selectedFile: null, // 右鍵選單 item
        selectedType: null,
        selectedId: null,
        selecteName: null,
        items: [
          {
            label: 'Rename',
            icon: 'edit_square',
            command: this.rename,
          },
          {
            label: 'Download',
            icon: 'download',
            command: this.download,
          },
          {
            separator: true // 分隔符號
          },
          {
            label: 'Delete',
            icon: 'delete',
            command: this.deleteFile,
          },
        ],
        compareData: null,
        primaryDragData: [],
        secondaryDragData: [],
        gridSort: null,
        columnType: [
          { name: 'By File Name (A to Z)', code: 'nameAscending'},
          { name: 'By File Name (Z to A)', code: 'nameDescending'},
          { name: 'By Dependency (A to Z)', code: 'parentLogAscending'},
          { name: 'By Dependency (Z to A)', code: 'parentLogDescending'},
          { name: 'By File Type (A to Z)', code: 'fileAscending'},
          { name: 'By File Type (Z to A)', code: 'fileDescending'},
          { name: 'By Last Update (A to Z)', code: 'updatedAscending'},
          { name: 'By Last Update (Z to A)', code: 'updatedDescending'},
        ],
      }
    },
    setup() {
      const loginStore = LoginStore();
      const store = filesStore();
      const allMapDataStore = AllMapDataStore();
      const loadingStore = LoadingStore();
      const { dependentsData, filesTag } = storeToRefs(store);
      const { createFilterId, baseLogId } = storeToRefs(allMapDataStore);
      const { isLoading } = storeToRefs(loadingStore);

      return { loginStore, store, dependentsData, filesTag, allMapDataStore, createFilterId, baseLogId, isLoading }
    },
    components: {
      IconDataFormat,
      IconRule,
      IconsFilter,
      IconFlowChart,
      IconVector,
      IconList,
      IconGrid
    },
    computed: {
      /**
       * Read allFiles
       */
      allFiles: function() {
        if(this.store.allFiles.length !== 0){
          let sortFiles = Array.from(this.store.allFiles);
          sortFiles.sort((x,y) => new Date(y.updated_base) - new Date(x.updated_base));
          return sortFiles;
        }
      },
      /**
       * 時間排序，如果沒有 accessed_at 就不加入 data
       */
      recentlyUsedFiles: function() {
        let recentlyUsedFiles = Array.from(this.store.allFiles);
        recentlyUsedFiles = recentlyUsedFiles.filter(item => item.accessed_at !== null);
        recentlyUsedFiles.sort((x, y) => new Date(y.accessed_base) - new Date(x.accessed_base));
        return recentlyUsedFiles;
      },
      /**
       * Compare Submit button disabled
       */
      isCompareDisabledButton: function() {
        let result = this.primaryDragData.length === 0 || this.secondaryDragData.length === 0 ? true : false;
        return result;
      }
    },
    watch: {
      filesTag: {
        handler(newValue) {
          if(newValue !== 'COMPARE'){
            this.primaryDragData = [];
            this.secondaryDragData = [];
          }
        }
      },
      allFiles: {
        handler(newValue) {
          this.compareData = JSON.parse(JSON.stringify(newValue));
        }
      }
    },
    methods: {
      /**
       * Set Row Style
       */
      setRowClass() {
        return ['group']
      },
      /**
       * Set Compare Row Style
       */
      setCompareRowClass() {
        return ['leading-6']
      },
      /**
       * 選擇該 files 進入 Discover/Compare/Design 頁面
       * @param {object} file
       */
      enterDiscover(file){
        let type;
        let fileId;
        let params;

        switch (file.type) {
          case 'log':
            this.createFilterId = null;
            this.baseLogId = file.id;
            fileId = file.id;
            type = 'log';
            params = { type: type, fileId: fileId };
            this.$router.push({name: 'Map', params: params});
            // this.$router.push({name: 'Map', params: params, query: params});
            break;
          case 'filter':
            this.createFilterId = file.id;
            this.baseLogId = file.parent.id;
            fileId = file.id;
            type = 'filter';
            params = { type: type, fileId: fileId };
            this.$router.push({name: 'Map', params: params});
            // this.$router.push({name: 'Map', params: params, query: params});
            break;
          // 先不考慮 MAP 只做 CONFORMANCE
          case 'log-check':
            // path: "/:type/:checkType/:checkId/conformance/:checkFileId"
            type = 'rule';
            params = { type: type, checkType: 'log', checkId: file.id, checkFileId: file.parent.id };
            this.$router.push({name: 'CheckConformance', params: params});
            break
          case 'filter-check':
            type = 'rule';
            params = { type: type, checkType: 'filter', checkId: file.id, checkFileId: file.parent.id };
            this.$router.push({name: 'CheckConformance', params: params});
            break;
        }
      },
      /**
       * Right Click DOM Event
       * @param {event} event
       * @param {string} file
       */
      onRightClick(event, file) {
        this.selectedType = file.type;
        this.selectedId = file.id;
        this.selecteName = file.name;
        this.$refs.fileRightMenu.show(event)
      },
      /**
       * Right Click Table DOM Event
       * @param {event} event
       */
      onRightClickTable(event) {
        this.selectedType = event.data.type;
        this.selectedId = event.data.id;
        this.selecteName = event.data.name;
        this.$refs.fileRightMenu.show(event.originalEvent)
      },
      /**
       * Right Click Gride Card DOM Event
       * @param {event} event
       * @param {number} index
       */
      onGridCardClick(file, index) {
        this.selectedType = file.type;
        this.selectedId = file.id;
        this.selecteName = file.name;
        this.isActive = index;
      },
      /**
       * File's Rename
       * @param {string} type
       * @param {number} id
       * @param {string} source hover icon
       * @param {string} fileName
       */
      rename(type, id, source, fileName) {
        if(type && id && source === 'list-hover') {
          this.selectedType = type;
          this.selectedId = id;
          this.selecteName = fileName;
        }
        renameModal(this.store.rename, this.selectedType, this.selectedId, this.selecteName);
      },
      /**
       * Delete file
       * @param {string} type
       * @param {number} id
       * @param {string} source hover icon
       */
      async deleteFile(type, id, name, source) {
        let srt = '';
        let data = [];

        // 判斷是否來自 hover icon 選單
        if(type && id && name && source === 'list-hover') {
          this.selectedType = type;
          this.selectedId = id;
          this.selecteName = name;
        }
        // 取得相依性檔案
        await this.store.getDependents(this.selectedType, this.selectedId);
        if(this.dependentsData.length !== 0) {
          data = [...this.dependentsData];
          data.forEach(i => {
            switch (i.type) {
              case 'log-check':
                i.type = 'rule';
                break;
              case 'filter-check':
                i.type = 'rule';
                break;
            }
            let content = `<li>[${i.type}] ${i.name}</li>`;
            srt += content;
          });
        }
        deleteFileModal(srt, this.selectedType, this.selectedId, this.selecteName);
        srt = '';
      },
      /**
       * Download file as CSV
       * @param {string} type
       * @param {number} id
       * @param {string} source hover icon
       */
      download(type, id, source, name) {
        if(type && id && source === 'list-hover' && name) {
          this.selectedType = type;
          this.selectedId = id;
          this.selecteName = name;
        }
        this.store.downloadFileCSV(this.selectedType, this.selectedId, this.selecteName);
      },
      /**
       * Delete Compare Primary log
       */
       primaryDragDelete() {
        this.compareData.unshift(this.primaryDragData[0]);
        this.primaryDragData.length = 0;
      },
      /**
       * Delete Compare Secondary log
       */
      secondaryDragDelete() {
        this.compareData.unshift(this.secondaryDragData[0]);
        this.secondaryDragData.length = 0;
      },
      /**
       * Enter the Compare page
       */
       compareSubmit() {
        const primaryType = this.primaryDragData[0].type;
        const secondaryType = this.secondaryDragData[0].type;
        const primaryId = this.primaryDragData[0].id;
        const secondaryId = this.secondaryDragData[0].id;
        const params = { primaryType: primaryType, primaryId: primaryId, secondaryType: secondaryType, secondaryId: secondaryId };

        this.$router.push({name: 'CompareDashboard', params: params});
      },
      /**
       *
       * @param {event} event choose columnType item
       */
      getGridSortData(event) {
        const code = event.value.code;

         // 文字排序: 將 name 字段轉換為小寫進行比較，使用 localeCompare() 方法進行字母順序比較
        switch (code) {
          case 'nameAscending':
            this.compareData = this.compareData.sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()));
            break;
          case 'nameDescending':
            this.compareData = this.compareData.sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase())).reverse();
            break;
          case 'parentLogAscending':
            this.compareData = this.compareData.sort((a, b) => a.parentLog.toLowerCase().localeCompare(b.parentLog.toLowerCase()));
            break;
          case 'parentLogDescending':
            this.compareData = this.compareData.sort((a, b) => a.parentLog.toLowerCase().localeCompare(b.parentLog.toLowerCase())).reverse();
            break;
          case 'fileAscending':
            this.compareData = this.compareData.sort((a, b) => a.fileType.toLowerCase().localeCompare(b.fileType.toLowerCase()));
            break;
          case 'fileDescending':
            this.compareData = this.compareData.sort((a, b) => a.fileType.toLowerCase().localeCompare(b.fileType.toLowerCase())).reverse();
            break;
          case 'updatedAscending':
            this.compareData = this.compareData.sort((a, b) => new Date(a.updated_base) - new Date(b.updated_base));
            break;
          case 'updatedDescending':
          this.compareData = this.compareData.sort((a, b) => new Date(a.updated_base) - new Date(b.updated_base)).reverse();
            break;
        }
      },
    },
    mounted() {
      this.isLoading = true;
      this.store.fetchAllFiles();
      window.addEventListener('click', (e) => {
        const clickedLi = e.target.closest('li');
        if(!clickedLi || !clickedLi.id.startsWith('li')) this.isActive = null;
      })
      // 為 DataTable tbody 加入 .scrollbar 選擇器
      const tbodyElement = document.querySelector('.p-datatable-tbody');
      tbodyElement.classList.add('scrollbar');
      this.isLoading = false;
    },
  }
</script>

<style scoped>
:deep(thead) {
  @apply sticky top-0 bg-neutral-10 after:border-b after:border-neutral-500 after:w-full after:left-0 after:bottom-0 after:absolute table table-fixed w-full
}
:deep(tbody) {
  @apply overflow-y-auto overflow-x-hidden max-h-[calc(100vh_-_480px)] block
}
:deep(table th) {
  @apply border-b !border-neutral-500 !p-2 text-left font-bold !bg-neutral-10 whitespace-nowrap break-keep overflow-hidden text-ellipsis
}
:deep(table td) {
  @apply border-b border-neutral-300 !p-2 whitespace-nowrap break-keep overflow-hidden text-ellipsis
}
:deep(tbody > tr) {
  @apply duration-300 cursor-pointer hover:bg-primary/10 focus:!outline-none table table-fixed w-full
}
:deep(.p-sortable-column) {
  @apply focus:!shadow-none !text-neutral-900
}
:deep(.p-sortable-column-icon) {
  @apply !text-[#6c757d]
}
</style>
