<script setup>
import { ref, computed, watch } from 'vue';
import DocumentDisplayModal from "~/components/DocumentDisplayModal.vue";
import DocumentUploadModal from "~/components/DocumentUploadModal.vue";
import dayjs from "dayjs";
import arraySort from "array-sort";

// --- Shortcuts ---
defineShortcuts({
  '/': () => document.getElementById("searchinput").focus(),
  '+': () => { uploadModalOpen.value = true },
  'Enter': {
    usingInput: true,
    handler: () => {
      const entry = renderedFileList.value[selectedFileIndex.value]
      if (!entry) return
      if (entry.type === "file") showFile(entry.id)
      else if (entry.type === "folder") changeFolder(folders.value.find(i => i.id === entry.id))
    }
  },
  'arrowdown': () => {
    if (selectedFileIndex.value < renderedFileList.value.length - 1) selectedFileIndex.value++
  },
  'arrowup': () => {
    if (selectedFileIndex.value > 0) selectedFileIndex.value--
  }
})

const dataStore = useDataStore()
const tempStore = useTempStore()
const router = useRouter()
const route = useRoute()
const modal = useModal()
const auth = useAuthStore()
const files = useFiles()

// --- State ---
const documents = ref([])
const folders = ref([])
const filetags = ref([])
const currentFolder = ref(null)
const loadingDocs = ref(true)
const loaded = ref(false)
const displayMode = ref("list")
const displayModes = [
  { label: 'Liste', key: 'list', icon: 'i-heroicons-list-bullet' },
  { label: 'Kacheln', key: 'rectangles', icon: 'i-heroicons-squares-2x2' }
]

const createFolderModalOpen = ref(false)
const createFolderData = ref({ name: '', standardFiletype: null, standardFiletypeIsOptional: true })
const selectedFiles = ref({})
const selectedFileIndex = ref(0)

// --- Search & Debounce ---
const searchString = ref(tempStore.searchStrings["files"] || '')
const debouncedSearch = ref(searchString.value)
let debounceTimeout = null

watch(searchString, (val) => {
  clearTimeout(debounceTimeout)
  debounceTimeout = setTimeout(() => {
    debouncedSearch.value = val
    tempStore.modifySearchString('files', val)
  }, 300)
})

// --- Logic ---
const setupPage = async () => {
  loadingDocs.value = true
  const [fRes, dRes, tRes] = await Promise.all([
    useEntities("folders").select(),
    files.selectDocuments(),
    useEntities("filetags").select()
  ])
  folders.value = fRes
  documents.value = dRes
  filetags.value = tRes

  if (route.query?.folder) {
    currentFolder.value = folders.value.find(i => i.id === route.query.folder) || null
  }
  loadingDocs.value = false
  loaded.value = true
}

onMounted(() => setupPage())

const currentFolders = computed(() => {
  return folders.value
      .filter(i => currentFolder.value ? i.parent === currentFolder.value.id : !i.parent)
      .sort((a, b) => a.name.localeCompare(b.name, undefined, { sensitivity: 'base' }))
})

const breadcrumbLinks = computed(() => {
  const links = [{ label: "Home", icon: "i-heroicons-home", click: () => changeFolder(null) }]
  if (currentFolder.value) {
    let path = []
    let curr = currentFolder.value
    while (curr) {
      path.unshift({
        label: curr.name,
        icon: "i-heroicons-folder",
        click: () => changeFolder(folders.value.find(f => f.id === curr.id))
      })
      curr = folders.value.find(f => f.id === curr.parent)
    }
    return [...links, ...path]
  }
  return links
})

const renderedFileList = computed(() => {
  const folderList = currentFolders.value.map(i => ({
    label: i.name,
    id: i.id,
    type: "folder",
    createdAt: i.createdAt
  }))

  const fileList = documents.value
      .filter(i => currentFolder.value ? i.folder === currentFolder.value.id : !i.folder)
      .map(i => ({
        label: i.path.split("/").pop(),
        id: i.id,
        type: "file",
        createdAt: i.createdAt
      }))
      .sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: 'base' }))

  let combined = [...folderList, ...fileList]
  if (debouncedSearch.value) {
    combined = useSearch(debouncedSearch.value, combined)
  }
  return combined
})

const changeFolder = async (folder) => {
  currentFolder.value = folder
  await router.push(folder ? `/files?folder=${folder.id}` : `/files`)
}

const createFolder = async () => {
  await useEntities("folders").create({
    parent: currentFolder.value?.id,
    name: createFolderData.value.name,
    standardFiletype: createFolderData.value.standardFiletype,
    standardFiletypeIsOptional: createFolderData.value.standardFiletypeIsOptional
  })
  createFolderModalOpen.value = false
  createFolderData.value = { name: '', standardFiletype: null, standardFiletypeIsOptional: true }
  setupPage()
}

const showFile = (fileId) => {
  modal.open(DocumentDisplayModal, {
    documentData: documents.value.find(i => i.id === fileId),
    onUpdatedNeeded: () => setupPage()
  })
}

const downloadSelected = async () => {
  const ids = Object.keys(selectedFiles.value).filter(k => selectedFiles.value[k])
  await useFiles().downloadFile(undefined, ids)
}

const clearSearchString = () => {
  searchString.value = ''
  debouncedSearch.value = ''
  tempStore.clearSearchString("files")
}

const selectAll = (event) => {
  if (event.target.checked) {
    const obj = {}
    renderedFileList.value.filter(e => e.type === 'file').forEach(e => obj[e.id] = true)
    selectedFiles.value = obj
  } else {
    selectedFiles.value = {}
  }
}
</script>

<template>
  <UDashboardNavbar title="Dateien">
    <template #right>
      <UInput
          id="searchinput"
          v-model="searchString"
          icon="i-heroicons-magnifying-glass"
          autocomplete="off"
          placeholder="Suche..."
          class="hidden lg:block w-64"
          @keydown.esc="$event.target.blur()"
      >
        <template #trailing>
          <div class="flex items-center gap-1">
            <UKbd value="/" />
            <UButton
                v-if="searchString.length > 0"
                icon="i-heroicons-x-mark"
                variant="ghost"
                color="gray"
                size="xs"
                @click="clearSearchString"
            />
          </div>
        </template>
      </UInput>
    </template>
  </UDashboardNavbar>

  <UDashboardToolbar class="sticky top-0 z-10 bg-white dark:bg-gray-900 border-b border-gray-200 dark:border-gray-800">
    <template #left>
      <UBreadcrumb :links="breadcrumbLinks" :ui="{ ol: 'gap-x-2', li: 'text-sm' }" />
    </template>
    <template #right>
      <USelectMenu
          v-model="displayMode"
          :options="displayModes"
          value-attribute="key"
          class="w-32"
      >
        <template #label>
          <UIcon :name="displayModes.find(i => i.key === displayMode).icon" class="w-4 h-4" />
          <span>{{ displayModes.find(i => i.key === displayMode).label }}</span>
        </template>
      </USelectMenu>

      <UButtonGroup size="sm">
        <UButton
            icon="i-heroicons-document-plus"
            color="primary"
            @click="modal.open(DocumentUploadModal, {
            fileData: {
              folder: currentFolder?.id,
              type: currentFolder?.standardFiletype,
              typeEnabled: currentFolder?.standardFiletypeIsOptional
            },
            onUploadFinished: () => setupPage()
          })"
        >Datei</UButton>
        <UButton
            icon="i-heroicons-folder-plus"
            color="white"
            @click="createFolderModalOpen = true"
        >Ordner</UButton>
      </UButtonGroup>

      <UButton
          v-if="Object.values(selectedFiles).some(Boolean)"
          icon="i-heroicons-cloud-arrow-down"
          color="gray"
          variant="solid"
          @click="downloadSelected"
      >Download</UButton>
    </template>
  </UDashboardToolbar>

  <div id="drop_zone" class="flex-1 overflow-hidden flex flex-col relative">
    <div v-if="!loaded" class="p-10 flex justify-center">
      <UProgress animation="carousel" class="w-1/2" />
    </div>

    <UDashboardPanelContent v-else class="p-0 overflow-y-auto">
      <div v-if="displayMode === 'list'" class="min-w-full inline-block align-middle">
        <table class="min-w-full divide-y divide-gray-300 dark:divide-gray-700">
          <thead class="bg-gray-50 dark:bg-gray-800 sticky top-0 z-20">
          <tr>
            <th scope="col" class="py-3.5 pl-4 pr-3 sm:pl-6 w-10">
              <UCheckbox @change="selectAll" />
            </th>
            <th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 dark:text-white sm:pl-6">Name</th>
            <th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-white">Erstellt am</th>
          </tr>
          </thead>
          <tbody class="divide-y divide-gray-200 dark:divide-gray-800 bg-white dark:bg-gray-900">
          <tr
              v-for="(entry, index) in renderedFileList"
              :key="entry.id"
              class="hover:bg-gray-50 dark:hover:bg-gray-800/50 cursor-pointer transition-colors"
              :class="{'bg-primary-50 dark:bg-primary-900/10': index === selectedFileIndex}"
              @click="entry.type === 'folder' ? changeFolder(entry) : showFile(entry.id)"
          >
            <td class="relative w-12 px-6 sm:w-16 sm:px-8" @click.stop>
              <UCheckbox v-if="entry.type === 'file'" v-model="selectedFiles[entry.id]" />
            </td>
            <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
              <div class="flex items-center">
                <UIcon
                    :name="entry.type === 'folder' ? 'i-heroicons-folder-solid' : 'i-heroicons-document-text'"
                    class="flex-shrink-0 h-5 w-5 mr-3"
                    :class="entry.type === 'folder' ? 'text-primary-500' : 'text-gray-400'"
                />
                <span class="font-medium text-gray-900 dark:text-white truncate max-w-md">
                    {{ entry.label }}
                  </span>
              </div>
            </td>
            <td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500 dark:text-gray-400">
              {{ dayjs(entry.createdAt).format("DD.MM.YY · HH:mm") }}
            </td>
          </tr>
          </tbody>
        </table>
      </div>

      <div v-else class="p-6">
        <div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8 gap-4">
          <div
              v-for="folder in currentFolders"
              :key="folder.id"
              class="group relative bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-4 flex flex-col items-center hover:border-primary-500 transition-all cursor-pointer"
              @click="changeFolder(folder)"
          >
            <UIcon name="i-heroicons-folder-solid" class="w-12 h-12 text-primary-500 mb-2 group-hover:scale-110 transition-transform" />
            <span class="text-sm font-medium text-center truncate w-full">{{ folder.name }}</span>
          </div>

          <div
              v-for="doc in renderedFileList.filter(e => e.type === 'file')"
              :key="doc.id"
              class="group relative bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-4 flex flex-col items-center hover:border-primary-500 transition-all cursor-pointer"
              @click="showFile(doc.id)"
          >
            <UCheckbox v-model="selectedFiles[doc.id]" class="absolute top-2 left-2 opacity-0 group-hover:opacity-100 transition-opacity" @click.stop />
            <UIcon name="i-heroicons-document-text" class="w-12 h-12 text-gray-400 mb-2 group-hover:scale-110 transition-transform" />
            <span class="text-sm font-medium text-center truncate w-full">{{ doc.label }}</span>
          </div>
        </div>
      </div>
    </UDashboardPanelContent>
  </div>

  <UModal v-model="createFolderModalOpen">
    <UCard>
      <template #header>
        <div class="flex items-center justify-between">
          <h3 class="text-lg font-bold">Ordner erstellen</h3>
          <UButton color="gray" variant="ghost" icon="i-heroicons-x-mark" @click="createFolderModalOpen = false" />
        </div>
      </template>

      <div class="space-y-4">
        <UFormGroup label="Name" required>
          <UInput v-model="createFolderData.name" placeholder="Name eingeben..." autofocus @keyup.enter="createFolder" />
        </UFormGroup>

        <UFormGroup label="Standard-Dateityp">
          <USelectMenu
              v-model="createFolderData.standardFiletype"
              :options="filetags"
              option-attribute="name"
              value-attribute="id"
              placeholder="Kein Standard"
          />
        </UFormGroup>

        <UCheckbox
            v-if="createFolderData.standardFiletype"
            v-model="createFolderData.standardFiletypeIsOptional"
            label="Typ ist optional"
        />
      </div>

      <template #footer>
        <div class="flex justify-end gap-2">
          <UButton color="gray" variant="soft" @click="createFolderModalOpen = false">Abbrechen</UButton>
          <UButton color="primary" :disabled="!createFolderData.name" @click="createFolder">Erstellen</UButton>
        </div>
      </template>
    </UCard>
  </UModal>
</template>

<style scoped>
#drop_zone::after {
  content: 'Datei hierher ziehen';
  @apply absolute inset-0 flex items-center justify-center bg-primary-500/10 border-4 border-dashed border-primary-500 opacity-0 pointer-events-none transition-opacity z-50 rounded-xl m-4;
}

#drop_zone:hover::after {
  /* In der setupPage Logik wird das Modal getriggert,
     dieser Style dient nur der visuellen Hilfe */
}

/* Custom Table Shadows & Borders */
table {
  border-collapse: separate;
  border-spacing: 0;
}
</style>