<template>
  <n-space align="center">
    <!-- Previous / Next -->
    <n-button
      type="default"
      size="medium"
      @click="goToPrev"
      :disabled="loading || fetching || !hasPrev"
      :title="t('Previous')"
      class="header-action-btn"
    >
      <template #icon>
        <n-icon><Icon icon="tabler:chevron-left" /></n-icon>
      </template>
    </n-button>
    <n-button
      type="default"
      size="medium"
      @click="goToNext"
      :disabled="loading || fetching || !hasNext"
      :title="t('Next')"
      class="header-action-btn"
    >
      <template #icon>
        <n-icon><Icon icon="tabler:chevron-right" /></n-icon>
      </template>
    </n-button>

    <!-- Refresh -->
    <n-button
      type="default"
      size="medium"
      @click="$emit('refresh')"
      :disabled="loading || isNew"
      :title="t('Refresh')"
      class="header-action-btn"
    >
      <template #icon>
        <n-icon><Icon icon="tabler:refresh" /></n-icon>
      </template>
    </n-button>

    <!-- ===== Email-specific actions ===== -->

    <!-- Reference page link -->
    <n-button
      v-if="record?.reference_pagetype && record?.reference_name"
      type="default"
      size="medium"
      @click="goToReference"
      :title="record.reference_name"
      class="header-action-btn"
    >
      <template #icon>
        <n-icon><Icon icon="tabler:file-text" /></n-icon>
      </template>
      {{ record.reference_name }}
    </n-button>

    <!-- Move to Trash -->
    <n-button
      v-if="!isTrash && !isSpam && !isArchived"
      type="default"
      size="medium"
      @click="moveToTrash"
      :disabled="loading || isNew"
      :title="t('Move to Trash')"
      class="header-action-btn delete-btn"
    >
      <template #icon>
        <n-icon><Icon icon="tabler:trash" /></n-icon>
      </template>
    </n-button>

    <!-- Like -->
    <n-button
      type="default"
      size="medium"
      @click="handleToggleLike"
      :disabled="loading || isNew"
      :loading="likeLoading"
      :title="isLiked ? t('Unlike') : t('Like')"
      class="header-action-btn like-action-btn"
      :class="{ 'is-liked': isLiked }"
    >
      <template #icon>
        <n-icon><Icon :icon="isLiked ? 'tabler:heart-filled' : 'tabler:heart'" /></n-icon>
      </template>
    </n-button>

    <!-- Back -->
    <n-button type="default" size="medium" @click="$emit('go-back')" :disabled="loading">
      <template #icon>
        <n-icon><Icon icon="tabler:arrow-left" /></n-icon>
      </template>
      {{ t('Back') }}
    </n-button>

    <!-- Reply -->
    <n-button
      v-if="canReply"
      type="default"
      size="medium"
      @click="reply"
      :disabled="loading"
      class="reply-btn"
    >
      <template #icon>
        <n-icon><Icon icon="tabler:arrow-back-up" /></n-icon>
      </template>
      {{ t('Reply') }}
    </n-button>

    <!-- Forward -->
    <n-button
      v-if="canReply"
      type="default"
      size="medium"
      @click="forward"
      :disabled="loading"
      class="header-action-btn"
    >
      <template #icon>
        <n-icon><Icon icon="tabler:arrow-forward-up" /></n-icon>
      </template>
      {{ t('Forward') }}
    </n-button>

    <!-- More menu -->
    <n-dropdown
      :options="moreOptions"
      trigger="click"
      :render-icon="renderMenuIcon"
      @select="handleMoreSelect"
    >
      <n-button type="default" size="medium" :title="t('More')" class="header-action-btn">
        <template #icon>
          <n-icon><Icon icon="tabler:dots" /></n-icon>
        </template>
      </n-button>
    </n-dropdown>

    <!-- Email Compose Drawer -->
    <EmailComposeModal ref="composeRef" @sent="onEmailSent" />

    <!-- Relink Dialog -->
    <n-modal v-model:show="showRelinkDialog" preset="dialog" :title="t('Relink Email')" style="width: 480px;" :auto-focus="false">
      <n-form ref="relinkFormRef" :model="relinkForm" :rules="relinkRules" label-placement="top">
        <n-form-item :label="t('Reference Pagetype')" path="reference_pagetype" label-placement="top">
          <LinkField
            v-model="relinkForm.reference_pagetype"
            :options="'PageType'"
            :enable-create="false"
            :get-query="() => ({ filters: { istable: 0 } })"
          />
        </n-form-item>
        <n-form-item :label="t('Reference Name')" path="reference_name" label-placement="top">
          <LinkField
            v-model="relinkForm.reference_name"
            :options="relinkForm.reference_pagetype || ''"
            :enable-create="false"
            :disabled="!relinkForm.reference_pagetype"
          />
        </n-form-item>
      </n-form>
      <template #action>
        <n-button @click="showRelinkDialog = false">{{ t('Cancel') }}</n-button>
        <n-button type="primary" :loading="relinking" @click="confirmRelink">
          {{ t('Relink') }}
        </n-button>
      </template>
    </n-modal>

    <!-- Move Dialog -->
    <n-modal v-model:show="showMoveDialog" preset="dialog" :title="t('Move Email')" style="width: 400px;">
      <n-form-item :label="t('Email Account')" path="email_account">
        <n-select
          v-model:value="moveTargetAccount"
          :options="emailAccountOptions"
          filterable
          placeholder=""
          :loading="loadingAccounts"
        />
      </n-form-item>
      <template #action>
        <n-button @click="showMoveDialog = false">{{ t('Cancel') }}</n-button>
        <n-button type="primary" :loading="moving" @click="confirmMove">
          {{ t('Move') }}
        </n-button>
      </template>
    </n-modal>

    <!-- Assign Dialog -->
    <n-modal v-model:show="showAssignDialog" preset="dialog" :title="t('Assign To')" style="width: 400px;">
      <n-form-item :label="t('Email Account')" path="assign_account">
        <n-select
          v-model:value="assignTargetAccount"
          :options="assignAccountOptions"
          filterable
          placeholder=""
          :loading="loadingAssignAccounts"
        />
      </n-form-item>
      <template #action>
        <n-button @click="showAssignDialog = false">{{ t('Cancel') }}</n-button>
        <n-button type="primary" :loading="assigning" @click="confirmAssign">
          {{ t('Assign') }}
        </n-button>
      </template>
    </n-modal>
  </n-space>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch, h } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import {
  NButton, NSpace, NIcon, NDropdown, NModal, NForm, NFormItem, NSelect,
  useMessage, useDialog, type DropdownOption, type FormRules, type FormInst,
} from 'naive-ui'
import { Icon } from '@iconify/vue'
import { t } from '@/shared/i18n'
import { usePageTypeSlug, pageTypeToSlug } from '@/shared/utils/slug'
import { getRecords, renameRecord, duplicateRecord, api } from '@/shared/api/common'
import { toggleLike as toggleLikeApi } from '@/shared/api/timeline'
import { useAuthStore } from '@/shared/stores/auth'
import EmailComposeModal from '@/shared/components/EmailComposeModal.vue'
import LinkField from '@/shared/components/LinkField.vue'

interface Props {
  entity: string
  id: string
  record?: any
  canEdit: boolean
  loading: boolean
  isSubmittable?: boolean
  pageStatus?: number
  sidebarPosition?: 'left' | 'right'
  pageMeta?: any
  _inPanel?: boolean
}

interface Emits {
  (e: 'toggle-sidebar-position'): void
  (e: 'refresh'): void
  (e: 'delete'): void
  (e: 'go-back'): void
  (e: 'save'): void
  (e: 'submit'): void
  (e: 'cancel-pg'): void
  (e: 'rename', newName: string): void
  (e: 'duplicate', newName: string): void
  (e: 'prev', name: string): void
  (e: 'next', name: string): void
}

const props = withDefaults(defineProps<Props>(), {
  sidebarPosition: 'left',
  record: () => ({}),
  isSubmittable: false,
  pageStatus: -1,
  pageMeta: () => ({}),
})
const emit = defineEmits<Emits>()
const message = useMessage()
const dialog = useDialog()
const authStore = useAuthStore()

// ===== Email Compose =====
const composeRef = ref<InstanceType<typeof EmailComposeModal> | null>(null)

// ===== Email context flags =====
const isEmail = computed(() => true)
const isReceived = computed(() => props.record?.sent_or_received === 'Received')
const canReply = computed(() => isEmail.value && isReceived.value && !props.isNew)
const isOpen = computed(() => props.record?.status === 'Open')
const isLinked = computed(() => props.record?.status === 'Linked')
const isSpam = computed(() => props.record?.email_status === 'Spam')
const isTrash = computed(() => props.record?.email_status === 'Trash')
const isDraft = computed(() => props.record?.email_status === 'Draft')
const isArchived = computed(() => props.record?.email_status === 'Archived')
const isSeen = computed(() => props.record?.seen)

const sender = computed(() => props.record?.sender || '')
const senderFullName = computed(() => props.record?.sender_full_name || '')
const subject = computed(() => props.record?.subject || '')
const cc = computed(() => props.record?.cc || '')
const recipients = computed(() => props.record?.recipients || '')
const emailAccount = computed(() => props.record?.email_account || '')
const originalComment = computed(() => props.record?.content || '')
const attachments = computed(() => props.record?.attachments || [])

// ===== Like =====
const likeLoading = ref(false)
const currentUser = computed(() => authStore.user?.username || authStore.user?.name || '')
const likedBy = computed<string[]>(() => {
  const raw = props.record?._liked_by
  if (!raw) return []
  if (typeof raw === 'string') { try { return JSON.parse(raw) } catch { return [] } }
  return Array.isArray(raw) ? raw : []
})
const isLiked = computed(() => likedBy.value.includes(currentUser.value))

async function handleToggleLike() {
  if (props.isNew || likeLoading.value) return
  likeLoading.value = true
  try {
    await toggleLikeApi(props.entity, props.id, isLiked.value ? 'No' : 'Yes')
    emit('refresh')
  } catch (err: any) {
    message.error(err?.message || t('Failed to toggle like'))
  } finally {
    likeLoading.value = false
  }
}

// ===== Navigation =====
const route = useRoute()
const router = useRouter()
const { pagetypeSlug } = usePageTypeSlug(route)
const isNew = computed(() => props.id === 'new' || props.id.startsWith('new-'))

const listStateKey = computed(() => `list-state:${props.entity}`)
const rowNames = ref<string[]>([])
const fetching = ref(false)
const loadedStart = ref(0)
const hasMoreNext = ref(false)
const hasMorePrev = ref(false)
const pageSize = parseInt(localStorage.getItem('itemsPerPage') || '10')

const currentIndex = computed(() => {
  if (!props.id || rowNames.value.length === 0) return -1
  return rowNames.value.indexOf(props.id)
})
const hasPrev = computed(() => {
  if (isNew.value) return false
  return currentIndex.value > 0 || hasMorePrev.value
})
const hasNext = computed(() => {
  if (isNew.value || currentIndex.value < 0) return false
  return currentIndex.value < rowNames.value.length - 1 || hasMoreNext.value
})

function readListState(): any | null {
  const saved = sessionStorage.getItem(listStateKey.value)
  if (!saved) return null
  try { return JSON.parse(saved) } catch { return null }
}

function loadRowNames() {
  const state = readListState()
  if (!state?.rowNames?.length) return
  rowNames.value = state.rowNames
  loadedStart.value = ((state.page || 1) - 1) * pageSize
  hasMorePrev.value = loadedStart.value > 0
  hasMoreNext.value = state.rowNames.length >= pageSize
}

function navigateTo(name: string) {
  router.push({
    name: 'PageTypeDetail',
    params: { entity: pagetypeSlug.value, id: name },
    state: { _listPage: history.state?._listPage || 1 }
  })
}


async function fetchPage(direction: 'next' | 'prev'): Promise<string[]> {
  const state = readListState()
  if (!state) return []

  const orderBy = 'communication_date desc'
  // Read pre-built API filters from sessionStorage (stored by email_list.vue)
  const filters = state.apiFilters || []
  const ps = pageSize

  let limitStart: number, limitLength: number
  if (direction === 'next') {
    limitStart = loadedStart.value + rowNames.value.length
    limitLength = ps
  } else {
    limitLength = Math.min(ps, loadedStart.value)
    limitStart = loadedStart.value - limitLength
    if (limitLength <= 0) return []
  }

  const res = await getRecords(props.entity, filters, ['name'], orderBy, limitStart, limitLength)
  if (!res.success || !res.data?.length) {
    if (direction === 'next') hasMoreNext.value = false
    else hasMorePrev.value = false
    return []
  }

  const newNames = res.data.map((r: any) => r.name)
  if (direction === 'next') {
    rowNames.value = [...rowNames.value, ...newNames]
    hasMoreNext.value = newNames.length >= ps
  } else {
    rowNames.value = [...newNames, ...rowNames.value]
    loadedStart.value -= newNames.length
    hasMorePrev.value = loadedStart.value > 0
  }

  try {
    state.rowNames = rowNames.value
    sessionStorage.setItem(listStateKey.value, JSON.stringify(state))
  } catch {}

  return newNames
}

async function goToPrev() {
  if (fetching.value) return
  if (currentIndex.value > 0) {
    const targetName = rowNames.value[currentIndex.value - 1]
    emit('prev', targetName)
    if (!props._inPanel) navigateTo(targetName)
  } else if (hasMorePrev.value) {
    fetching.value = true
    try {
      const newNames = await fetchPage('prev')
      if (newNames.length) {
        const idx = rowNames.value.indexOf(props.id)
        if (idx > 0) {
          const target = rowNames.value[idx - 1]
          emit('prev', target)
          if (!props._inPanel) navigateTo(target)
        }
      }
    } finally { fetching.value = false }
  }
}

async function goToNext() {
  if (fetching.value) return
  if (currentIndex.value >= 0 && currentIndex.value < rowNames.value.length - 1) {
    const targetName = rowNames.value[currentIndex.value + 1]
    emit('next', targetName)
    if (!props._inPanel) navigateTo(targetName)
  } else if (hasMoreNext.value) {
    fetching.value = true
    try {
      const newNames = await fetchPage('next')
      if (newNames.length) {
        const idx = currentIndex.value + 1
        if (idx < rowNames.value.length) {
          const target = rowNames.value[idx]
          emit('next', target)
          if (!props._inPanel) navigateTo(target)
        }
      }
    } finally { fetching.value = false }
  }
}

// ===== Reference link =====
function goToReference() {
  if (!props.record?.reference_pagetype || !props.record?.reference_name) return
  router.push({
    name: 'PageTypeDetail',
    params: {
      entity: props.record.reference_pagetype.replace(/ /g, '-').toLowerCase(),
      id: props.record.reference_name,
    }
  })
}

// ===== Email actions =====
function getMailArgs() {
  return {
    pg: props.record,
    lastEmail: props.record,
    sender: getSenderEmailId(),
    attachments: attachments.value,
    referencePagetype: props.record?.reference_pagetype,
    referenceName: props.record?.reference_name,
  }
}

function getSenderEmailId(): string {
  const bootAccounts = (window as any).jingrow?.boot?.email_accounts || []
  for (const account of bootAccounts) {
    if (account.email_account === emailAccount.value) {
      return account.email_id || ''
    }
  }
  return ''
}

function reply() {
  composeRef.value?.open({
    ...getMailArgs(),
    isReply: true,
    replyAll: false,
    defaultSubject: subject.value.startsWith('Re:') ? subject.value : `Re: ${subject.value}`,
    defaultRecipients: sender.value,
    defaultContent: originalComment.value,
  })
}

function replyAll() {
  const selfEmail = getSenderEmailId()
  const allRecipients = splitEmailList(recipients.value)
  const allCc = splitEmailList(cc.value)
  const otherRecipients = [...allRecipients, ...allCc].filter(e => e !== selfEmail)
  composeRef.value?.open({
    ...getMailArgs(),
    isReply: true,
    replyAll: true,
    defaultSubject: subject.value.startsWith('Re:') ? subject.value : `Re: ${subject.value}`,
    defaultRecipients: sender.value,
    defaultCc: otherRecipients.join(', '),
    defaultContent: originalComment.value,
  })
}

function forward() {
  composeRef.value?.open({
    ...getMailArgs(),
    isForward: true,
    defaultSubject: subject.value.startsWith('Fw:') ? subject.value : `Fw: ${subject.value}`,
    defaultRecipients: '',
    defaultContent: originalComment.value,
  })
}

function splitEmailList(str: string): string[] {
  if (!str) return []
  return str.split(/[;,]/).map(s => s.trim()).filter(Boolean)
}

function onEmailSent() {
  emit('refresh')
}

// ===== Mark as Read/Unread =====
async function markAsReadUnread() {
  const action = isSeen.value ? 'Unread' : 'Read'
  try {
    await api.call('jingrow.email.inbox.create_email_flag_queue', {
      names: JSON.stringify([props.id]),
      action,
      flag: '\\SEEN',
    })
    message.success(t(action === 'Read' ? 'Marked as Read' : 'Marked as Unread'))
    emit('refresh')
  } catch (err: any) {
    message.error(err?.message || t('Failed to update'))
  }
}

// ===== Mark as Closed/Open =====
async function markAsClosedOpen() {
  const status = isOpen.value ? 'Closed' : 'Open'
  try {
    await api.call('jingrow.email.inbox.mark_as_closed_open', {
      email: props.id,
      status,
    })
    emit('refresh')
  } catch (err: any) {
    message.error(err?.message || t('Failed to update'))
  }
}

// ===== Mark as Spam =====
async function markAsSpam() {
  try {
    await api.call('jingrow.email.inbox.mark_as_spam', {
      email: props.id,
      sender: sender.value,
    })
    message.success(t('Marked as spam'))
    emit('refresh')
  } catch (err: any) {
    message.error(err?.message || t('Operation failed'))
  }
}

// ===== Edit Email (all statuses) =====
function editEmail() {
  const rec = props.record
  if (!rec) return
  composeRef.value?.open({
    pg: rec,
    lastEmail: rec,
    sender: getSenderEmailId(),
    attachments: attachments.value,
    referencePagetype: rec.reference_pagetype,
    referenceName: rec.reference_name,
    isEdit: true,
    defaultSubject: rec.subject || '',
    defaultRecipients: rec.recipients || '',
    defaultCc: rec.cc || '',
    defaultBcc: rec.bcc || '',
    defaultContent: rec.content || '',
  })
}

// ===== Move to Trash =====
async function moveToTrash() {
  try {
    await api.call('jingrow.email.inbox.mark_as_trash', {
      email: props.id,
    })
    message.success(t('Moved to trash'))
    emit('refresh')
  } catch (err: any) {
    message.error(err?.message || t('Operation failed'))
  }
}

// ===== Restore from Spam/Trash/Draft =====
async function markAsOpen() {
  try {
    await api.call('jingrow.email.inbox.mark_as_open', {
      email: props.id,
    })
    message.success(t('Restored successfully'))
    emit('refresh')
  } catch (err: any) {
    message.error(err?.message || t('Operation failed'))
  }
}

// ===== Permanent Delete (from Trash/Spam) =====
async function permanentDelete() {
  dialog.warning({
    title: t('Delete'),
    content: t('Are you sure you want to delete this record? This action cannot be undone.'),
    positiveText: t('Delete'),
    negativeText: t('Cancel'),
    onPositiveClick: async () => {
      try {
        await api.call('jingrow.email.inbox.permanent_delete_emails', {
                  names: [props.id],
                })
        message.success(t('Deleted successfully'))
        emit('refresh')
      } catch (err: any) {
        message.error(err?.message || t('Delete failed'))
      }
    }
  })
}

// ===== Purge Archived (admin only) =====
async function purgeArchived() {
  dialog.warning({
    title: t('Delete Record'),
    content: t('Are you sure you want to delete this record? This action cannot be undone.'),
    positiveText: t('Delete'),
    negativeText: t('Cancel'),
    onPositiveClick: async () => {
      try {
        await api.call('jingrow.email.inbox.purge_archived_emails', {
                  names: [props.id],
                })
        message.success(t('Deleted successfully'))
        emit('refresh')
      } catch (err: any) {
        message.error(err?.message || t('Delete failed'))
      }
    }
  })
}

// ===== Add to Contact =====
function addToContact() {
  const fullname = senderFullName.value || ''
  const names = fullname.split(' ')
  const firstName = names[0] || ''
  const lastName = names.length >= 2 ? names[names.length - 1] : ''
  const email = sender.value.replace(/<.*>/, '').trim() || sender.value
  const phone = props.record?.phone_no || ''

  // Store default values in sessionStorage (same mechanism as Duplicate)
  const storageKey = 'duplicate:Contact'
  try {
    sessionStorage.setItem(storageKey, JSON.stringify({
      email_id: email,
      first_name: firstName,
      last_name: lastName,
      mobile_no: phone,
    }))
  } catch {}

  // Navigate to new Contact page using Vue Router
  const slug = pageTypeToSlug('Contact')
  const randomStr = Math.random().toString(36).substring(2, 12)
  const tempName = `new-${slug}-${randomStr}`
  router.push({
    name: 'PageTypeDetail',
    params: { entity: slug, id: tempName }
  })
}

// ===== Relink =====
const showRelinkDialog = ref(false)
const relinkFormRef = ref<FormInst | null>(null)
const relinking = ref(false)
const relinkForm = ref({ reference_pagetype: '', reference_name: '' as string | null })

const relinkRules: FormRules = {
  reference_pagetype: [{ required: true, message: t('Required'), trigger: 'change' }],
}

// Clear reference_name when pagetype changes
watch(() => relinkForm.value.reference_pagetype, () => {
  relinkForm.value.reference_name = ''
})

async function confirmRelink() {
  try {
    await relinkFormRef.value?.validate()
  } catch { return }

  relinking.value = true
  try {
    await api.call('jingrow.email.relink', {
      name: props.id,
      reference_pagetype: relinkForm.value.reference_pagetype,
      reference_name: relinkForm.value.reference_name,
    })
    message.success(t('Relinked successfully'))
    showRelinkDialog.value = false
    emit('refresh')
  } catch (err: any) {
    message.error(err?.message || t('Operation failed'))
  } finally {
    relinking.value = false
  }
}

// ===== Move =====
const showMoveDialog = ref(false)
const moveTargetAccount = ref<string | null>(null)
const emailAccountOptions = ref<{ label: string; value: string }[]>([])
const loadingAccounts = ref(false)
const moving = ref(false)

async function openMoveDialog() {
  showMoveDialog.value = true
  moveTargetAccount.value = null
  if (emailAccountOptions.value.length === 0) {
    try {
      loadingAccounts.value = true
      const res = await api.call('jingrow.email.inbox.get_email_accounts')
      const payload = res?.email_accounts ? res : (res?.message || {})
      const data = (payload?.email_accounts ?? []) as any[]
      emailAccountOptions.value = data
        .filter((d: any) => {
          const ea = d.email_account ?? ''
          return ea && ea !== emailAccount.value && ea !== 'All Accounts'
        })
        .map((d: any) => ({
          label: d.email_id,
          value: d.email_account,
        }))
    } catch { /* ignore */ } finally {
      loadingAccounts.value = false
    }
  }
}

async function confirmMove() {
  if (!moveTargetAccount.value) {
    message.warning(t('Select an email account'))
    return
  }
  moving.value = true
  try {
    await api.call('jingrow.email.inbox.move_email', {
      email: props.id,
      email_account: moveTargetAccount.value,
    })
    message.success(t('Done'))
    showMoveDialog.value = false
    emit('refresh')
  } catch (err: any) {
    message.error(err?.message || t('Operation failed'))
  } finally {
    moving.value = false
  }
}

// ===== Assign To =====
const showAssignDialog = ref(false)
const assignTargetAccount = ref<string | null>(null)
const assignAccountOptions = ref<{ label: string; value: string }[]>([])
const loadingAssignAccounts = ref(false)
const assigning = ref(false)

async function openAssignDialog() {
  showAssignDialog.value = true
  assignTargetAccount.value = null
  assignAccountOptions.value = []
  try {
    loadingAssignAccounts.value = true
    const res = await api.call('jingrow.email.inbox.get_all_email_accounts')
    const payload = res?.email_accounts ? res : (res?.message || {})
    const data = (payload?.email_accounts ?? []) as any[]
    assignAccountOptions.value = data
      .filter((d: any) => d.name && d.name !== emailAccount.value)
      .map((d: any) => ({
        label: d.email_account_name ? `${d.email_account_name} (${d.email_id})` : (d.email_id || d.name),
        value: d.name,
      }))
  } catch (err: any) {
    message.error(err?.message || t('Failed to load email accounts'))
  } finally {
    loadingAssignAccounts.value = false
  }
}

async function confirmAssign() {
  if (!assignTargetAccount.value) {
    message.warning(t('Select an email account'))
    return
  }
  assigning.value = true
  try {
    await api.call('jingrow.email.inbox.move_email', {
      email: props.id,
      email_account: assignTargetAccount.value,
    })
    message.success(t('Done'))
    showAssignDialog.value = false
    emit('refresh')
  } catch (err: any) {
    message.error(err?.message || t('Operation failed'))
  } finally {
    assigning.value = false
  }
}

// ===== Dropdown helpers =====
function makeOption(key: string, label: string, icon: string | undefined, condition = true): DropdownOption | null {
  if (!condition || !icon) return null
  return { label, key, icon }
}

function renderMenuIcon(option: DropdownOption) {
  const iconName = option.icon as string
  if (!iconName) return null
  return h(NIcon, null, { default: () => h(Icon, { icon: iconName }) })
}

const moreOptions = computed<DropdownOption[]>(() => {
  const opts: DropdownOption[] = []

  // Email action items (from former Actions dropdown)
  if (canReply.value) {
    const replyAll = makeOption('reply_all', t('Reply All'), 'tabler:arrow-back-up-double')
    if (replyAll) opts.push(replyAll)

    const readLabel = isSeen.value ? t('Mark as Unread') : t('Mark as Read')
    const readIcon = isSeen.value ? 'tabler:mail-opened' : 'tabler:mail-check'
    const toggleRead = makeOption('toggle_read', readLabel, readIcon)
    if (toggleRead) opts.push(toggleRead)

    const move = makeOption('move', t('Move'), 'tabler:arrows-transfer-down')
    if (move) opts.push(move)

    const assign = makeOption('assign', t('Assign To'), 'tabler:user-share')
    if (assign) opts.push(assign)

    if (isSpam.value) {
      const notSpam = makeOption('not_spam', t('Not Spam'), 'tabler:circle-check')
      if (notSpam) opts.push(notSpam)
    } else if (!isTrash.value) {
      const spam = makeOption('spam', t('Mark as Spam'), 'tabler:alert-triangle')
      if (spam) opts.push(spam)
    }

    if (isTrash.value || isSpam.value) {
      if (isTrash.value) {
        const restore = makeOption('restore', t('Restore'), 'tabler:arrow-back-up')
        if (restore) opts.push(restore)
      }
      const permanentDelete = makeOption('permanent_delete', t('Delete Permanently'), 'tabler:trash-x')
      if (permanentDelete) opts.push(permanentDelete)
    } else if (isArchived.value) {
      const restore = makeOption('restore', t('Restore'), 'tabler:arrow-back-up')
      if (restore) opts.push(restore)
      const purge = makeOption('purge', t('Delete'), 'tabler:trash-x')
      if (purge) opts.push(purge)
    } else {
      const trash = makeOption('trash', t('Move To Trash'), 'tabler:trash')
      if (trash) opts.push(trash)
    }

    // Close / Reopen
    if (!isNew.value && !isLinked.value) {
      const closeLabel = isOpen.value ? t('Close') : t('Reopen')
      const closeIcon = isOpen.value ? 'tabler:x' : 'tabler:rotate-clockwise'
      const closeOpt = makeOption('toggle_close', closeLabel, closeIcon)
      if (closeOpt) opts.push(closeOpt)
    }

    opts.push({ type: 'divider', key: 'd-email-actions' })
  }

  // Edit (available for all non-new emails)
  if (!isNew.value) {
    const edit = makeOption('edit', t('Edit'), 'tabler:edit')
    if (edit) opts.push(edit)
  }

  // General more items
  const canRename = !isNew.value && props.canEdit && !!props.pageMeta?.allow_rename
  if (canRename) {
    const rename = makeOption('rename', t('Rename'), 'tabler:edit')
    if (rename) opts.push(rename)
  }

  if (!isNew.value) {
    const newEmail = makeOption('new_email', t('New Email'), 'tabler:mail')
    if (newEmail) opts.push(newEmail)
  }

  // Add to Contact
  if (canReply.value) {
    const contact = makeOption('contact', t('Contact'), 'tabler:user-plus')
    if (contact) opts.push(contact)
  }

  // Relink
  if (!isNew.value) {
    const relink = makeOption('relink', t('Relink'), 'tabler:link')
    if (relink) opts.push(relink)
  }

  return opts
})

function handleMoreSelect(key: string) {
  switch (key) {
    case 'reply_all': replyAll(); break
    case 'toggle_read': markAsReadUnread(); break
    case 'move': openMoveDialog(); break
    case 'assign': openAssignDialog(); break
    case 'spam': markAsSpam(); break
    case 'not_spam': markAsOpen(); break
    case 'trash': moveToTrash(); break
    case 'restore': markAsOpen(); break
    case 'permanent_delete': permanentDelete(); break
        case 'purge': purgeArchived(); break
    case 'edit': editEmail(); break
    case 'toggle_close': markAsClosedOpen(); break
    case 'contact': addToContact(); break
    case 'relink': showRelinkDialog.value = true; break
    case 'rename': emit('rename', '')
      break
    case 'new_email':
      composeRef.value?.open({
        referencePagetype: props.entity,
        referenceName: props.id,
      })
      break
  }
}

onMounted(() => {
  loadRowNames()
})

watch(() => props.id, (newId) => {
  // Only reload when the id is not in current rowNames (e.g., after list refresh from delete/restore)
  // Do NOT reload on normal prev/next navigation, which would reset fetchPage extensions
  if (newId && !rowNames.value.includes(newId)) {
    loadRowNames()
  }
})
</script>

<style scoped>
.header-action-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.header-action-btn.delete-btn:hover:not(:disabled) {
  background: #ef4444 !important;
  border-color: #ef4444 !important;
  color: white !important;
}

.header-action-btn.like-action-btn.is-liked {
  background: #fef2f2 !important;
}
.header-action-btn.like-action-btn.is-liked :deep(.n-icon) {
  color: #ef4444;
}

/* Reply button - same style as Forward */


/* Relink dialog - allow LinkField dropdown to overflow */
:deep(.n-dialog__content) {
  overflow: visible !important;
}
</style>
