<script setup lang="ts">
import { format, isToday, isYesterday } from "date-fns"
import { de as deLocale } from "date-fns/locale"

type EmailAccount = {
  id: string
  email: string
  imapHost?: string | null
  hasPassword?: boolean
}

type EmailMailbox = {
  id: string
  path: string
  name: string
  delimiter?: string | null
  specialUse?: string | null
  unseen?: number
}

type EmailMailboxNode = {
  mailbox: EmailMailbox
  children: EmailMailboxNode[]
}

type EmailAddress = {
  name?: string | null
  address?: string | null
}

type EmailMessage = {
  id: string
  accountId: string
  mailboxPath: string
  subject?: string | null
  from?: EmailAddress[]
  to?: EmailAddress[]
  cc?: EmailAddress[]
  preview?: string | null
  seen?: boolean
  flagged?: boolean
  hasAttachments?: boolean
  receivedAt?: string | null
  sentAt?: string | null
  body?: {
    text?: string | null
    html?: string | null
  } | null
  attachments?: Array<{
    id: string
    filename?: string | null
    contentType?: string | null
    size?: number | null
  }>
}

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

const accounts = ref<EmailAccount[]>([])
const mailboxes = ref<EmailMailbox[]>([])
const messages = ref<EmailMessage[]>([])
const selectedAccountId = ref("")
const selectedMailboxPath = ref("INBOX")
const selectedMessage = ref<EmailMessage | null>(null)
const search = ref("")
const loadingAccounts = ref(true)
const loadingMailboxes = ref(false)
const loadingMessages = ref(false)
const loadingMessage = ref(false)
const syncing = ref(false)
const expandedMailboxPaths = ref<string[]>([])
const syncedMailboxPaths = ref<string[]>([])
const actionLoading = ref("")
const moveTargetMailboxPath = ref("")

const selectedAccount = computed(() =>
    accounts.value.find((account) => account.id === selectedAccountId.value) || null
)

const selectedMailbox = computed(() =>
    mailboxes.value.find((mailbox) => mailbox.path === selectedMailboxPath.value) || null
)

const mailboxPriority = (mailbox: EmailMailbox) => {
  if (mailbox.specialUse === "\\Inbox" || mailbox.path.toUpperCase() === "INBOX") return 0
  if (mailbox.specialUse === "\\Sent") return 1
  if (mailbox.specialUse === "\\Drafts") return 2
  if (mailbox.specialUse === "\\Archive") return 3
  if (mailbox.specialUse === "\\Junk") return 4
  if (mailbox.specialUse === "\\Trash") return 5
  return 9
}

const mailboxDelimiter = (mailbox: EmailMailbox) => {
  if (mailbox.delimiter) return mailbox.delimiter
  if (mailbox.path.includes("/")) return "/"
  if (mailbox.path.includes(".")) return "."
  return "/"
}

const parentMailboxPath = (mailbox: EmailMailbox, mailboxPaths: Set<string>) => {
  const delimiter = mailboxDelimiter(mailbox)
  const parts = mailbox.path.split(delimiter)

  while (parts.length > 1) {
    parts.pop()
    const candidate = parts.join(delimiter)
    if (mailboxPaths.has(candidate)) return candidate
  }

  return null
}

const sortMailboxNodes = (nodes: EmailMailboxNode[]) => {
  nodes.sort((first, second) =>
      mailboxPriority(first.mailbox) - mailboxPriority(second.mailbox)
      || mailboxLabel(first.mailbox).localeCompare(mailboxLabel(second.mailbox))
  )
  nodes.forEach((node) => sortMailboxNodes(node.children))
  return nodes
}

const mailboxTree = computed(() => {
  const mailboxPaths = new Set(mailboxes.value.map((mailbox) => mailbox.path))
  const nodes = new Map<string, EmailMailboxNode>()
  const roots: EmailMailboxNode[] = []

  mailboxes.value.forEach((mailbox) => {
    nodes.set(mailbox.path, { mailbox, children: [] })
  })

  mailboxes.value.forEach((mailbox) => {
    const node = nodes.get(mailbox.path)
    if (!node) return

    const parentPath = parentMailboxPath(mailbox, mailboxPaths)
    const parent = parentPath ? nodes.get(parentPath) : null

    if (parent) {
      parent.children.push(node)
    } else {
      roots.push(node)
    }
  })

  return sortMailboxNodes(roots)
})

const mailboxRows = computed(() => {
  const rows: Array<{ mailbox: EmailMailbox; depth: number; hasChildren: boolean }> = []
  const append = (node: EmailMailboxNode, depth: number) => {
    const expanded = expandedMailboxPaths.value.includes(node.mailbox.path)
    rows.push({ mailbox: node.mailbox, depth, hasChildren: node.children.length > 0 })
    if (expanded) {
      node.children.forEach((child) => append(child, depth + 1))
    }
  }

  mailboxTree.value.forEach((node) => append(node, 0))
  return rows
})

const filteredMessages = computed(() => {
  const needle = search.value.trim().toLowerCase()
  if (!needle) return messages.value

  return messages.value.filter((message) => [
    message.subject,
    message.preview,
    formatAddressList(message.from),
    formatAddressList(message.to),
  ].some((value) => String(value || "").toLowerCase().includes(needle)))
})

const moveMailboxOptions = computed(() =>
    mailboxes.value
        .filter((mailbox) => mailbox.path !== selectedMessage.value?.mailboxPath)
        .map((mailbox) => ({
          label: mailboxLabel(mailbox),
          value: mailbox.path,
        }))
)

const mailboxIcon = (mailbox: EmailMailbox) => {
  if (mailbox.specialUse === "\\Inbox" || mailbox.path.toUpperCase() === "INBOX") return "i-heroicons-inbox"
  if (mailbox.specialUse === "\\Sent") return "i-heroicons-paper-airplane"
  if (mailbox.specialUse === "\\Drafts") return "i-heroicons-document"
  if (mailbox.specialUse === "\\Archive") return "i-heroicons-archive-box"
  if (mailbox.specialUse === "\\Junk") return "i-heroicons-no-symbol"
  if (mailbox.specialUse === "\\Trash") return "i-heroicons-trash"
  return "i-heroicons-folder"
}

const mailboxLabel = (mailbox: EmailMailbox) => {
  if (mailbox.specialUse === "\\Inbox" || mailbox.path.toUpperCase() === "INBOX") return "Posteingang"
  if (mailbox.specialUse === "\\Sent") return "Gesendet"
  if (mailbox.specialUse === "\\Drafts") return "Entwürfe"
  if (mailbox.specialUse === "\\Archive") return "Archiv"
  if (mailbox.specialUse === "\\Junk") return "Spam"
  if (mailbox.specialUse === "\\Trash") return "Papierkorb"
  return mailbox.name || mailbox.path
}

const isMailboxExpanded = (mailbox: EmailMailbox) => expandedMailboxPaths.value.includes(mailbox.path)

const expandMailboxPath = (path: string) => {
  if (!expandedMailboxPaths.value.includes(path)) {
    expandedMailboxPaths.value = [...expandedMailboxPaths.value, path]
  }
}

const collapseMailboxPath = (path: string) => {
  expandedMailboxPaths.value = expandedMailboxPaths.value.filter((item) => item !== path)
}

const toggleMailboxExpanded = (mailbox: EmailMailbox) => {
  if (isMailboxExpanded(mailbox)) {
    collapseMailboxPath(mailbox.path)
  } else {
    expandMailboxPath(mailbox.path)
  }
}

const expandMailboxAncestors = (path: string) => {
  const mailbox = mailboxes.value.find((item) => item.path === path)
  if (!mailbox) return

  const delimiter = mailboxDelimiter(mailbox)
  const parts = path.split(delimiter)

  while (parts.length > 1) {
    parts.pop()
    expandMailboxPath(parts.join(delimiter))
  }
}

const resetExpandedMailboxes = () => {
  const roots = mailboxTree.value.map((node) => node.mailbox.path)
  expandedMailboxPaths.value = Array.from(new Set([
    ...roots,
    ...expandedMailboxPaths.value.filter((path) => mailboxes.value.some((mailbox) => mailbox.path === path)),
  ]))
}

const formatAddress = (address?: EmailAddress | null) => {
  if (!address) return "Unbekannt"
  return address.name || address.address || "Unbekannt"
}

const formatAddressList = (addresses?: EmailAddress[] | null) => {
  return (addresses || []).map(formatAddress).filter(Boolean).join(", ")
}

const formatMessageDate = (value?: string | null) => {
  if (!value) return ""
  const date = new Date(value)
  if (isToday(date)) return format(date, "HH:mm")
  if (isYesterday(date)) return "Gestern"
  return format(date, "dd. MMM", { locale: deLocale })
}

const formatDetailDate = (value?: string | null) => {
  if (!value) return ""
  return format(new Date(value), "dd. MMMM yyyy, HH:mm", { locale: deLocale })
}

const formatAttachmentSize = (size?: number | null) => {
  if (!size) return ""
  if (size < 1024 * 1024) return `${Math.round(size / 1024)} KB`
  return `${(size / 1024 / 1024).toFixed(1)} MB`
}

const iframeContent = computed(() => {
  const html = selectedMessage.value?.body?.html
  if (html) {
    return `<!doctype html><html><head><base target="_blank"><style>body{font-family:Arial,sans-serif;font-size:14px;line-height:1.5;color:#111827;margin:0;padding:0}img{max-width:100%;height:auto}table{max-width:100%}</style></head><body>${html}</body></html>`
  }

  const text = selectedMessage.value?.body?.text || selectedMessage.value?.preview || ""
  return `<!doctype html><html><head><style>body{font-family:Arial,sans-serif;font-size:14px;line-height:1.5;color:#111827;margin:0;padding:0;white-space:pre-wrap}</style></head><body>${escapeHtml(text)}</body></html>`
})

function escapeHtml(value: string) {
  return value
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;")
      .replace(/'/g, "&#039;")
}

async function loadAccounts() {
  loadingAccounts.value = true
  try {
    accounts.value = await $api("/api/email/accounts")
    selectedAccountId.value = accounts.value[0]?.id || ""
    if (selectedAccountId.value) {
      await loadMailboxes()
    }
  } finally {
    loadingAccounts.value = false
  }
}

async function loadMailboxes() {
  if (!selectedAccountId.value) return

  const previousMailboxPath = selectedMailboxPath.value
  loadingMailboxes.value = true
  selectedMessage.value = null

  try {
    mailboxes.value = await $api(`/api/email/accounts/${selectedAccountId.value}/mailboxes`)
    resetExpandedMailboxes()
    const inbox = mailboxes.value.find((mailbox) => mailbox.specialUse === "\\Inbox" || mailbox.path.toUpperCase() === "INBOX")
    const previousMailbox = mailboxes.value.find((mailbox) => mailbox.path === previousMailboxPath)
    selectedMailboxPath.value = previousMailbox?.path || inbox?.path || mailboxes.value[0]?.path || "INBOX"
    expandMailboxAncestors(selectedMailboxPath.value)
    await loadMessages()
  } finally {
    loadingMailboxes.value = false
  }
}

async function loadMessages(options: { syncIfEmpty?: boolean } = {}) {
  if (!selectedAccountId.value || !selectedMailboxPath.value) return

  loadingMessages.value = true
  selectedMessage.value = null

  try {
    messages.value = await fetchMessages(selectedMailboxPath.value)

    if (!messages.value.length && options.syncIfEmpty && !syncedMailboxPaths.value.includes(selectedMailboxPath.value)) {
      await syncSelectedMailbox({ silent: true, reloadMailboxes: false })
      syncedMailboxPaths.value = [...syncedMailboxPaths.value, selectedMailboxPath.value]
      messages.value = await fetchMessages(selectedMailboxPath.value)
    }

    if (messages.value.length) {
      await selectMessage(messages.value[0])
    }
  } finally {
    loadingMessages.value = false
  }
}

async function fetchMessages(mailboxPath: string) {
  return await $api(`/api/email/accounts/${selectedAccountId.value}/messages`, {
    query: {
      mailbox: mailboxPath,
      limit: 100,
    },
  })
}

async function selectMailbox(mailbox: EmailMailbox) {
  selectedMailboxPath.value = mailbox.path
  expandMailboxAncestors(mailbox.path)
  await loadMessages({ syncIfEmpty: true })
}

async function selectMessage(message: EmailMessage) {
  loadingMessage.value = true
  try {
    selectedMessage.value = await $api(`/api/email/messages/${message.id}`)
    moveTargetMailboxPath.value = ""
    if (!message.seen) {
      await setMessageSeen(message.id, true)
    }
  } finally {
    loadingMessage.value = false
  }
}

function removeMessageFromCurrentList(messageId: string) {
  const currentIndex = messages.value.findIndex((message) => message.id === messageId)
  messages.value = messages.value.filter((message) => message.id !== messageId)

  const nextMessage = messages.value[currentIndex] || messages.value[currentIndex - 1] || null
  selectedMessage.value = null

  if (nextMessage) {
    selectMessage(nextMessage)
  }
}

async function archiveSelectedMessage() {
  if (!selectedMessage.value) return

  const messageId = selectedMessage.value.id
  actionLoading.value = "archive"

  try {
    await $api(`/api/email/messages/${messageId}/archive`, { method: "POST" })
    removeMessageFromCurrentList(messageId)
    toast.add({ title: "E-Mail archiviert", color: "success" })
  } catch (err: any) {
    toast.add({
      title: "Archivieren fehlgeschlagen",
      description: err?.data?.error || err?.message || "Die E-Mail konnte nicht archiviert werden.",
      color: "error",
    })
  } finally {
    actionLoading.value = ""
  }
}

async function deleteSelectedMessage() {
  if (!selectedMessage.value) return

  const messageId = selectedMessage.value.id
  actionLoading.value = "delete"

  try {
    await $api(`/api/email/messages/${messageId}`, { method: "DELETE" })
    removeMessageFromCurrentList(messageId)
    toast.add({ title: "E-Mail gelöscht", color: "success" })
  } catch (err: any) {
    toast.add({
      title: "Löschen fehlgeschlagen",
      description: err?.data?.error || err?.message || "Die E-Mail konnte nicht gelöscht werden.",
      color: "error",
    })
  } finally {
    actionLoading.value = ""
  }
}

async function moveSelectedMessage() {
  if (!selectedMessage.value || !moveTargetMailboxPath.value) return

  const messageId = selectedMessage.value.id
  actionLoading.value = "move"

  try {
    await $api(`/api/email/messages/${messageId}/move`, {
      method: "POST",
      body: { mailbox: moveTargetMailboxPath.value },
    })
    removeMessageFromCurrentList(messageId)
    toast.add({ title: "E-Mail verschoben", color: "success" })
    moveTargetMailboxPath.value = ""
  } catch (err: any) {
    toast.add({
      title: "Verschieben fehlgeschlagen",
      description: err?.data?.error || err?.message || "Die E-Mail konnte nicht verschoben werden.",
      color: "error",
    })
  } finally {
    actionLoading.value = ""
  }
}

async function downloadAttachment(attachment: NonNullable<EmailMessage["attachments"]>[number]) {
  actionLoading.value = `attachment-${attachment.id}`
  try {
    const response = await $fetch.raw(`/api/email/attachments/${attachment.id}/download`, {
      responseType: "blob",
      credentials: "include",
      headers: {
        ...(useCookie("token").value ? { Authorization: `Bearer ${useCookie("token").value}` } : {}),
      },
    })
    const blob = response._data as Blob
    const disposition = response.headers.get("content-disposition") || ""
    const dispositionFilename = disposition.match(/filename="([^"]+)"/)?.[1]
    const filename = dispositionFilename || attachment.filename || "anhang"
    const url = URL.createObjectURL(blob)
    const link = document.createElement("a")

    link.href = url
    link.download = filename
    document.body.appendChild(link)
    link.click()
    link.remove()
    URL.revokeObjectURL(url)
  } catch (err: any) {
    toast.add({
      title: "Download fehlgeschlagen",
      description: err?.data?.error || err?.message || "Der Anhang konnte nicht geladen werden.",
      color: "error",
    })
  } finally {
    actionLoading.value = ""
  }
}

async function setMessageSeen(messageId: string, seen: boolean) {
  const previousMessage = messages.value.find((message) => message.id === messageId)

  const res = await $api(`/api/email/messages/${messageId}/read`, {
    method: "POST",
    body: { seen },
  })

  messages.value = messages.value.map((message) =>
      message.id === messageId ? { ...message, seen } : message
  )

  if (selectedMessage.value?.id === messageId) {
    selectedMessage.value = {
      ...selectedMessage.value,
      ...(res.message || {}),
      seen,
    }
  }

  if (previousMessage && previousMessage.seen !== seen) {
    mailboxes.value = mailboxes.value.map((mailbox) => {
      if (mailbox.path !== previousMessage.mailboxPath) return mailbox
      const delta = seen ? -1 : 1
      return {
        ...mailbox,
        unseen: Math.max(0, Number(mailbox.unseen || 0) + delta),
      }
    })
  }
}

async function syncAccount() {
  if (!selectedAccountId.value) return

  await syncSelectedMailbox({ silent: false, reloadMailboxes: true })
}

async function syncSelectedMailbox(options: { silent: boolean; reloadMailboxes: boolean }) {
  syncing.value = true
  try {
    const res = await $api(`/api/email/accounts/${selectedAccountId.value}/sync`, {
      method: "POST",
      body: {
        mailbox: selectedMailboxPath.value,
        limit: 100,
      },
    })

    if (!options.silent) {
      toast.add({
        title: "E-Mails synchronisiert",
        description: `${res.synced?.[0]?.fetched || 0} neue Nachrichten geladen`,
        color: "success",
      })
    }

    if (options.reloadMailboxes) {
      await loadMailboxes()
    }
  } catch (err: any) {
    if (!options.silent) {
      toast.add({
        title: "Synchronisation fehlgeschlagen",
        description: err?.data?.error || err?.message || "Das Postfach konnte nicht synchronisiert werden.",
        color: "error",
      })
    }
  } finally {
    syncing.value = false
  }
}

watch(selectedAccountId, async (next, previous) => {
  if (next && previous && next !== previous) {
    await loadMailboxes()
  }
})

onMounted(loadAccounts)
</script>

<template>
  <UPage>
    <UDashboardNavbar>
      <template #title>
        <div class="flex items-center gap-2">
          <UIcon name="i-heroicons-envelope" class="size-5 text-primary" />
          <span class="text-lg font-semibold">E-Mail</span>
        </div>
      </template>

      <template #right>
        <UButton
            icon="i-heroicons-pencil-square"
            size="sm"
            @click="navigateTo('/email/new')"
        >
          Neue E-Mail
        </UButton>
      </template>
    </UDashboardNavbar>

    <UDashboardToolbar>
      <template #left>
        <UInput
            v-model="search"
            icon="i-heroicons-magnifying-glass"
            size="sm"
            class="w-72"
            placeholder="E-Mails durchsuchen"
        />
      </template>

      <template #right>
        <UButton
            icon="i-heroicons-cog-6-tooth"
            color="neutral"
            variant="ghost"
            size="sm"
            @click="navigateTo('/settings/emailaccounts')"
        />
        <UButton
            icon="i-heroicons-arrow-path"
            color="neutral"
            variant="soft"
            size="sm"
            :loading="syncing"
            :disabled="!selectedAccountId"
            @click="syncAccount"
        >
          Aktualisieren
        </UButton>
      </template>
    </UDashboardToolbar>

    <div class="flex h-[calc(100vh-150px)] overflow-hidden">
      <aside class="w-72 shrink-0 border-r border-(--ui-border) bg-(--ui-bg) overflow-y-auto">
        <div class="border-b border-(--ui-border) p-3">
          <USkeleton v-if="loadingAccounts" class="h-9" />
          <USelectMenu
              v-else-if="accounts.length"
              v-model="selectedAccountId"
              :items="accounts"
              label-key="email"
              value-key="id"
              class="w-full"
          />
          <UButton
              v-else
              icon="i-heroicons-plus"
              block
              @click="navigateTo('/settings/emailaccounts/create')"
          >
            E-Mail Konto
          </UButton>
        </div>

        <div v-if="loadingMailboxes" class="space-y-2 p-3">
          <USkeleton v-for="i in 6" :key="i" class="h-9" />
        </div>

        <div v-else-if="!accounts.length" class="p-4 text-sm text-dimmed">
          Lege zuerst ein E-Mail Konto an.
        </div>

        <nav v-else class="p-2">
          <button
              v-for="row in mailboxRows"
              :key="row.mailbox.id"
              class="flex w-full items-center gap-2 rounded-md px-3 py-2 text-left text-sm transition-colors"
              :class="selectedMailboxPath === row.mailbox.path ? 'bg-primary/10 text-primary' : 'hover:bg-(--ui-bg-muted)'"
              :style="{ paddingLeft: `${12 + row.depth * 18}px` }"
              @click="selectMailbox(row.mailbox)"
          >
            <UIcon
                v-if="row.hasChildren"
                :name="isMailboxExpanded(row.mailbox) ? 'i-heroicons-chevron-down' : 'i-heroicons-chevron-right'"
                class="size-3 shrink-0 text-dimmed"
                @click.stop="toggleMailboxExpanded(row.mailbox)"
            />
            <span
                v-else
                class="size-3 shrink-0"
            />
            <UIcon :name="mailboxIcon(row.mailbox)" class="size-4 shrink-0" />
            <span class="min-w-0 flex-1 truncate">{{ mailboxLabel(row.mailbox) }}</span>
            <UBadge
                v-if="row.mailbox.unseen"
                size="xs"
                color="primary"
                variant="soft"
            >
              {{ row.mailbox.unseen }}
            </UBadge>
          </button>
        </nav>
      </aside>

      <section class="w-[390px] shrink-0 border-r border-(--ui-border) bg-(--ui-bg) overflow-y-auto">
        <div class="flex h-12 items-center justify-between border-b border-(--ui-border) px-4">
          <div class="min-w-0">
            <p class="truncate text-sm font-medium">
              {{ selectedMailbox ? mailboxLabel(selectedMailbox) : 'Postfach' }}
            </p>
            <p class="text-xs text-dimmed">
              {{ filteredMessages.length }} Nachrichten
            </p>
          </div>
        </div>

        <div v-if="loadingMessages" class="space-y-2 p-3">
          <USkeleton v-for="i in 8" :key="i" class="h-20" />
        </div>

        <TableEmptyState
            v-else-if="!filteredMessages.length"
            label="Keine E-Mails anzuzeigen"
        />

        <div v-else class="divide-y divide-(--ui-border)">
          <button
              v-for="message in filteredMessages"
              :key="message.id"
              class="block w-full border-l-2 px-4 py-3 text-left transition-colors"
              :class="selectedMessage?.id === message.id ? 'border-primary bg-primary/10' : 'border-transparent hover:bg-(--ui-bg-muted)'"
              @click="selectMessage(message)"
          >
            <div class="flex items-start justify-between gap-3">
              <p class="min-w-0 truncate text-sm" :class="message.seen ? 'font-medium' : 'font-semibold'">
                {{ formatAddress(message.from?.[0]) }}
              </p>
              <span class="shrink-0 text-xs text-dimmed">
                {{ formatMessageDate(message.receivedAt || message.sentAt) }}
              </span>
            </div>
            <p class="mt-1 truncate text-sm" :class="message.seen ? 'text-highlighted' : 'font-semibold text-highlighted'">
              {{ message.subject || '(kein Betreff)' }}
            </p>
            <div class="mt-1 flex items-center gap-2 text-xs text-dimmed">
              <UIcon
                  v-if="message.hasAttachments"
                  name="i-heroicons-paper-clip"
                  class="size-3.5"
              />
              <p class="min-w-0 flex-1 truncate">
                {{ message.preview || 'Keine Vorschau' }}
              </p>
            </div>
          </button>
        </div>
      </section>

      <main class="min-w-0 flex-1 overflow-y-auto bg-(--ui-bg)">
        <div v-if="loadingMessage" class="space-y-4 p-6">
          <USkeleton class="h-8 w-2/3" />
          <USkeleton class="h-5 w-1/3" />
          <USkeleton class="h-80" />
        </div>

        <div v-else-if="selectedMessage" class="flex min-h-full flex-col">
          <div class="border-b border-(--ui-border) px-6 py-4">
            <div class="flex items-start justify-between gap-4">
              <div class="min-w-0">
                <h1 class="truncate text-xl font-semibold text-highlighted">
                  {{ selectedMessage.subject || '(kein Betreff)' }}
                </h1>
                <p class="mt-1 text-sm text-dimmed">
                  {{ formatDetailDate(selectedMessage.receivedAt || selectedMessage.sentAt) }}
                </p>
              </div>
              <div class="flex shrink-0 items-center gap-2">
                <USelectMenu
                    v-model="moveTargetMailboxPath"
                    :items="moveMailboxOptions"
                    value-key="value"
                    label-key="label"
                    size="sm"
                    class="w-48"
                    placeholder="Verschieben nach"
                />
                <UButton
                    icon="i-heroicons-folder-arrow-down"
                    color="neutral"
                    variant="soft"
                    size="sm"
                    :loading="actionLoading === 'move'"
                    :disabled="!moveTargetMailboxPath"
                    @click="moveSelectedMessage"
                />
                <UButton
                    icon="i-heroicons-archive-box-arrow-down"
                    color="neutral"
                    variant="ghost"
                    size="sm"
                    :loading="actionLoading === 'archive'"
                    @click="archiveSelectedMessage"
                />
                <UButton
                    icon="i-heroicons-trash"
                    color="error"
                    variant="ghost"
                    size="sm"
                    :loading="actionLoading === 'delete'"
                    @click="deleteSelectedMessage"
                />
                <UButton
                    :icon="selectedMessage.seen ? 'i-heroicons-envelope' : 'i-heroicons-envelope-open'"
                    color="neutral"
                    variant="ghost"
                    size="sm"
                    @click="setMessageSeen(selectedMessage.id, !selectedMessage.seen)"
                >
                  {{ selectedMessage.seen ? 'Ungelesen' : 'Gelesen' }}
                </UButton>
                <UButton
                    icon="i-heroicons-arrow-uturn-left"
                    color="neutral"
                    variant="soft"
                    size="sm"
                    @click="navigateTo(`/email/new?to=${encodeURIComponent(formatAddressList(selectedMessage.from))}&subject=${encodeURIComponent(`Re: ${selectedMessage.subject || ''}`)}`)"
                >
                  Antworten
                </UButton>
                <UButton
                    icon="i-heroicons-arrow-uturn-right"
                    color="neutral"
                    variant="ghost"
                    size="sm"
                    @click="navigateTo(`/email/new?subject=${encodeURIComponent(`Fw: ${selectedMessage.subject || ''}`)}`)"
                >
                  Weiterleiten
                </UButton>
              </div>
            </div>

            <div class="mt-4 grid gap-1 text-sm">
              <p>
                <span class="text-dimmed">Von:</span>
                <span class="ml-2">{{ formatAddressList(selectedMessage.from) || 'Unbekannt' }}</span>
              </p>
              <p>
                <span class="text-dimmed">An:</span>
                <span class="ml-2">{{ formatAddressList(selectedMessage.to) || selectedAccount?.email }}</span>
              </p>
              <p v-if="selectedMessage.cc?.length">
                <span class="text-dimmed">Kopie:</span>
                <span class="ml-2">{{ formatAddressList(selectedMessage.cc) }}</span>
              </p>
            </div>

            <div v-if="selectedMessage.attachments?.length" class="mt-4 flex flex-wrap gap-2">
              <button
                  v-for="attachment in selectedMessage.attachments"
                  :key="attachment.id"
                  class="flex items-center gap-2 rounded-md border border-(--ui-border) px-3 py-2 text-left text-sm hover:bg-(--ui-bg-muted)"
                  @click="downloadAttachment(attachment)"
              >
                <UIcon name="i-heroicons-paper-clip" class="size-4 text-dimmed" />
                <span>{{ attachment.filename || 'Anhang' }}</span>
                <span class="text-xs text-dimmed">{{ formatAttachmentSize(attachment.size) }}</span>
                <UIcon
                    :name="actionLoading === `attachment-${attachment.id}` ? 'i-heroicons-arrow-path' : 'i-heroicons-arrow-down-tray'"
                    class="size-4 text-dimmed"
                    :class="actionLoading === `attachment-${attachment.id}` ? 'animate-spin' : ''"
                />
              </button>
            </div>
          </div>

          <div class="flex-1 p-6">
            <iframe
                title="E-Mail Inhalt"
                class="h-[calc(100vh-360px)] min-h-[420px] w-full"
                sandbox="allow-popups allow-popups-to-escape-sandbox"
                :srcdoc="iframeContent"
            />
          </div>
        </div>

        <div v-else class="flex h-full items-center justify-center p-6 text-center">
          <div>
            <UIcon name="i-heroicons-envelope-open" class="mx-auto mb-3 size-10 text-dimmed" />
            <p class="font-medium">Keine E-Mail ausgewählt</p>
            <p class="mt-1 text-sm text-dimmed">Wähle links eine Nachricht aus oder synchronisiere dein Postfach.</p>
          </div>
        </div>
      </main>
    </div>
  </UPage>
</template>
