<script setup>
import { computed, onMounted, ref } from "vue"

const dataStore = useDataStore()
const toast = useToast()

const { select, create, update } = useEntities("letterheads")

const letterheads = ref([])
const files = ref([])
const loading = ref(true)
const saving = ref(false)
const modalOpen = ref(false)
const selectedFile = ref(null)
const itemInfo = ref({})

const documentTypeOptions = computed(() =>
  Object.entries(dataStore.documentTypesForCreation || {})
    .filter(([key]) => key !== "serialInvoices")
    .map(([key, value]) => ({
      key,
      label: value.label || value.labelSingle || key
    }))
)

const getDocumentTypeLabel = (type) =>
  dataStore.documentTypesForCreation?.[type]?.label || type

const normalizePath = (path) =>
  String(path || "").trim().replace(/^\/+/, "")

const getFileForLetterhead = (letterhead) => {
  const letterheadPath = normalizePath(letterhead?.path)
  if (!letterheadPath) return null

  return files.value.find((file) => normalizePath(file.path) === letterheadPath) || null
}

const getFileNameForLetterhead = (letterhead) => {
  const file = getFileForLetterhead(letterhead)
  if (file?.name) return file.name

  const path = normalizePath(letterhead?.path)
  return path ? decodeURIComponent(path.split("/").pop()) : null
}

const sortedLetterheads = computed(() =>
  [...letterheads.value].sort((a, b) => {
    const aAll = !a.documentTypes?.length
    const bAll = !b.documentTypes?.length
    if (aAll !== bAll) return aAll ? -1 : 1
    return String(a.name || "").localeCompare(String(b.name || ""), "de")
  })
)

const refreshData = async () => {
  loading.value = true
  try {
    const [loadedLetterheads, loadedFiles] = await Promise.all([
      select("*", "name", true),
      useEntities("files").select()
    ])

    letterheads.value = loadedLetterheads
    files.value = loadedFiles
  } catch (error) {
    toast.add({
      title: "Briefpapiere konnten nicht geladen werden",
      description: error?.message,
      color: "error"
    })
  } finally {
    loading.value = false
  }
}

const resetForm = () => {
  itemInfo.value = {
    name: "",
    documentTypes: []
  }
  selectedFile.value = null
}

const openCreateModal = () => {
  resetForm()
  modalOpen.value = true
}

const openEditModal = (letterhead) => {
  itemInfo.value = {
    ...JSON.parse(JSON.stringify(letterhead)),
    documentTypes: Array.isArray(letterhead.documentTypes) ? [...letterhead.documentTypes] : []
  }
  selectedFile.value = null
  modalOpen.value = true
}

const onFileChange = (event) => {
  selectedFile.value = event.target.files?.[0] || null
}

const uploadLetterheadPdf = async () => {
  if (!selectedFile.value) return null

  if (selectedFile.value.type !== "application/pdf") {
    throw new Error("Bitte wähle eine PDF-Datei aus.")
  }

  const formData = new FormData()
  formData.append("file", selectedFile.value)
  formData.append("meta", JSON.stringify({ filename: selectedFile.value.name }))

  return await useNuxtApp().$api("/api/files/upload", {
    method: "POST",
    body: formData
  })
}

const saveLetterhead = async () => {
  if (!itemInfo.value.name?.trim()) {
    toast.add({ title: "Name fehlt", description: "Bitte gib eine Bezeichnung ein.", color: "warning" })
    return
  }

  if (!itemInfo.value.id && !selectedFile.value) {
    toast.add({ title: "PDF fehlt", description: "Bitte lade ein Briefpapier als PDF hoch.", color: "warning" })
    return
  }

  saving.value = true
  try {
    const uploaded = await uploadLetterheadPdf()
    const payload = {
      name: itemInfo.value.name.trim(),
      documentTypes: Array.isArray(itemInfo.value.documentTypes) ? itemInfo.value.documentTypes : [],
      path: uploaded?.path || itemInfo.value.path
    }

    if (itemInfo.value.id) {
      await update(itemInfo.value.id, payload, true)
    } else {
      await create(payload, true)
    }

    modalOpen.value = false
    await refreshData()
  } catch (error) {
    toast.add({
      title: "Briefpapier konnte nicht gespeichert werden",
      description: error?.message,
      color: "error"
    })
  } finally {
    saving.value = false
  }
}

const archiveLetterhead = async (letterhead) => {
  await update(letterhead.id, { archived: true }, true)
  await refreshData()
}

const downloadLetterhead = async (letterhead) => {
  const file = getFileForLetterhead(letterhead)
  if (!file?.id) {
    toast.add({
      title: "Datei nicht gefunden",
      description: "Für dieses Briefpapier konnte keine Datei zugeordnet werden.",
      color: "warning"
    })
    return
  }

  await useFiles().downloadFile(file.id)
}

onMounted(refreshData)
</script>

<template>
  <UDashboardNavbar title="Briefpapiere">
    <template #right>
      <UButton icon="i-heroicons-plus" @click="openCreateModal">
        Briefpapier
      </UButton>
    </template>
  </UDashboardNavbar>

  <UDashboardPanelContent>
    <UTable
      :data="sortedLetterheads"
      :loading="loading"
      :columns="normalizeTableColumns([
        { key: 'name', label: 'Bezeichnung' },
        { key: 'documentTypes', label: 'Verwendung' },
        { key: 'path', label: 'Datei' },
        { key: 'actions', label: '' }
      ])"
    >
      <template #name-cell="{ row }">
        <span class="font-medium text-gray-900 dark:text-white">
          {{ row.original.name || "Briefpapier" }}
        </span>
      </template>

      <template #documentTypes-cell="{ row }">
        <div class="flex flex-wrap gap-1">
          <UBadge v-if="!row.original.documentTypes?.length" color="primary" variant="soft">
            Alle Dokumente
          </UBadge>
          <template v-else>
            <UBadge
              v-for="type in row.original.documentTypes"
              :key="type"
              color="gray"
              variant="soft"
            >
              {{ getDocumentTypeLabel(type) }}
            </UBadge>
          </template>
        </div>
      </template>

      <template #path-cell="{ row }">
        <UButton
          v-if="getFileForLetterhead(row.original)"
          icon="i-heroicons-arrow-down-tray"
          color="gray"
          variant="ghost"
          @click.stop="downloadLetterhead(row.original)"
        >
          {{ getFileNameForLetterhead(row.original) || "PDF" }}
        </UButton>
        <span v-else-if="getFileNameForLetterhead(row.original)" class="text-sm text-gray-700 dark:text-gray-300">
          {{ getFileNameForLetterhead(row.original) }}
        </span>
        <span v-else class="text-sm text-gray-500">Keine Datei hinterlegt</span>
      </template>

      <template #actions-cell="{ row }">
        <div class="flex justify-end gap-1">
          <UButton
            icon="i-heroicons-pencil-square"
            color="gray"
            variant="ghost"
            @click="openEditModal(row.original)"
          />
          <ButtonWithConfirm
            color="error"
            variant="ghost"
            @confirmed="archiveLetterhead(row.original)"
          >
            <template #button>Archivieren</template>
            <template #header>
              <span class="font-bold">Briefpapier archivieren?</span>
            </template>
            Das Briefpapier "{{ row.original.name }}" wird archiviert.
          </ButtonWithConfirm>
        </div>
      </template>
      <template #empty>
        <TableEmptyState label="Keine Briefpapiere gefunden" icon="i-heroicons-document" />
      </template>
    </UTable>
  </UDashboardPanelContent>

  <UModal v-model:open="modalOpen" :ui="{ width: 'sm:max-w-2xl' }">
    <template #content>
      <UCard>
        <template #header>
          <div class="flex items-center justify-between">
            <h3 class="text-lg font-semibold">
              {{ itemInfo.id ? "Briefpapier bearbeiten" : "Briefpapier erstellen" }}
            </h3>
            <UButton icon="i-heroicons-x-mark" color="gray" variant="ghost" @click="modalOpen = false" />
          </div>
        </template>

        <div class="space-y-4">
          <UFormField label="Bezeichnung" required>
            <UInput v-model="itemInfo.name" icon="i-heroicons-tag" placeholder="z.B. Standard Briefpapier" />
          </UFormField>

          <UFormField label="Verwendung">
            <USelectMenu
              v-model="itemInfo.documentTypes"
              :options="documentTypeOptions"
              multiple
              option-attribute="label"
              value-attribute="key"
              placeholder="Alle Dokumente"
            />
          </UFormField>

          <UFormField :label="itemInfo.id ? 'PDF ersetzen' : 'PDF hochladen'" :required="!itemInfo.id">
            <input
              type="file"
              accept="application/pdf"
              class="block w-full text-sm text-gray-700 file:mr-4 file:rounded-md file:border-0 file:bg-primary-50 file:px-3 file:py-2 file:text-sm file:font-medium file:text-primary-700 hover:file:bg-primary-100 dark:text-gray-200 dark:file:bg-primary-950 dark:file:text-primary-300"
              @change="onFileChange"
            >
          </UFormField>

          <div v-if="itemInfo.path" class="text-sm text-gray-500">
            Aktuelle Datei: {{ itemInfo.path.split("/").pop() }}
          </div>
        </div>

        <template #footer>
          <div class="flex justify-end gap-2">
            <UButton color="gray" variant="ghost" @click="modalOpen = false">
              Abbrechen
            </UButton>
            <UButton :loading="saving" icon="i-heroicons-check" @click="saveLetterhead">
              Speichern
            </UButton>
          </div>
        </template>
      </UCard>
    </template>
  </UModal>
</template>
