<script setup>
const props = defineProps({
  scanData: {
    type: Object,
    default: () => ({
      folder: null,
      type: null,
      typeEnabled: true
    })
  }
})

const emit = defineEmits(["scanFinished"])

const modal = useModal()
const toast = useToast()
const { $api } = useNuxtApp()

const loadingAgents = ref(true)
const scanInProgress = ref(false)
const agents = ref([])
const selectedAgentId = ref(null)
const currentJob = ref(null)
const statusMessage = ref("")

const scanForm = reactive({
  filename: `scan-${new Date().toISOString().slice(0, 10)}.pdf`,
  scannerName: "",
  format: "pdf",
  resolution: 300,
  mode: "Color",
  source: "ADF Duplex",
  postprocess: true,
  postprocessProfile: "receipt"
})

const activeAgents = computed(() =>
  agents.value.filter((agent) => agent.active && agent.capabilities?.scan)
)

const selectedAgent = computed(() =>
  agents.value.find((agent) => agent.id === selectedAgentId.value) || null
)

const scannerOptions = computed(() =>
  (selectedAgent.value?.scannerNames || []).map((scanner) => ({
    label: scanner,
    value: scanner
  }))
)

const isOnline = (agent) => {
  if (!agent.lastSeenAt) return false
  return Date.now() - new Date(agent.lastSeenAt).getTime() < 2 * 60 * 1000
}

const applyAgentDefaults = (agent) => {
  if (!agent) return

  scanForm.scannerName = agent.preferredScannerName || agent.scannerNames?.[0] || ""
  scanForm.format = agent.scanDefaults?.format || "pdf"
  scanForm.resolution = Number(agent.scanDefaults?.resolution || 300)
  scanForm.mode = agent.scanDefaults?.mode || "Color"
  scanForm.source = agent.scanDefaults?.source || "ADF Duplex"
  scanForm.postprocess = agent.scanDefaults?.postprocess !== false
  scanForm.postprocessProfile = agent.scanDefaults?.postprocessProfile || "receipt"

  if (!scanForm.filename || scanForm.filename.startsWith("scan-")) {
    scanForm.filename = `scan-${new Date().toISOString().slice(0, 10)}.${scanForm.format || "pdf"}`
  }
}

watch(selectedAgent, (agent) => applyAgentDefaults(agent))

const loadAgents = async () => {
  loadingAgents.value = true

  try {
    const response = await $api("/api/instance-agents")
    agents.value = response?.agents || []

    const firstOnlineAgent = activeAgents.value.find(isOnline)
    selectedAgentId.value = firstOnlineAgent?.id || activeAgents.value[0]?.id || null
    applyAgentDefaults(selectedAgent.value)
  } catch (err) {
    toast.add({
      title: "Scanner konnten nicht geladen werden",
      description: err?.data?.error || err?.message || "Unbekannter Fehler",
      color: "error"
    })
  } finally {
    loadingAgents.value = false
  }
}

const waitForJob = async (jobId) => {
  for (let i = 0; i < 90; i++) {
    await new Promise((resolve) => setTimeout(resolve, 2000))

    const response = await $api(`/api/scan-jobs/${jobId}`)
    const job = response?.job
    currentJob.value = job

    if (job?.status === "completed") return job
    if (job?.status === "failed" || job?.status === "canceled") {
      throw new Error(job.agentMessage || "Scan-Auftrag wurde abgebrochen.")
    }

    statusMessage.value = job?.status === "running"
      ? "Scanner arbeitet..."
      : "Warte auf den Agenten..."
  }

  throw new Error("Der Scan-Auftrag läuft länger als erwartet.")
}

const startScan = async () => {
  if (!selectedAgentId.value) return

  scanInProgress.value = true
  statusMessage.value = "Scan-Auftrag wird erstellt..."
  currentJob.value = null

  try {
    const response = await $api("/api/scan-jobs", {
      method: "POST",
      body: {
        agentId: selectedAgentId.value,
        scannerName: scanForm.scannerName || null,
        requestedFilename: scanForm.filename || null,
        settings: {
          format: scanForm.format || "pdf",
          resolution: Number(scanForm.resolution || 300),
          mode: scanForm.mode || "Color",
          source: scanForm.source || null,
          postprocess: scanForm.postprocess,
          postprocessProfile: scanForm.postprocessProfile
        },
        target: {
          folder: props.scanData.folder || null,
          type: props.scanData.type || null
        }
      }
    })

    currentJob.value = response?.job
    if (!response?.job?.id) {
      throw new Error("FEDEO hat keinen Scan-Auftrag zurückgegeben.")
    }

    statusMessage.value = "Warte auf den Agenten..."

    await waitForJob(response.job.id)

    toast.add({
      title: "Scan gespeichert",
      description: props.scanData.folder ? "Die Datei wurde im aktuellen Ordner abgelegt." : "Die Datei wurde in Dateien abgelegt.",
      color: "success"
    })

    emit("scanFinished")
    modal.close()
  } catch (err) {
    toast.add({
      title: "Scan fehlgeschlagen",
      description: err?.data?.error || err?.message || "Unbekannter Fehler",
      color: "error"
    })
    statusMessage.value = err?.message || "Scan fehlgeschlagen"
  } finally {
    scanInProgress.value = false
  }
}

loadAgents()
</script>

<template>
  <UModal>
    <template #content>
      <UCard class="shadow-xl ring-1 ring-black/5">
        <template #header>
          <div class="flex items-center justify-between gap-4">
            <div class="flex items-center gap-3">
              <div class="flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10 text-primary ring-1 ring-primary/15">
                <UIcon name="i-heroicons-document-magnifying-glass" class="h-5 w-5" />
              </div>
              <div>
                <h3 class="text-base font-semibold text-highlighted">Dokument scannen</h3>
                <p class="text-xs text-muted">Der Scan wird im aktuellen Ordner gespeichert.</p>
              </div>
            </div>
            <UButton
                color="neutral"
                variant="ghost"
                icon="i-heroicons-x-mark-20-solid"
                :disabled="scanInProgress"
                @click="modal.close()"
            />
          </div>
        </template>

        <div class="space-y-4">
          <UAlert
              v-if="!loadingAgents && activeAgents.length === 0"
              color="warning"
              variant="soft"
              icon="i-heroicons-exclamation-triangle"
              title="Kein aktiver Scan-Agent"
              description="Lege in der Administration einen Scanner-Agenten an und starte den lokalen Agenten."
          />

          <UFormField label="Scanner-Agent">
            <USelectMenu
                v-model="selectedAgentId"
                :items="activeAgents.map((agent) => ({ label: agent.name, value: agent.id, suffix: isOnline(agent) ? 'Online' : 'Offline' }))"
                value-key="value"
                label-key="label"
                placeholder="Agent wählen"
                :loading="loadingAgents"
                class="w-full"
                :disabled="scanInProgress"
            />
          </UFormField>

          <UFormField label="Scanner">
            <USelectMenu
                v-if="scannerOptions.length"
                v-model="scanForm.scannerName"
                :items="scannerOptions"
                value-key="value"
                label-key="label"
                placeholder="Standard-Scanner"
                class="w-full"
                :disabled="scanInProgress"
            />
            <UInput
                v-else
                v-model="scanForm.scannerName"
                placeholder="Standard-Scanner"
                :disabled="scanInProgress"
            />
          </UFormField>

          <UFormField label="Dateiname">
            <UInput v-model="scanForm.filename" :disabled="scanInProgress" />
          </UFormField>

          <div class="grid gap-3 sm:grid-cols-2">
            <UFormField label="Quelle">
              <UInput v-model="scanForm.source" placeholder="ADF Duplex" :disabled="scanInProgress" />
            </UFormField>
            <UFormField label="Auflösung">
              <UInput v-model.number="scanForm.resolution" type="number" min="75" step="25" :disabled="scanInProgress" />
            </UFormField>
          </div>

          <div class="grid gap-3 sm:grid-cols-2">
            <UFormField label="Modus">
              <UInput v-model="scanForm.mode" placeholder="Color" :disabled="scanInProgress" />
            </UFormField>
            <UFormField label="Format">
              <USelectMenu
                  v-model="scanForm.format"
                  :items="[
                    { label: 'PDF', value: 'pdf' },
                    { label: 'PNG', value: 'png' },
                    { label: 'TIFF', value: 'tiff' }
                  ]"
                  value-key="value"
                  label-key="label"
                  :disabled="scanInProgress"
              />
            </UFormField>
          </div>

          <div class="grid gap-3 sm:grid-cols-[auto_minmax(0,1fr)]">
            <UCheckbox
                v-model="scanForm.postprocess"
                label="OpenCV-Korrektur"
                :disabled="scanInProgress"
            />
            <UFormField label="Profil">
              <USelectMenu
                  v-model="scanForm.postprocessProfile"
                  :items="[
                    { label: 'Bon', value: 'receipt' },
                    { label: 'Dokument', value: 'document' },
                    { label: 'Rohscan', value: 'raw' }
                  ]"
                  value-key="value"
                  label-key="label"
                  :disabled="scanInProgress || !scanForm.postprocess"
              />
            </UFormField>
          </div>

          <UAlert
              v-if="statusMessage"
              color="info"
              variant="soft"
              icon="i-heroicons-clock"
              :title="statusMessage"
              :description="currentJob?.status ? `Status: ${currentJob.status}` : undefined"
          />
        </div>

        <template #footer>
          <div class="flex justify-end gap-2">
            <UButton color="neutral" variant="ghost" :disabled="scanInProgress" @click="modal.close()">Abbrechen</UButton>
            <UButton
                icon="i-heroicons-document-magnifying-glass"
                :loading="scanInProgress"
                :disabled="!selectedAgentId || loadingAgents"
                @click="startScan"
            >
              Scannen
            </UButton>
          </div>
        </template>
      </UCard>
    </template>
  </UModal>
</template>
