<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { useUser } from '@KTXC'
import { useMailUiStore } from '@/stores/mailUiStore'
import type { EntityObject, MessageObject } from '@MailManager/models'
import { SecurityLevel } from '@/utile/emailSanitizer'
import { mediaViewerCanDisplay, mediaViewerComponent } from '@/services/mediaViewer'
import type { MediaViewerItem } from '@/types/mediaViewer'
import ReaderEmpty from './reader/ReaderEmpty.vue'
import ReaderToolbar from './reader/ReaderToolbar.vue'
import ReaderHeader from './reader/ReaderHeader.vue'
import ReaderBody from './reader/ReaderBody.vue'

// Props
const props = defineProps<{
  entity: EntityObject | null
}>()

// Emits
const emit = defineEmits<{
  reply: [entity: EntityObject]
  forward: [entity: EntityObject]
  move: [entity: EntityObject]
  delete: [entity: EntityObject]
  flag: [entity: EntityObject]
  compose: []
}>()

// User settings
const { getSetting } = useUser()
const mailUiStore = useMailUiStore()

// Security overrides
const allowImages = ref(false)
const overrideSecurityLevel = ref<SecurityLevel | null>(null)

// Viewer state
const showViewer = ref(false)
const viewerIndex = ref(0)

// Computed
const message = computed<MessageObject | null>(() => {
  return props.entity?.properties ?? null
})

const isHtml = computed(() => {
  return message.value?.hasHtmlContent() ?? false
})

// Security preferences from user settings
const securityLevel = computed(() => {
  return (getSetting('mail.security.level') as SecurityLevel) || SecurityLevel.MODERATE
})

const allowImagesDefault = computed(() => {
  return getSetting('mail.security.allowImagesDefault') as boolean || false
})

// Computed effective security level (use override if set, otherwise default)
const effectiveSecurityLevel = computed(() => {
  return overrideSecurityLevel.value ?? securityLevel.value
})

// Preview state
const previewDialog = computed(() => mediaViewerComponent('dialog'))
const previewItems = computed<MediaViewerItem[]>(() => {
  const attachments = message.value?.attachments ?? []
  const items: MediaViewerItem[] = []
  attachments.forEach((attachment, index) => {
    if (!mediaViewerCanDisplay(attachment.type)) return
    items.push({
      id: attachment.partId || attachment.blobId || attachment.cid || `att-${index}`,
      title: attachment.name || 'Attachment',
      mime: attachment.type || '',
      size: attachment.size ?? null,
      meta: { index, attachment },
    })
  })
  return items
})

// Reset overrides when message changes
watch(() => props.entity, () => {
  allowImages.value = allowImagesDefault.value
  overrideSecurityLevel.value = null
})

// Close the viewer when switching messages.
watch(() => props.entity, () => {
  showViewer.value = false
})

// Toggle images for current message only
const toggleImages = () => {
  allowImages.value = !allowImages.value
}

// Set security level override for current message only
const setSecurityLevel = (level: SecurityLevel) => {
  overrideSecurityLevel.value = level
}

// Handlers
const handleReply = () => {
  if (props.entity) {
    emit('reply', props.entity)
  }
}

const handleForward = () => {
  if (props.entity) {
    emit('forward', props.entity)
  }
}

const handleDelete = () => {
  if (props.entity) {
    emit('delete', props.entity)
  }
}

const handleMove = () => {
  if (props.entity) {
    emit('move', props.entity)
  }
}

const handleDownload = async (partIndex?: number) => {
  if (!props.entity) {
    return
  }

  await mailUiStore.downloadMessage(props.entity, partIndex)
}

const handleFlag = () => {
  if (props.entity) {
    emit('flag', props.entity)
  }
}

const handleCompose = () => {
  emit('compose')
}

const handlePreview = (index: number) => {
  const pos = previewItems.value.findIndex(item => item.meta.index === index)
  if (pos < 0) return
  viewerIndex.value = pos
  showViewer.value = true
}

const handleViewerRetrieve = (item: MediaViewerItem): Promise<Blob> => {
  if (!props.entity) return Promise.reject(new Error('No message selected'))
  return mailUiStore.attachmentBlob(props.entity, item.meta.attachment)
}

const handleViewerDownload = (item: MediaViewerItem) => {
  if (props.entity) mailUiStore.downloadMessage(props.entity, item.meta.index)
}
</script>

<template>
  <div class="message-reader">
    <!-- Empty state -->
    <ReaderEmpty 
      v-if="!message" 
      @compose="handleCompose"
    />

    <!-- Message viewer -->
    <template v-else>
      <ReaderToolbar
        :is-html="isHtml"
        :allow-images="allowImages"
        :security-level="effectiveSecurityLevel"
        :is-security-overridden="overrideSecurityLevel !== null"
        @reply="handleReply"
        @forward="handleForward"
        @move="handleMove"
        @delete="handleDelete"
        @flag="handleFlag"
        @download="handleDownload"
        @toggle-images="toggleImages"
        @set-security-level="setSecurityLevel"
      />

      <!-- Message content -->
      <div class="message-content">
        <ReaderHeader
          :entity="props.entity"
          @download="handleDownload"
          @preview="handlePreview"
        />
        
        <v-divider />
        
        <ReaderBody
          :message="message!"
          :security-level="effectiveSecurityLevel"
          :allow-images="allowImages"
        />
      </div>

      <!-- Inline attachment viewer (provided by the media_viewer module) -->
      <component
        :is="previewDialog"
        v-if="previewDialog"
        v-model="showViewer"
        :items="previewItems"
        :index="viewerIndex"
        :source="handleViewerRetrieve"
        :download="handleViewerDownload"
        :navigation="true"
        @update:index="viewerIndex = $event"
      />
    </template>
  </div>
</template>

<style scoped lang="scss">
.message-reader {
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.message-content {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
}
</style>
