<script setup lang="ts">
import type { QTableProps } from 'quasar'
import { onMounted, ref, watch } from 'vue'
import { storeToRefs } from 'pinia'
import io from 'socket.io-client'

import { useSearchDataStore } from '@/stores/searched-data'
import { useFileInfoStore } from '@/stores/file-info-data'
import useStorage from '@/stores/storage'
import type { StorageFile } from '@/stores/storage'

import DialogDelete from '@/components/DialogDelete.vue'
import FileFormWrapper from '@/components/FileFormWrapper.vue'
import FileItemAction from '@/components/FileItemAction.vue'
import FileIcon from '@/components/FileIcon.vue'

const props = withDefaults(
  defineProps<{
    action: boolean
    viewMode: 'view_list' | 'view_module'
  }>(),
  {
    action: false,
  },
)
const { foundFile } = storeToRefs(useSearchDataStore())
const { getFileInfo, getSize, getType } = useFileInfoStore()

const storageStore = useStorage()
const { deleteFile } = storageStore

const fileInfoStore = useFileInfoStore()
const { getFormatDate } = fileInfoStore

const fileFormComponent = ref<InstanceType<typeof FileFormWrapper>>()

const keywordList = ref<string[]>([])
const categoryList = ref<string[]>([])
const selectKeyword = ref<string[]>([])
const selectCategory = ref<string[]>([])
const filterFoundFile = ref<StorageFile[]>()

const deleteFormType = ref<'deleteFile'>('deleteFile')
const dialogDeleteState = ref<boolean>(false)
const deleteFormPath = ref<string>('')

const columns: QTableProps['columns'] = [
  {
    name: 'name',
    required: true,
    label: 'ชื่อไฟล์',
    align: 'left',
    field: (row) => row.fileName,
    format: (val) => `${val}`,
    sortable: true,
    style: 'width: 200px',
  },
  {
    name: 'title',
    align: 'left',
    label: 'ชื่อเรื่อง',
    field: 'title',
    style: 'width: 200px',
    sortable: true,
  },
  {
    name: 'author',
    align: 'left',
    label: 'เจ้าของผลงาน',
    field: 'author',
    style: 'width: 200px',
    sortable: true,
  },
  {
    name: 'fileType',
    align: 'center',
    label: 'ประเภทของไฟล์',
    field: 'fileType',
    sortable: true,
    style: 'width: 200px',
  },
  {
    name: 'actions',
    align: 'center',
    label: '',
    field: '',
    style: 'width: 20px',
  },
]
const socket = io(import.meta.env.VITE_API_HOST)

socket.on('FileUpload', (data: StorageFile) => {
  replaceSearchItem(data.pathname, data)
})
socket.on('FileMove', (data: { from: StorageFile; to: StorageFile }) => {
  replaceSearchItem(data.from.pathname, data.to)
})
socket.on('FileDelete', (data: { pathname: string }) => {
  removeSearchItem(data.pathname)
})

function removeSearchItem(pathname: string) {
  const idx = foundFile.value.findIndex((v) => v.pathname === pathname)
  if (idx !== -1) foundFile.value.splice(idx, 1)
  filterSearch()
}

function replaceSearchItem(pathname: string, data: StorageFile) {
  const idx = foundFile.value.findIndex((v) => v.pathname === pathname)
  if (idx !== -1) foundFile.value[idx] = data
  filterSearch()
}

function triggerFileDelete(pathname: string) {
  deleteFormType.value = 'deleteFile'
  deleteFormPath.value = pathname
  dialogDeleteState.value = !dialogDeleteState.value
}

function confirmDelete() {
  if (deleteFormType) {
    deleteFile(deleteFormPath.value)
  }
}

function filterSearch() {
  keywordList.value = []
  categoryList.value = []
  foundFile.value.forEach((obj) => {
    obj.keyword.forEach((keyword) => {
      if (!keywordList.value.includes(keyword)) {
        keywordList.value.push(keyword)
      }
    })
    obj.category.forEach((category) => {
      if (!categoryList.value.includes(category)) {
        categoryList.value.push(category)
      }
    })
  })

  if (!(selectKeyword.value.length || selectCategory.value.length)) {
    filterFoundFile.value = foundFile.value
  } else {
    filterFoundFile.value = foundFile.value.filter(
      (entry) =>
        entry.keyword.some((kw) => selectKeyword.value.includes(kw)) ||
        entry.category.some((kw) => selectCategory.value.includes(kw)),
    )
  }
}

watch(
  [
    () => foundFile.value,
    () => selectKeyword.value,
    () => selectCategory.value,
  ],
  filterSearch,
)

onMounted(() => {
  filterSearch()
})
</script>

<template>
  <file-form-wrapper ref="fileFormComponent" />
  <dialog-delete v-model:open="dialogDeleteState" @confirm="confirmDelete" />

  <div class="row grid q-py-md q-gutter-sm">
    <q-select
      outlined
      dense
      multiple
      use-chips
      v-model="selectKeyword"
      :options="keywordList"
      style="width: 100%"
      label="คำสำคัญ"
      class="custom-selection"
    />
    <q-select
      outlined
      dense
      multiple
      use-chips
      v-model="selectCategory"
      :options="categoryList"
      style="width: 100%"
      label="กลุ่ม/หมวดหมู่"
    />
  </div>

  <div v-if="props.viewMode === 'view_list' && foundFile.length > 0">
    <span class="text-body text-grey"
      >จำนวน {{ filterFoundFile?.length }} รายการ</span
    >
    <div class="grid q-mt-md">
      <div v-for="(value, index) in filterFoundFile" :key="value.pathname">
        <div
          :style="{
            position: 'relative',
            display: 'flex',
            gap: '0.5rem',
            flexDirection: 'column',
            alignItems: 'center',
            padding: '1rem',
            maxWidth: '100%',
          }"
          class="box"
          @click="() => getFileInfo(foundFile[index])"
          :id="`getFileInfoFileSearched${index}`"
        >
          <div class="q-px-md flex items-center justify-center">
            <file-icon
              size="preview"
              :fileMimeType="value.fileType ? value.fileType : 'unknow'"
              :fileName="value.fileName ? value.fileName : 'unknow'"
            />
          </div>
          <div
            class="absolute"
            style="top: 0.5rem; right: 0.5rem"
            v-if="props.action"
          >
            <file-item-action
              :nameId="value.pathname"
              :have-meta="
                !!(value.metadata && Object.keys(value.metadata).length > 0)
              "
              @edit="
                () =>
                  fileFormComponent?.triggerFileEdit(
                    {
                      title: value.title,
                      description: value.description,
                      keyword: value.keyword,
                      category: value.category,
                      author: value.author,
                      metadata: value.metadata,
                    },
                    value.pathname,
                    value.fileName,
                  )
              "
              @delete="() => triggerFileDelete(value.pathname)"
            />
          </div>
          <div
            class="text-overflow-handle block q-px-md text-center"
            style="max-width: 100%"
          >
            {{ value.title }}
          </div>
        </div>
      </div>
    </div>
  </div>

  <div
    v-if="props.viewMode === 'view_module' && foundFile.length > 0"
    class="q-gutter-sm"
  >
    <q-table
      flat
      bordered
      row-key="name"
      class="cursor"
      :rows="filterFoundFile"
      :columns="columns"
      :pagination="{
        rowsPerPage: 0,
      }"
    >
      <template v-slot:body-cell-name="nameData">
        <q-td style="width: 50%" @click="() => getFileInfo(nameData.row)">
          <file-icon
            size="list"
            :fileMimeType="
              nameData.row.fileType ? nameData.row.fileType : 'unknown'
            "
            :fileName="
              nameData.row.fileName ? nameData.row.fileName : 'unknown'
            "
          />
          {{ nameData.row.fileName }}
        </q-td>
      </template>
      <template v-slot:body-cell-title="data">
        <q-td style="width: 50%" @click="() => getFileInfo(data.row)">
          {{ data.row.metadata.subject ?? data.row.title }}
        </q-td>
      </template>
      <template v-slot:body-cell-author="author">
        <q-td style="width: 50%" @click="() => getFileInfo(author.row)">
          {{ author.row.metadata.author ?? author.row.author }}
        </q-td>
      </template>

      <template v-slot:body-cell-fileType="typeData">
        <q-td>
          <div>
            {{ getType(typeData.row.fileType, typeData.row.fileName) }}
          </div>
        </q-td>
      </template>

      <template v-slot:body-cell-actions="actionData">
        <q-td class="justify-center">
          <div>
            <q-icon class="q-ma-sm" name="o_info" size="2em" color="primary" />
            <q-tooltip anchor="center left" self="center right">
              <div class="flex" style="flex-direction: column; font-size: 120%">
                <span>ชื่อไฟล์: {{ actionData.row.fileName }}</span>
                <span>
                  ชื่อเรื่อง:
                  {{ actionData.row.metadata.subject ?? actionData.row.title }}
                </span>
                <span>
                  เจ้าของผลงาน:
                  {{ actionData.row.metadata.author ?? actionData.row.author }}
                </span>
                <span>ขนาด: {{ getSize(actionData.row.fileSize) }}</span>
                <span>
                  ประเภทของไฟล์:
                  {{
                    getType(actionData.row.fileType, actionData.row.fileName)
                  }}
                </span>
                <span>
                  วันที่อัปโหลด:
                  {{ getFormatDate(actionData.row.createdAt) }}
                </span>
              </div>
            </q-tooltip>
          </div>
          <div v-if="props.action">
            <q-btn
              flat
              color="positive"
              dense
              icon="o_edit"
              @click.stop="
                () =>
                  fileFormComponent?.triggerFileEdit(
                    actionData.row,
                    actionData.row.pathname,
                    actionData.row.fileName,
                  )
              "
              id="listViewFileEdit"
            />
            <q-btn
              flat
              color="negative"
              dense
              icon="mdi-trash-can-outline"
              @click="() => triggerFileDelete(actionData.row.pathname)"
              v-if="
                !(
                  actionData.row.metadata &&
                  Object.keys(actionData.row.metadata).length > 0
                )
              "
              id="listViewFileDelete"
            />
            <div
              style="width: 64px"
              v-if="
                actionData.row.metadata &&
                Object.keys(actionData.row.metadata).length > 0
              "
            ></div>
          </div>
        </q-td>
      </template>
    </q-table>
  </div>

  <div class="q-mt-md" v-if="foundFile.length == 0">
    <span>ไม่พบรายการที่ค้นหา</span>
  </div>
</template>

<style scoped lang="scss">
.box {
  border: 2px solid $separator-color;
  border-radius: 8px;
  cursor: pointer;
}

.cursor {
  cursor: pointer;
}

.text-overflow-handle {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.grid {
  display: grid;
  width: 100%;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
}

@media (min-width: $breakpoint-md-min) {
  .grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.grid .box {
  position: relative;
}

.justify-center {
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
