<script setup>
const toast = useToast()
const modal = useModal()

const props = defineProps({
  documentData: {
    type: Object,
    required: true
  },
  openShowModal: {
    type: Boolean,
    required: false,
  },
  returnEmit: {
    type: Boolean
  },
})

const emit = defineEmits(["updateNeeded"])

const filetypes = ref([])
const getFiletypeId = () => props.documentData.type && typeof props.documentData.type === "object"
    ? props.documentData.type.id
    : props.documentData.type || null
const selectedFiletype = ref(getFiletypeId())

const resourceOptions = ref([
  {label: "Projekt", value: "project", entity: "projects", optionAttr: "name", route: (item) => `/standardEntity/projects/show/${item.id}`},
  {label: "Kunde", value: "customer", entity: "customers", optionAttr: "name", route: (item) => `/standardEntity/customers/show/${item.id}`},
  {label: "Lieferant", value: "vendor", entity: "vendors", optionAttr: "name", route: (item) => `/standardEntity/vendors/show/${item.id}`},
  {label: "Fahrzeug", value: "vehicle", entity: "vehicles", optionAttr: "licensePlate", route: (item) => `/standardEntity/vehicles/show/${item.id}`},
  {label: "Objekt", value: "plant", entity: "plants", optionAttr: "name", route: (item) => `/standardEntity/plants/show/${item.id}`},
  {label: "Vertrag", value: "contract", entity: "contracts", optionAttr: "name", route: (item) => `/standardEntity/contracts/show/${item.id}`},
  {label: "Produkt", value: "product", entity: "products", optionAttr: "name", route: (item) => `/standardEntity/products/show/${item.id}`},
  {label: "Ausgangsbeleg", value: "createddocument", entity: "createddocuments", optionAttr: "documentNumber", route: (item) => `/createDocument/show/${item.id}`},
  {label: "Eingangsrechnung", value: "incominginvoice", entity: "incominginvoices", optionAttr: "reference", route: (item) => `/incomingInvoices/show/${item.id}`},
  {label: "Inventarartikel", value: "inventoryitem", entity: "inventoryitems", optionAttr: "name", route: (item) => `/standardEntity/inventoryitems/show/${item.id}`},
  {label: "Überprüfung", value: "check", entity: "checks", optionAttr: "name", route: (item) => `/standardEntity/checks/show/${item.id}`},
  {label: "Mitarbeiter", value: "authProfile", entity: "profiles", optionAttr: "fullName", route: (item) => `/staff/profiles/${item.id}`}
])

const resourceToAssign = ref("project")
const itemOptions = ref([])
const idToAssign = ref(null)

const selectedResource = computed(() => resourceOptions.value.find((option) => option.value === resourceToAssign.value))

const setup = async () => {
  filetypes.value = await useEntities("filetags").select()
  selectedFiletype.value = getFiletypeId()
  await getItemsBySelectedResource()
}

const updateDocument = async (payload, closeAfterUpdate = false) => {
  try {
    await useEntities("files").update(props.documentData.id, payload, true)
    Object.assign(props.documentData, payload)
    toast.add({title: "Datei aktualisiert"})
    emit("updateNeeded")
    if (closeAfterUpdate) modal.close()
  } catch (error) {
    console.error(error)
    toast.add({title: "Datei konnte nicht aktualisiert werden", color: "error"})
  }
}

const archiveDocument = async () => {
  await updateDocument({archived: true}, true)
}

const getItemsBySelectedResource = async () => {
  idToAssign.value = null
  itemOptions.value = selectedResource.value?.entity
      ? await useEntities(selectedResource.value.entity).select()
      : []
}

const updateDocumentAssignment = async () => {
  if (!selectedResource.value || !idToAssign.value) return

  await updateDocument({[selectedResource.value.value]: idToAssign.value})
  props.documentData[selectedResource.value.value] = itemOptions.value.find((item) => item.id === idToAssign.value) || idToAssign.value
  idToAssign.value = null
}

const removeAssignment = async (assignment) => {
  await updateDocument({[assignment.value]: null})
  props.documentData[assignment.value] = null
}

const getAssignmentItem = (assignment) => {
  const value = props.documentData[assignment.value]
  return value && typeof value === "object" ? value : null
}

const getAssignmentLabel = (assignment) => {
  const value = props.documentData[assignment.value]
  if (!value) return ""
  if (typeof value === "object") return value[assignment.optionAttr] || value.name || value.id
  return value
}

const currentAssignments = computed(() =>
    resourceOptions.value
        .filter((assignment) => Boolean(props.documentData[assignment.value]))
        .map((assignment) => ({
          ...assignment,
          item: getAssignmentItem(assignment),
          display: getAssignmentLabel(assignment)
        }))
)

const displayedFileTags = computed(() => {
  if (Array.isArray(props.documentData.filetags) && props.documentData.filetags.length) {
    return props.documentData.filetags
  }

  if (props.documentData.type && typeof props.documentData.type === "object") {
    return [props.documentData.type]
  }

  const selected = filetypes.value.find((filetype) => filetype.id === props.documentData.type)
  return selected ? [selected] : []
})

const updateFiletype = async () => {
  await updateDocument({type: selectedFiletype.value || null})
  props.documentData.type = selectedFiletype.value || null
}

setup()
</script>

<template>
  <UModal fullscreen>
    <template #content>
      <UCard :ui="{ body: { base: 'flex-1' }, ring: '', divide: 'divide-y divide-gray-100 dark:divide-gray-800' }" class="h-full">
        <template #header>
          <div class="flex flex-row justify-between">
            <div class="flex items-center gap-2">
              <UBadge
                  v-for="tag in displayedFileTags"
                  :key="tag.id"
              >
                {{tag.name}}
              </UBadge>
            </div>
            <UButton color="gray" variant="ghost" icon="i-heroicons-x-mark-20-solid" class="-my-1" @click="modal.close()" />
          </div>
        </template>

        <div class="flex flex-row">
          <div class="w-1/3">
            <PDFViewer
                v-if="props.documentData.id && props.documentData.path.toLowerCase().includes('pdf')"
                :file-id="props.documentData.id" />

            <img
                v-else
                class="w-full"
                :src="props.documentData.url"
                alt=""
            />
          </div>

          <div class="w-2/3 p-5">
            <UButtonGroup>
              <ArchiveButton
                  color="error"
                  variant="outline"
                  type="files"
                  @confirmed="archiveDocument"
              />

              <UButton
                  :to="props.documentData.url"
                  variant="outline"
                  icon="i-heroicons-arrow-top-right-on-square"
                  target="_blank"
              >
                Öffnen
              </UButton>
            </UButtonGroup>

            <USeparator class="my-3" label="Zuweisungen"/>

            <div class="space-y-2">
              <div
                  v-for="assignment in currentAssignments"
                  :key="assignment.value"
                  class="flex items-center justify-between gap-3 rounded-md border border-gray-200 p-2 dark:border-gray-800"
              >
                <div class="min-w-0">
                  <div class="text-xs text-gray-500">{{ assignment.label }}</div>
                  <nuxt-link
                      v-if="assignment.item"
                      :to="assignment.route(assignment.item)"
                      class="block truncate font-medium text-primary"
                  >
                    {{ assignment.display }}
                  </nuxt-link>
                  <span v-else class="font-medium">{{ assignment.display }}</span>
                </div>
                <UButton
                    icon="i-heroicons-x-mark"
                    color="neutral"
                    variant="ghost"
                    @click="removeAssignment(assignment)"
                />
              </div>
              <UAlert
                  v-if="currentAssignments.length === 0"
                  icon="i-heroicons-link"
                  title="Noch keine Zuweisungen vorhanden"
                  color="neutral"
                  variant="soft"
              />
            </div>

            <USeparator class="my-3" label="Datei zuweisen"/>

            <UFormField label="Bereich auswählen">
              <USelectMenu
                  v-model="resourceToAssign"
                  :items="resourceOptions"
                  value-key="value"
                  label-key="label"
                  @update:model-value="getItemsBySelectedResource"
              />
            </UFormField>

            <UFormField class="mt-3" label="Eintrag auswählen">
              <USelectMenu
                  v-model="idToAssign"
                  :items="itemOptions"
                  :label-key="selectedResource ? selectedResource.optionAttr : 'name'"
                  value-key="id"
                  :search-input="{ placeholder: 'Eintrag suchen...' }"
                  :filter-fields="[selectedResource ? selectedResource.optionAttr : 'name']"
              />
            </UFormField>

            <div class="mt-2 flex justify-end">
              <UButton
                  icon="i-heroicons-link"
                  :disabled="!idToAssign"
                  @click="updateDocumentAssignment"
              >
                Zuweisen
              </UButton>
            </div>

            <USeparator class="my-5" label="Dateityp"/>

            <InputGroup class="w-full">
              <USelectMenu
                  v-model="selectedFiletype"
                  class="flex-auto"
                  value-key="id"
                  label-key="name"
                  :items="filetypes"
                  @update:model-value="updateFiletype"
              />
            </InputGroup>
          </div>
        </div>
      </UCard>
    </template>
  </UModal>
</template>

<style scoped>
.bigPreview {
  width: 100%;
  aspect-ratio: 1/ 1.414;
}
</style>
