<script setup lang="ts">
import { computed, ref } from 'vue'
import { storeToRefs } from 'pinia'

import FileIcon from '@/components/FileIcon.vue'
import FileItemAction from '@/components/FileItemAction.vue'
import DialogDelete from '@/components/DialogDelete.vue'
import FileForm from './FileForm.vue'
import FolderForm from './FolderForm.vue'
import UploadExistDialog from './UploadExistDialog.vue'
import { useTreeDataStore } from '@/stores/tree-data'
import { useFileInfoStore } from '@/stores/file-info-data'

const props = withDefaults(
  defineProps<{ action: boolean; viewMode: 'view_list' | 'view_module' }>(),
  {
    action: false,
  },
)
const DEPT_NAME = ['ตู้เอกสาร', 'ลิ้นชัก', 'แฟ้ม', 'แฟ้มย่อย'] as const
const { getFileInfo, getFileNameFormat } = useFileInfoStore()
const { currentFolder, currentFile, currentDept, currentPath } =
  storeToRefs(useTreeDataStore())
const {
  createFolder,
  editFolder,
  getFolder,
  deleteFolder,
  uploadFile,
  updateFile,
  deleteFile,
  checkFile,
} = useTreeDataStore()

const currentIcon = computed(() =>
  currentDept.value === 0
    ? 'mdi-file-cabinet'
    : currentDept.value === 1
      ? 'inbox'
      : 'o_folder_open',
)

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

const folderFormState = ref<boolean>(false)
const folderFormPath = ref<string>('')
const folderFormData = ref<{
  name?: string
}>({})
const folderFormType = ref<'edit' | 'create'>('create')
const fileFormState = ref<boolean>(false)
const fileFormPath = ref<string>('')
const fileFormData = ref<{
  file?: File
  title?: string
  description?: string
  keyword?: string
  category?: string
}>({})
const fileFormType = ref<'edit' | 'create'>('create')
const fileFormError = ref<{ fileExist?: boolean }>({})
const fileExistNotification = ref<boolean>(false)

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

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

function triggerFolderCreate() {
  folderFormType.value = 'create'
  folderFormData.value = {}
  folderFormState.value = !folderFormState.value
}

function triggerFolderEdit(name: string, pathname: string) {
  folderFormType.value = 'edit'
  folderFormPath.value = pathname
  folderFormData.value.name = name
  folderFormState.value = true
}

async function submitFolderForm(value: {
  mode: 'create' | 'edit'
  name: string
}) {
  if (value.mode === 'create') {
    await createFolder(value.name)
  } else {
    await editFolder(value.name, folderFormPath.value)
  }
}

function triggerFileCreate() {
  fileFormType.value = 'create'
  fileFormData.value = {}
  fileFormState.value = !fileFormState.value
}

function triggerFileEdit(
  value: {
    title: string
    description: string
    keyword: string
    category: string
  },
  pathname: string,
) {
  fileFormState.value = true
  fileFormType.value = 'edit'
  fileFormPath.value = pathname
  fileFormData.value = {
    title: value.title,
    description: value.description,
    keyword: value.keyword,
    category: value.keyword,
  }
}

const currentParam = ref<Parameters<typeof submitFileForm>[0]>()

async function submitFileForm(
  value: {
    mode: 'create' | 'edit'
    file: File
    title: string
    description: string
    keyword: string
    category: string
  },
  force = false,
) {
  currentParam.value = value

  if (checkFile(value.file.name) && !force) {
    fileExistNotification.value = true
    return
  }

  if (value.mode === 'create') {
    await uploadFile(currentPath.value, value.file, {
      title: value.title,
      description: value.description,
      keyword: value.keyword,
      category: value.category,
    })
  } else {
    await updateFile(
      fileFormPath.value,
      {
        title: value.title,
        description: value.description,
        keyword: value.keyword,
        category: value.category,
      },
      value.file,
    )
  }
  fileFormData.value = {}
  fileFormState.value = false
  currentParam.value = undefined
}
</script>

<template>
  <div class="text-h6 q-mt-md" v-if="currentDept > 2">
    {{ DEPT_NAME[currentDept] }}
  </div>
  <div class="grid q-mt-md">
    <div v-for="value in currentFolder">
      <div
        :style="{
          position: 'relative',
          display: 'flex',
          gap: '0.5rem',
          flexDirection: currentDept > 2 ? 'row' : 'column',
          alignItems: 'center',
          padding: currentDept > 2 ? '.5rem 0' : '.5rem',
        }"
        class="box"
        @click="() => getFolder(value.pathname)"
      >
        <div class="q-px-md flex items-center justify-center">
          <q-icon
            :name="currentIcon"
            :size="currentDept > 2 ? '3em' : '6em'"
            color="primary"
            class="col"
          />
        </div>
        <div
          class="absolute flex items-center justify-center"
          style="top: 0.5rem; right: 0.5rem"
          :style="{ bottom: currentDept > 2 ? '0.5rem' : 'unset' }"
          v-if="props.action"
        >
          <file-item-action
            @delete="() => triggerFolderDelete(value.pathname)"
            @edit="() => triggerFolderEdit(value.name, value.pathname)"
          />
        </div>
        <div
          class="text-overflow-handle block text-center"
          :class="{
            'q-px-md': currentDept < 3,
            'q-pr-xl': currentDept > 2,
          }"
          style="max-width: 100%"
        >
          {{ value.name }}
        </div>
      </div>
    </div>
    <div v-if="props.action && currentDept < 4">
      <div
        class="dashed"
        :style="{
          position: 'relative',
          display: 'flex',
          gap: '0.5rem',
          flexDirection: currentDept > 2 ? 'row' : 'column',
          alignItems: 'center',
          padding: currentDept > 2 ? '.5rem 0' : '.5rem',
        }"
        @click="() => triggerFolderCreate()"
      >
        <div
          class="q-px-md flex items-center justify-center"
          style="position: relative"
        >
          <q-icon
            :name="currentIcon"
            :size="currentDept > 2 ? '3em' : '6em'"
            color="primary"
            class="col"
          />
          <q-btn
            round
            :dense="currentDept > 2"
            color="white"
            size="10px"
            style="position: absolute; bottom: 0"
            :style="{ right: currentDept > 2 ? '.5rem' : '1.75rem' }"
          >
            <q-icon name="add" color="primary" size="1.5rem" />
          </q-btn>
        </div>
        <div
          class="text-overflow-handle block text-center"
          :class="{
            'q-px-md': currentDept < 3,
            'q-pr-xl': currentDept > 2,
          }"
          style="max-width: 100%"
        >
          สร้าง{{ DEPT_NAME[currentDept] }}ใหม่
        </div>
      </div>
    </div>
  </div>
  <div
    style="grid-column: 1 / span 5"
    class="text-h6 q-mt-md"
    v-if="currentDept > 2"
  >
    เอกสาร
  </div>
  <div class="grid q-mt-md">
    <div v-for="value in currentFile">
      <div
        :style="{
          position: 'relative',
          display: 'flex',
          gap: '0.5rem',
          flexDirection: 'column',
          alignItems: 'center',
          padding: '1rem',
          maxWidth: '100%',
        }"
        class="box"
        @click="() => getFileInfo(value)"
      >
        <div class="q-px-md flex items-center justify-center">
          <file-icon
            size="preview"
            :fileMimeType="value.fileType ? value.fileType : 'unknow'"
          />
        </div>
        <div
          class="absolute"
          style="top: 0.5rem; right: 0.5rem"
          v-if="props.action"
        >
          <file-item-action
            @edit="
              () =>
                triggerFileEdit(
                  {
                    title: value.title,
                    description: value.description,
                    keyword: value.keyword.join(','),
                    category: value.category.join(','),
                  },
                  value.pathname,
                )
            "
            @delete="() => triggerFileDelete(value.pathname)"
          />
        </div>
        <div
          class="text-overflow-handle block q-px-md text-center"
          style="max-width: 100%"
        >
          {{ getFileNameFormat(value.fileName) }}
        </div>
      </div>
    </div>
    <div v-if="props.action && currentDept > 2">
      <div
        :style="{
          display: 'flex',
          gap: '0.5rem',
          flexDirection: 'column',
          alignItems: 'center',
          padding: '1rem',
          maxWidth: '100%',
        }"
        class="dashed"
        @click="() => triggerFileCreate()"
      >
        <div
          class="q-px-md flex items-center justify-center"
          style="position: relative"
        >
          <q-icon name="mdi-file" class="add-icon" size="6em" color="primary" />
          <q-btn
            round
            color="white"
            size="10px"
            style="position: absolute; right: 1.75rem; bottom: 0"
          >
            <q-icon name="add" color="primary" size="1.5rem" />
          </q-btn>
        </div>
        <div
          class="text-overflow-handle block q-px-md text-center"
          style="max-width: 100%"
        >
          สร้างไฟล์ใหม่
        </div>
      </div>
    </div>
  </div>

  <file-form
    :mode="fileFormType"
    :error="fileFormError"
    v-model:open="fileFormState"
    v-model:title="fileFormData.title"
    v-model:description="fileFormData.description"
    v-model:keyword="fileFormData.keyword"
    v-model:category="fileFormData.category"
    @filechange="(name: string) => (fileFormError.fileExist = checkFile(name))"
    @submit="submitFileForm"
  />

  <folder-form
    :mode="folderFormType"
    :tree="DEPT_NAME[currentDept]"
    v-if="currentDept < 4"
    v-model:open="folderFormState"
    v-model:name="folderFormData.name"
    @submit="submitFolderForm"
  />

  <upload-exist-dialog
    v-model:notification="fileExistNotification"
    @confirm="() => currentParam && submitFileForm(currentParam, true)"
    @cancel="() => (currentParam = undefined)"
  />

  <dialog-delete
    v-model:open="dialogDeleteState"
    @confirm="
      () =>
        deleteFormType &&
        { deleteFolder, deleteFile }[deleteFormType](deleteFormPath)
    "
  />
</template>

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

.dashed {
  opacity: 0.4;
  display: inline-block;
  border: 2px solid #6985c2;
  border-radius: 8px;
  cursor: pointer;
  border-style: dashed;
}

.add-icon {
  margin: auto auto;
}

.add-button {
  position: absolute;
  top: 50%;
  right: 40%;
  background-color: white;
}

.add-button-folder-level {
  position: absolute;
  left: 30px;
  top: 22px;
  background-color: white;
}

.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;
}
</style>
