<script setup lang="ts">
import { computed } from 'vue'
import RecipientDetails from '@/components/common/RecipientDetails.vue'
import { formatFileSize } from '@/utile/format'
import { mediaViewerCanDisplay, mediaViewerComponent } from '@/services/mediaViewer'
import { useMailUiStore } from '@/stores/mailUiStore'
import type { EntityObject } from '@MailManager/models';
import type { MessagePartInterface } from '@MailManager/types/message';

interface AttachmentItem {
  id: string
  title: string
  mime: string
  size?: number | null
  meta: { index: number; attachment: MessagePartInterface }
}

interface Props {
  entity: EntityObject | null
}

const props = defineProps<Props>()

const emit = defineEmits<{
  download: [index: number]
  preview: [index: number]
}>()

const mailUiStore = useMailUiStore()
const previewPopover = computed(() => mediaViewerComponent('popover'))

const message = computed(() => {
  return props.entity?.properties ?? null
})

const randomKey = computed(() => {
  return Math.random().toString(36).substring(2, 15)
})

const attachmentItems = computed<AttachmentItem[]>(() =>
  (message.value?.attachments ?? []).map((attachment, index) => ({
    id: attachment.partId || attachment.blobId || attachment.cid || `att-${index}`,
    title: attachment.name || 'Attachment',
    mime: attachment.type || '',
    size: attachment.size ?? null,
    meta: { index, attachment },
  })),
)

const isPreviewable = (attachment: MessagePartInterface): boolean => {
  return mediaViewerCanDisplay(attachment.type)
}

const handleAttachmentClick = (attachment: MessagePartInterface, index: number): void => {
  if (isPreviewable(attachment)) {
    emit('preview', index)
  } else {
    emit('download', index)
  }
}

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

// Format date for display
const formatDate = (date: Date | string | null | undefined): string => {
  if (!date) return ''
  
  const messageDate = new Date(date)
  return messageDate.toLocaleString('en-US', {
    weekday: 'short',
    year: 'numeric',
    month: 'short',
    day: 'numeric',
    hour: 'numeric',
    minute: '2-digit',
    hour12: true
  })
}
</script>

<template>
  <div class="message-header pa-6">
    <div class="text-h5 mb-4">{{ message?.subject || '(No subject)' }}</div>
    
    <div class="d-flex align-center mb-3">
      <v-avatar size="48" color="primary" class="mr-3">
        <span class="text-white text-h6">
          {{ (message?.from?.label || message?.from?.address || 'U')[0].toUpperCase() }}
        </span>
      </v-avatar>
      
      <div class="flex-grow-1">
        <div class="text-body-1 font-weight-medium">
          <RecipientDetails :address="message?.from">
            <template #default="{ label }">
              <span class="contact-link">{{ label }}</span>
            </template>
          </RecipientDetails>
        </div>
        <div class="text-caption text-medium-emphasis">
          {{ formatDate(message?.received || message?.sent) }}
        </div>
      </div>
    </div>

    <!-- Recipients -->
    <div v-if="message?.to && message?.to.length > 0" class="text-body-2 mb-1">
      <span class="text-medium-emphasis">To:</span>
      <template v-for="(recipient, index) in message.to" :key="randomKey">
        <RecipientDetails :address="recipient">
          <template #default="{ label }">
            <span class="contact-link">{{ label }}</span>
          </template>
        </RecipientDetails>
        <span v-if="index < message.to.length - 1">, </span>
      </template>
    </div>

    <div v-if="message?.cc && message?.cc.length > 0" class="text-body-2 mb-1">
      <span class="text-medium-emphasis">Cc:</span>
      <template v-for="(recipient, index) in message.cc" :key="randomKey">
        <RecipientDetails :address="recipient">
          <template #default="{ label }">
            <span class="contact-link">{{ label }}</span>
          </template>
        </RecipientDetails>
        <span v-if="index < message.cc.length - 1">, </span>
      </template>
    </div>

    <!-- Attachments -->
    <div v-if="message?.attachments && message?.attachments.length > 0" class="mt-4">
      <div class="text-body-2 text-medium-emphasis mb-2">
        Attachments ({{ message?.attachments.length }})
      </div>
      <div class="d-flex flex-wrap gap-2">
        <div
          v-for="(attachment, index) in message?.attachments"
          :key="attachment.partId || attachment.blobId || attachment.cid || index"
          class="attachment-item"
        >
          <v-chip
            :prepend-icon="isPreviewable(attachment) ? 'mdi-eye-outline' : 'mdi-paperclip'"
            size="small"
            variant="outlined"
            class="attachment-chip"
            :title="isPreviewable(attachment) ? 'Preview' : 'Download'"
            @click="handleAttachmentClick(attachment, index)"
          >
            <span class="attachment-name">{{ attachment.name || 'Untitled' }}</span>
            <span v-if="attachment.size != null" class="text-caption text-medium-emphasis ml-1">
              ({{ formatFileSize(attachment.size) }})
            </span>
          </v-chip>

          <!-- Hover preview (provided by the media_viewer module) -->
          <component
            :is="previewPopover"
            v-if="previewPopover && isPreviewable(attachment)"
            :item="attachmentItems[index]"
            :source="handleViewerRetrieve"
            @expand="emit('preview', index)"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.message-header {
  background-color: rgba(var(--v-theme-surface));
}

.gap-2 {
  gap: 0.5rem;
}

.attachment-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.attachment-chip {
  max-width: 300px;
  cursor: pointer;
  
  .attachment-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

.attachment-error {
  color: rgb(var(--v-theme-error));
  margin-top: 0.25rem;
}

.contact-link {
  display: inline-block;
  border-radius: 4px;
  padding: 1px 4px;
  margin: -1px -4px;
  transition: background-color 0.2s ease;
}

.contact-link:hover {
  background-color: rgba(var(--v-theme-primary), 0.08);
}
</style>
