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

// --- Services & Stores ---
const dataStore = useDataStore()
const tempStore = useTempStore()
const router = useRouter()
const route = useRoute()
const modal = useModal()
const toast = useToast()
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)
const draggedItem = ref(null)

// --- 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
  } else {
    currentFolder.value = null
  }
  loadingDocs.value = false
  loaded.value = true
}

onMounted(() => setupPage())

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

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

// --- Drag & Drop ---
const handleDragStart = (entry) => {
  draggedItem.value = entry
}

const handleDrop = async (targetFolder) => {
  if (!draggedItem.value || draggedItem.value.id === targetFolder.id) return

  // Verhindern, dass Ordner in sich selbst verschoben werden
  if (draggedItem.value.type === 'folder' && draggedItem.value.id === targetFolder.id) return

  loadingDocs.value = true
  try {
    if (draggedItem.value.type === 'file') {
      await useEntities("files").update(draggedItem.value.id, { folder: targetFolder.id })
    } else {
      await useEntities("folders").update(draggedItem.value.id, { parent: targetFolder.id })
    }
    toast.add({ title: 'Erfolgreich verschoben', icon: 'i-heroicons-check-circle', color: 'green' })
    await setupPage()
  } catch (e) {
    toast.add({ title: 'Fehler beim Verschieben', color: 'red' })
  } finally {
    draggedItem.value = null
    loadingDocs.value = false
  }
}

// --- Data Mapping ---
const renderedFileList = computed(() => {
  const folderList = folders.value
      .filter(i => currentFolder.value ? i.parent === currentFolder.value.id : !i.parent)
      .map(i => ({ ...i, label: i.name, type: "folder" }))
      .sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: 'base' }))

  const fileList = documents.value
      .filter(i => currentFolder.value ? i.folder === currentFolder.value.id : !i.folder)
      .map(i => ({ ...i, label: i.path.split("/").pop(), type: "file" }))
      .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
})

// --- Actions ---
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 clearSearchString = () => {
  searchString.value = ''
  debouncedSearch.value = ''
  tempStore.clearSearchString("files")
}

// --- Shortcuts ---
defineShortcuts({
  '/': () => document.getElementById("searchinput").focus(),
  '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(entry)
    }
  },
  'arrowdown': () => {
    if (selectedFileIndex.value < renderedFileList.value.length - 1) selectedFileIndex.value++
  },
  'arrowup': () => {
    if (selectedFileIndex.value > 0) selectedFileIndex.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-30 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"
          :ui-menu="{ zIndex: 'z-50' }"
      >
        <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 },
          onUploadFinished: () => setupPage()
        })"
        >Datei</UButton>
        <UButton
            icon="i-heroicons-folder-plus"
            color="white"
            @click="createFolderModalOpen = true"
        >Ordner</UButton>
      </UButtonGroup>
    </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">
        <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 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"
              draggable="true"
              @dragstart="handleDragStart(entry)"
              @dragover.prevent
              @drop="entry.type === 'folder' ? handleDrop(entry) : null"
              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="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="entry in renderedFileList"
              :key="entry.id"
              draggable="true"
              @dragstart="handleDragStart(entry)"
              @dragover.prevent
              @drop="entry.type === 'folder' ? handleDrop(entry) : null"
              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="entry.type === 'folder' ? changeFolder(entry) : showFile(entry.id)"
          >
            <UIcon
                :name="entry.type === 'folder' ? 'i-heroicons-folder-solid' : 'i-heroicons-document-text'"
                class="w-12 h-12 mb-2 group-hover:scale-110 transition-transform"
                :class="entry.type === 'folder' ? 'text-primary-500' : 'text-gray-400'"
            />
            <span class="text-sm font-medium text-center truncate w-full">{{ entry.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>
/* Drag & Drop Visuals */
[draggable="true"] {
  user-select: none;
}
.bg-primary-50 {
  transition: background-color 0.2s ease;
}
</style>