<template>
  <div class="email-list-page">
    <!-- 页面头部 -->
    <div class="page-header">
      <div class="header-left">
        <h2>{{ t('Email') }}</h2>
      </div>
      <div class="header-right">
        <!-- 自定义工具栏 -->
        <EmailListToolbar
          :entity="entity"
          :search-query="searchQuery"
          :view-mode="viewMode"
          :selected-keys="selectedKeys"
          :loading="loading"
          :can-edit="canEditList"
          @update:search-query="searchQuery = $event"
          @update:view-mode="viewMode = $event"
          @reload="reload"
          @create="openComposeEmail"
          @delete-selected="handleDeleteSelected"
        />
      </div>
    </div>

    <!-- 邮件列表 + 预览面板 -->
    <div class="list-content-wrapper" :class="{ 'three-col': viewMode === '3col', 'preview-open': previewVisible }">

      <!-- 左侧列：过滤栏 + 邮件列表 -->
      <div class="left-column">
        <!-- 过滤栏（只占列表列宽） -->
        <div class="filter-bar">
          <div class="filter-tabs">
            <label class="select-all-label" :title="isAllSelected ? t('Unselect All') : t('Select All')">
              <input type="checkbox" :checked="isAllSelected" :indeterminate.prop="isPartialSelected" @change="toggleSelectAll" />
            </label>
            <button
              v-for="tab in filterTabs"
              :key="tab.key"
              class="filter-tab"
              :class="{ active: activeFilter === tab.key, ['tab-' + tab.key]: true }"
              @click="setFilter(tab.key)"
            >
              <Icon :icon="tab.icon" :size="16" />
              <span>{{ tab.label }}</span>
              <span v-if="tab.count !== undefined" class="tab-count">{{ tab.count }}</span>
            </button>
          </div>
          <div class="filter-actions">
          </div>
        </div>

        <div class="email-list-panel">
        <!-- 加载状态 -->
        <div v-if="loading && rows.length === 0" class="loading-full">
          <div class="loading-spinner"></div>
          <span>{{ t('Loading...') }}</span>
        </div>

        <!-- 空状态 -->
        <div v-else-if="rows.length === 0" class="empty-state">
          <Icon icon="tabler:mail-off" :size="48" />
          <p>{{ t('No Results found') }}</p>
        </div>

        <!-- 邮件行列表 -->
        <div v-else class="email-rows">
          <div
            v-for="row in rows"
            :key="row.name"
            class="email-row"
            :class="{
              'is-selected': selectedKeys.includes(row.name),
              'is-previewed': previewName === row.name,
              'is-unread': !row.seen && row.sent_or_received === 'Received',
              'is-incoming': row.sent_or_received === 'Received',
              'is-outgoing': row.sent_or_received === 'Sent',
            }"
            @click="handleRowClick(row)"
          >
            <div class="row-checkbox" @click.stop="toggleSelection(row.name)">
              <input type="checkbox" :checked="selectedKeys.includes(row.name)" />
            </div>
            <div class="row-avatar">
              <span class="avatar-letter">{{ getAvatarLetter(row) }}</span>
            </div>
            <div class="row-content">
              <div class="row-top">
                <span class="row-sender">{{ getSenderName(row) }}</span>
                <span class="row-direction" :class="row.sent_or_received === 'Received' ? 'dir-in' : 'dir-out'">
                  <Icon :icon="row.sent_or_received === 'Received' ? 'tabler:arrow-down-left' : 'tabler:arrow-up-right'" :size="12" />
                </span>
              </div>
              <div class="row-subject">{{ row.subject || t('No Subject') }}</div>
            </div>
            <div class="row-date-wrapper">
              <span class="row-date">{{ formatDateTime(row.communication_date) }}</span>
            </div>
            <div class="row-actions">
              <template v-if="activeFilter === 'spam' || activeFilter === 'trash'">
                <button class="restore-btn" @click.stop="handleRestoreSingle(row)" :title="t('Restore')">
                  <Icon icon="tabler:arrow-back-up" :size="16" />
                </button>
                <button class="delete-btn" @click.stop="handlePermanentDeleteSingle(row)" :title="t('Delete Permanently')">
                  <Icon icon="tabler:trash-x" :size="16" />
                </button>
              </template>
              <template v-else-if="activeFilter === 'archived'">
                <button class="restore-btn" @click.stop="handleRestoreSingle(row)" :title="t('Restore')">
                  <Icon icon="tabler:arrow-back-up" :size="16" />
                </button>
                <button class="delete-btn" @click.stop="handlePurgeSingle(row)" :title="t('Delete')">
                  <Icon icon="tabler:trash-x" :size="16" />
                </button>
              </template>
              <template v-else>
                <button class="delete-btn" @click.stop="handleDeleteSingle(row)" :title="t('Move to Trash')">
                  <Icon icon="tabler:trash" :size="16" />
                </button>
              </template>
            </div>

          </div>
        </div>

        <!-- 分页 -->
        <div v-if="rows.length > 0" class="list-pagination">
          <n-pagination v-model:page="page" :page-count="pageCount" size="small" />
        </div>
      </div><!-- /email-list-panel -->
      </div><!-- /left-column -->

      <!-- 三列布局：拖拽分割线 -->
      <div
        v-if="viewMode === '3col' && previewVisible"
        class="resize-handle"
        @mousedown="startResize"
      ></div>

      <!-- 三列布局：内嵌预览面板 -->
      <div v-if="viewMode === '3col' && previewVisible" class="preview-panel" :style="panelWidth > 0 ? { width: panelWidth + 'px' } : { flex: '0 0 55%' }">
        <div ref="panelPreviewWrapperRef" class="preview-wrapper">
          <!-- 加载状态 -->
          <div v-if="previewLoading" class="preview-loading">
            <div class="loading-spinner"></div>
          </div>

          <template v-if="!previewLoading && previewRecord">
            <!-- 预览标题区 -->
            <div class="preview-header">
              <h3 class="preview-subject">{{ previewRecord.subject || t('No Subject') }}</h3>
              <button class="action-icon-btn close-preview-btn" @click="closePreview" :title="t('Close Preview')">
                <Icon icon="tabler:x" :size="16" />
              </button>
            </div>

            <!-- 工具栏 -->
            <div class="drawer-toolbar">
              <EmailToolbar
                :entity="entity"
                :id="previewName"
                :record="previewRecord"
                :can-edit="canEditList"
                :loading="false"
                :_in-panel="true"
                @refresh="refreshPreview"
                @delete="handleDeletePreview"
                @go-back="closePreview"
                @prev="navigatePreviewPrev"
                @next="navigatePreviewNext"
              />
            </div>

            <EmailEnvelope
              :record="previewRecord"
              :attachments="previewAttachments"
              :status-badge="previewStatusBadge"
              :delivery-badge="previewDeliveryBadge"
              @reply="replyPreview"
              @reply-all="replyAllPreview"
              @forward="forwardPreview"
              @go-to-reference="goToReference"
            />

            <!-- Activity Section -->
            <div class="activity-wrapper">
              <ActivitySection
                :entity="entity"
                :id="previewName"
                :record="previewRecord"
                :can-edit="canEditList"
                @refresh="refreshPreview"
              />
            </div>
          </template>
        </div>
      </div>
    </div>

    <!-- 两列布局：抽屉弹窗预览 -->
    <n-drawer v-if="viewMode === '2col'" v-model:show="previewVisible" :width="'50%'" placement="right" :mask-closable="true" @after-leave="onDrawerClose">
      <n-drawer-content closable :title="previewSubject" class="preview-drawer-content">
        <div class="preview-wrapper">
          <div v-if="previewLoading" class="preview-loading">
            <div class="loading-spinner"></div>
          </div>

          <template v-if="!previewLoading && previewRecord">
            <div class="drawer-toolbar">
              <EmailToolbar
                :entity="entity"
                :id="previewName"
                :record="previewRecord"
                :can-edit="canEditList"
                :loading="false"
                :_in-panel="true"
                @refresh="refreshPreview"
                @delete="handleDeletePreview"
                @go-back="previewVisible = false"
                @prev="navigatePreviewPrev"
                @next="navigatePreviewNext"
              />
            </div>

            <EmailEnvelope
              :record="previewRecord"
              :attachments="previewAttachments"
              :status-badge="previewStatusBadge"
              :delivery-badge="previewDeliveryBadge"
              @reply="replyPreview"
              @reply-all="replyAllPreview"
              @forward="forwardPreview"
              @go-to-reference="goToReference"
            />

            <div class="activity-wrapper">
              <ActivitySection
                :entity="entity"
                :id="previewName"
                :record="previewRecord"
                :can-edit="canEditList"
                @refresh="refreshPreview"
              />
            </div>
          </template>
        </div>
      </n-drawer-content>
    </n-drawer>

    <!-- 邮件编写抽屉 -->
    <EmailComposeModal ref="composeRef" @sent="onEmailSent" />
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref, computed, watch, shallowRef, markRaw, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { NDrawer, NDrawerContent, NButton, NIcon, NPagination, useMessage, useDialog } from 'naive-ui'
import { Icon } from '@iconify/vue'
import axios from 'axios'
import { t, createT } from '@/shared/i18n'
import { formatDateTimeInTimezone } from '@/shared/utils/timezone'
import { usePageTypeSlug } from '@/shared/utils/slug'
import { getRecord, getRecordAttachments, getPageTypeMeta, api } from '@/shared/api/common'
import { usePermissionStore } from '@/shared/stores/permissions'
import { useAuthStore } from '@/shared/stores/auth'
import EmailComposeModal from '@/shared/components/EmailComposeModal.vue'
import EmailEnvelope from '@/shared/components/EmailEnvelope.vue'
import ActivitySection from '@/core/pagetype/form/panel/ActivitySection.vue'
import EmailToolbar from './email_toolbar.vue'
import EmailListToolbar from './email_list_toolbar.vue'

const route = useRoute()
const router = useRouter()
const message = useMessage()
const dialog = useDialog()
const permissionStore = usePermissionStore()
const authStore = useAuthStore()

const { pagetypeSlug, entity } = usePageTypeSlug(route)
const t_ctx = createT(() => entity.value)
const canEditList = computed(() => permissionStore.canWrite(entity.value))

// ===== 列表状态 =====
const searchQuery = ref('')
const loading = ref(false)
const rows = ref<any[]>([])
const page = ref(Number(route.query.page) || 1)
const pageSize = ref(parseInt(localStorage.getItem('comm_items_per_page') || '10'))
const total = ref(0)
const pageCount = computed(() => {
  if (total.value === 0) return 1
  return Math.max(1, Math.ceil(total.value / pageSize.value))
})
const selectedKeys = ref<string[]>([])
const viewMode = ref<'2col' | '3col'>((localStorage.getItem('comm_view_mode') as any) || '3col')

watch(viewMode, (val) => {
  localStorage.setItem('comm_view_mode', val)
  closePreview()
})

// ===== 列表状态持久化（供 toolbar Prev/Next 使用） =====
const listStateKey = computed(() => `list-state:${entity.value}`)

function saveListState() {
  const state = {
    page: page.value,
    activeFilter: activeFilter.value,
    searchQuery: searchQuery.value,
    rowNames: rows.value.map((r: any) => r.name),
    apiFilters: currentFilters.value,
  }
  sessionStorage.setItem(listStateKey.value, JSON.stringify(state))
}

// ===== 过滤状态 =====
const activeFilter = ref<string>('all')

const filterTabs = computed(() => {
  const tabs = [
    { key: 'all', label: t('All'), icon: 'tabler:mail', count: undefined },
    { key: 'inbox', label: t_ctx('Inbox'), icon: 'tabler:arrow-down-left', count: undefined },
    { key: 'sent', label: t_ctx('Sent'), icon: 'tabler:arrow-up-right', count: undefined },
    { key: 'draft', label: t_ctx('Draft'), icon: 'tabler:file-pencil', count: undefined },
    { key: 'spam', label: t_ctx('Spam'), icon: 'tabler:alert-octagon', count: undefined },
    { key: 'trash', label: t_ctx('Trash'), icon: 'tabler:trash', count: undefined },
  ]
  // Archived tab: only visible to System Manager or Administrator
  const isSystemManager = permissionStore.roles.includes('System Manager') || permissionStore.roles.includes('Administrator')
  if (isSystemManager) {
    tabs.push({ key: 'archived', label: t_ctx('Archived'), icon: 'tabler:archive', count: undefined })
  }
  return tabs
})

function setFilter(key: string) {
  activeFilter.value = key
  page.value = 1
  loadData()
}

// ===== 全选逻辑 =====
const isAllSelected = computed(() => rows.value.length > 0 && rows.value.every(r => selectedKeys.value.includes(r.name)))
const isPartialSelected = computed(() => !isAllSelected.value && rows.value.some(r => selectedKeys.value.includes(r.name)))

function toggleSelectAll() {
  if (isAllSelected.value) {
    selectedKeys.value = []
  } else {
    selectedKeys.value = rows.value.map(r => r.name)
  }
}

// ===== 预览状态 =====
const previewVisible = ref(false)
const previewLoading = ref(false)
const previewName = ref('')
const previewRecord = ref<any>(null)
const panelPreviewWrapperRef = ref<HTMLElement | null>(null)

// ===== 三列布局面板宽度 & 拖拽 =====
const panelWidth = ref(0) // 0 = 使用CSS flex默认值，拖拽后切换为px
const isResizing = ref(false)

function startResize(e: MouseEvent) {
  e.preventDefault()
  isResizing.value = true
  const wrapperEl = (e.currentTarget as HTMLElement).parentElement
  if (!wrapperEl) return
  const wrapperWidth = wrapperEl.clientWidth
  const startX = e.clientX
  // 读取面板当前实际渲染宽度作为拖拽起点
  const panelEl = wrapperEl.querySelector('.preview-panel') as HTMLElement | null
  const startWidth = panelEl ? panelEl.clientWidth : Math.round(wrapperWidth * 0.55)
  const minWidth = Math.round(wrapperWidth * 0.5)
  const maxWidth = Math.round(wrapperWidth * 0.7)

  function onMouseMove(ev: MouseEvent) {
    const delta = startX - ev.clientX // 向左拖=面板变宽
    let newWidth = startWidth + delta
    newWidth = Math.max(minWidth, Math.min(newWidth, maxWidth))
    panelWidth.value = newWidth
  }

  function onMouseUp() {
    isResizing.value = false
    document.removeEventListener('mousemove', onMouseMove)
    document.removeEventListener('mouseup', onMouseUp)
    document.body.style.cursor = ''
    document.body.style.userSelect = ''
  }

  document.addEventListener('mousemove', onMouseMove)
  document.addEventListener('mouseup', onMouseUp)
  document.body.style.cursor = 'col-resize'
  document.body.style.userSelect = 'none'
}

// ===== 邮件编写 =====
const composeRef = ref<InstanceType<typeof EmailComposeModal> | null>(null)

function openComposeEmail() {
  composeRef.value?.open()
}

function onEmailSent() {
  reload()
}

// ===== 数据加载 =====
const listFields = [
  'name', 'subject', 'sender', 'sender_full_name', 'recipients', 'cc', 'bcc',
  'communication_date', 'sent_or_received', 'status', 'delivery_status',
  'reference_pagetype', 'reference_name',
  'seen', 'email_account', 'email_status', 'user', '_liked_by',
]

// ===== 过滤条件（供 loadData 和 saveListState 使用） =====
const currentFilters = computed(() => {
  const filters: any[] = []
  if (activeFilter.value === 'draft') {
    filters.push(['email_status', '=', 'Draft'])
  } else if (activeFilter.value === 'spam') {
    filters.push(['email_status', '=', 'Spam'])
  } else if (activeFilter.value === 'trash') {
    filters.push(['email_status', '=', 'Trash'])
  } else if (activeFilter.value === 'archived') {
    filters.push(['email_status', '=', 'Archived'])
  } else {
    filters.push(['email_status', 'not in', ['Draft', 'Spam', 'Trash', 'Archived']])
  }
  if (activeFilter.value === 'inbox') {
    filters.push(['sent_or_received', '=', 'Received'])
  } else if (activeFilter.value === 'sent') {
    filters.push(['sent_or_received', '=', 'Sent'])
  }
  if (searchQuery.value) {
    filters.push(['subject', 'like', `%${searchQuery.value}%`])
  }
  return filters
})

async function loadData() {
  loading.value = true
  try {
    const params: any = {
      fields: JSON.stringify(listFields),
      limit_start: (page.value - 1) * pageSize.value,
      limit_page_length: pageSize.value + 1,
      order_by: 'communication_date desc',
    }

    if (currentFilters.value.length > 0) {
      params.filters = JSON.stringify(currentFilters.value)
    }

    const res = await axios.get(`/api/data/${encodeURIComponent(entity.value)}`, { params })
    const allRows = res.data?.data || []

    if (res.data?.total) {
      rows.value = allRows
      total.value = res.data.total
    } else {
      const hasMore = allRows.length > pageSize.value
      rows.value = hasMore ? allRows.slice(0, pageSize.value) : allRows
      total.value = (page.value - 1) * pageSize.value + rows.value.length + (hasMore ? 1 : 0)
    }
  } catch (error) {
    console.error('Load data error:', error)
    message.error(t('Load failed'))
  } finally {
    loading.value = false
    saveListState()
  }
}

function reload() {
  loadData()
}

// ===== 行操作 =====
function handleRowClick(row: any) {
  if (viewMode.value === '3col') {
    // 三列布局：内嵌面板预览
    openPreview(row)
  } else {
    // 两列布局：跳转详情页
    router.push({
      name: 'PageTypeDetail',
      params: { entity: pagetypeSlug.value, id: row.name },
      state: { _listPage: page.value }
    })
  }
}

function closePreview() {
  previewVisible.value = false
  previewName.value = ''
  previewRecord.value = null
  panelWidth.value = 0
}

function toggleSelection(name: string) {
  const idx = selectedKeys.value.indexOf(name)
  if (idx >= 0) {
    selectedKeys.value.splice(idx, 1)
  } else {
    selectedKeys.value.push(name)
  }
}

async function handleDeleteSelected() {
  if (selectedKeys.value.length === 0) return
  const previewWasInSelection = previewName.value && selectedKeys.value.includes(previewName.value)
  const removedIdx = previewWasInSelection ? rows.value.findIndex(r => r.name === previewName.value) : -1
  const isDeletableFilter = activeFilter.value === 'spam' || activeFilter.value === 'trash'
  const isArchivedFilter = activeFilter.value === 'archived'

  if (isDeletableFilter) {
    // In spam/trash: permanent delete with confirmation
    dialog.warning({
      title: t('Delete Selected Records'),
      content: `${t('Are you sure you want to delete')} ${selectedKeys.value.length} ${t('selected record(s)? This action cannot be undone.')}`,
      positiveText: t('Delete'),
      negativeText: t('Cancel'),
      onPositiveClick: async () => {
        loading.value = true
        try {
          await api.call('jingrow.email.inbox.permanent_delete_emails', {
                    names: selectedKeys.value,
                  })
          message.success(t('Successfully deleted {count} records', { count: selectedKeys.value.length }))
          selectedKeys.value = []
          await loadData()
          if (previewWasInSelection) {
            previewNextOrClose(previewName.value, removedIdx)
          }
        } catch {
          message.error(t('Delete failed'))
        } finally {
          loading.value = false
        }
      }
    })
  } else if (isArchivedFilter) {
    // In archived: purge from DB with confirmation
    dialog.warning({
      title: t('Delete Selected Records'),
      content: `${t('Are you sure you want to delete')} ${selectedKeys.value.length} ${t('selected record(s)? This action cannot be undone.')}`,
      positiveText: t('Delete'),
      negativeText: t('Cancel'),
      onPositiveClick: async () => {
        loading.value = true
        try {
          await api.call('jingrow.email.inbox.purge_archived_emails', {
                    names: selectedKeys.value,
                  })
          message.success(t('Successfully deleted {count} records', { count: selectedKeys.value.length }))
          selectedKeys.value = []
          await loadData()
          if (previewWasInSelection) {
            previewNextOrClose(previewName.value, removedIdx)
          }
        } catch {
          message.error(t('Delete failed'))
        } finally {
          loading.value = false
        }
      }
    })
  } else {
    // In other tabs: move to trash
    loading.value = true
    try {
      for (const name of selectedKeys.value) {
        try {
          await api.call('jingrow.email.inbox.mark_as_trash', { email: name })
        } catch { /* skip failed */ }
      }
      message.success(t('Moved to trash'))
      selectedKeys.value = []
      await loadData()
      if (previewWasInSelection) {
        previewNextOrClose(previewName.value, removedIdx)
      }
    } catch {
      message.error(t('Operation failed'))
    } finally {
      loading.value = false
    }
  }
}

async function handleDeleteSingle(row: any) {
  const removedIdx = rows.value.findIndex(r => r.name === row.name)
  try {
    await api.call('jingrow.email.inbox.mark_as_trash', { email: row.name })
    message.success(t('Moved to trash'))
    await loadData()
    previewNextOrClose(row.name, removedIdx)
  } catch (err: any) {
    message.error(err?.message || t('Operation failed'))
  }
}

async function handleRestoreSingle(row: any) {
  const removedIdx = rows.value.findIndex(r => r.name === row.name)
  try {
    await api.call('jingrow.email.inbox.mark_as_open', { email: row.name })
    message.success(t('Restored successfully'))
    await loadData()
    previewNextOrClose(row.name, removedIdx)
  } catch (err: any) {
    message.error(err?.message || t('Operation failed'))
  }
}

async function handlePermanentDeleteSingle(row: any) {
  const removedIdx = rows.value.findIndex(r => r.name === row.name)
  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: [row.name],
              })
        message.success(t('Deleted successfully'))
        await loadData()
        previewNextOrClose(row.name, removedIdx)
      } catch (err: any) {
        message.error(err?.message || t('Delete failed'))
      }
    }
  })
}

/** Purge archived email from DB permanently (admin only) */
async function handlePurgeSingle(row: any) {
  const removedIdx = rows.value.findIndex(r => r.name === row.name)
  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.purge_archived_emails', {
                names: [row.name],
              })
        message.success(t('Deleted successfully'))
        await loadData()
        previewNextOrClose(row.name, removedIdx)
      } catch (err: any) {
        message.error(err?.message || t('Delete failed'))
      }
    }
  })
}

// ===== 预览操作 =====

/** After a removal operation, navigate to the next record or close preview if none */
function previewNextOrClose(removedName: string, removedIndex: number) {
  if (previewName.value !== removedName) return
  if (rows.value.length === 0) {
    closePreview()
    return
  }
  const nextIdx = Math.min(removedIndex >= 0 ? removedIndex : 0, rows.value.length - 1)
  openPreview(rows.value[nextIdx])
}

// ===== 预览滚动重置 =====
function scrollPreviewToTop() {
  nextTick(() => {
    // 三列面板：直接滚动 wrapper
    if (panelPreviewWrapperRef.value) {
      panelPreviewWrapperRef.value.scrollTop = 0
    }
    // 两列抽屉：滚动 naive-ui 内部滚动容器
    const drawerScrollEl = document.querySelector('.preview-drawer-content .n-scrollbar-container') as HTMLElement
    if (drawerScrollEl) {
      drawerScrollEl.scrollTop = 0
    }
  })
}

async function openPreview(row: any) {
  // 点击同一行不重复加载
  if (previewName.value === row.name && previewRecord.value) return

  previewName.value = row.name
  previewVisible.value = true

  // 仅在首次打开（无已有内容）时显示加载状态
  // 切换记录时保留旧内容直到新数据就绪，避免内容闪烁
  if (!previewRecord.value) {
    previewLoading.value = true
  }

  try {
    const [recordRes, attachmentsRes] = await Promise.all([
      getRecord(entity.value, row.name),
      getRecordAttachments(entity.value, row.name)
    ])

    if (recordRes.success && recordRes.data) {
      previewRecord.value = recordRes.data
      if (attachmentsRes.success && attachmentsRes.data) {
        previewRecord.value.attachments = attachmentsRes.data
      }
      scrollPreviewToTop()
    } else {
      message.error(recordRes.message || t('Failed to load detail'))
      previewRecord.value = null
    }

    // 自动标记已读
    if (!row.seen) {
      try {
        await api.call('jingrow.email.inbox.create_email_flag_queue', {
          names: JSON.stringify([row.name]),
          action: 'Read',
          flag: '\\SEEN',
        })
        row.seen = true
      } catch { /* ignore */ }
    }
  } catch (error) {
    message.error(t('Failed to load detail'))
    previewRecord.value = null
  } finally {
    previewLoading.value = false
  }
}

function onDrawerClose() {
  previewName.value = ''
  previewRecord.value = null
}

async function refreshPreview() {
  const currentName = previewName.value
  if (!currentName) return
  // Capture index before reload (in case the record gets removed from current view)
  const currentIdx = rows.value.findIndex(r => r.name === currentName)
  // Refresh the left list first
  await loadData()
  // If the current record is no longer in the list (e.g., permanently deleted, marked as spam/trash/restored),
  // auto-navigate to the next record without trying to reload the removed record
  if (!rows.value.some(r => r.name === currentName)) {
    previewNextOrClose(currentName, currentIdx)
    return
  }
  // Record still in list, reload its detail
  try {
    const [recordRes, attachmentsRes] = await Promise.all([
      getRecord(entity.value, currentName),
      getRecordAttachments(entity.value, currentName)
    ])
    if (recordRes.success && recordRes.data) {
      previewRecord.value = recordRes.data
      if (attachmentsRes.success && attachmentsRes.data) {
        previewRecord.value.attachments = attachmentsRes.data
      }
    }
  } catch { /* ignore */ }
}

async function navigatePreview(name: string) {
  if (!name) return
  previewName.value = name

  // 仅在无已有内容时显示加载状态，避免切换时闪烁
  if (!previewRecord.value) {
    previewLoading.value = true
  }

  try {
    const [recordRes, attachmentsRes] = await Promise.all([
      getRecord(entity.value, name),
      getRecordAttachments(entity.value, name)
    ])
    if (recordRes.success && recordRes.data) {
      previewRecord.value = recordRes.data
      if (attachmentsRes.success && attachmentsRes.data) {
        previewRecord.value.attachments = attachmentsRes.data
      }
      scrollPreviewToTop()
    }
  } catch { /* ignore */ }
  finally {
    previewLoading.value = false
  }
}

/** 跨页导航时同步列表页码 */
function syncPageIfCrossed(name: string, direction: 'prev' | 'next') {
  if (!name || rows.value.some(r => r.name === name)) return
  if (direction === 'next' && page.value < pageCount.value) page.value++
  else if (direction === 'prev' && page.value > 1) page.value--
}

/** 预览导航：上一个 */
function navigatePreviewPrev(name: string) {
  navigatePreview(name)
  syncPageIfCrossed(name, 'prev')
}

/** 预览导航：下一个 */
function navigatePreviewNext(name: string) {
  navigatePreview(name)
  syncPageIfCrossed(name, 'next')
}

async function handleDeletePreview() {
  if (!previewName.value) return
  const removedIdx = rows.value.findIndex(r => r.name === previewName.value)
  try {
    await api.call('jingrow.email.inbox.mark_as_trash', { email: previewName.value })
    message.success(t('Moved to trash'))
    await loadData()
    previewNextOrClose(previewName.value, removedIdx)
  } catch (err: any) {
    message.error(err?.message || t('Operation failed'))
  }
}

// ===== 预览 computed =====
const previewSubject = computed(() => previewRecord.value?.subject || t('No Subject'))

const previewAttachments = computed(() => previewRecord.value?.attachments || [])

const previewStatusBadge = computed(() => {
  const map: Record<string, { label: string; class: string }> = {
    'Open': { label: t('Open'), class: 'status-open' },
    'Replied': { label: t('Replied'), class: 'status-replied' },
    'Closed': { label: t('Closed'), class: 'status-closed' },
    'Linked': { label: t('Linked'), class: 'status-linked' },
  }
  return map[previewRecord.value?.status || ''] || null
})

const previewDeliveryBadge = computed(() => {
  const map: Record<string, { label: string; class: string }> = {
    'Opened': { label: t('Opened'), class: 'delivery-opened' },
    'Bounced': { label: t('Bounced'), class: 'delivery-bounced' },
    'Error': { label: t('Error'), class: 'delivery-error' },
    'Sending': { label: t('Sending'), class: 'delivery-sending' },
    'Scheduled': { label: t('Scheduled'), class: 'delivery-scheduled' },
  }
  return map[previewRecord.value?.delivery_status || ''] || null
})

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

function getAvatarLetter(row: any): string {
  const raw = row.sender || ''
  const match = raw.match(/^(.+?)\s*<.*>$/)
  const name = match ? match[1].trim().replace(/^"|"$/g, '') : (row.sender_full_name || raw)
  return name.charAt(0).toUpperCase()
}

function getSenderName(row: any): string {
  const raw = row.sender || ''
  const match = raw.match(/^(.+?)\s*<.*>$/)
  return match ? match[1].trim().replace(/^"|"$/g, '') : (row.sender_full_name || raw)
}

function formatDateTime(value: any) {
  if (!value) return '—'
  try {
    return formatDateTimeInTimezone(value)
  } catch { return String(value) }
}

// ===== 导航 =====
function goToReference() {
  if (!previewRecord.value?.reference_pagetype || !previewRecord.value?.reference_name) return
  router.push({
    name: 'PageTypeDetail',
    params: {
      entity: previewRecord.value.reference_pagetype.replace(/ /g, '-').toLowerCase(),
      id: previewRecord.value.reference_name,
    }
  })
}

// ===== 预览中的邮件操作 =====
function getEmailAccount(): string {
  return previewRecord.value?.email_account || ''
}

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

function replyPreview() {
  const rec = previewRecord.value
  if (!rec) return
  composeRef.value?.open({
    pg: rec,
    lastEmail: rec,
    referencePagetype: rec.reference_pagetype,
    referenceName: rec.reference_name,
    isReply: true,
    replyAll: false,
    defaultSubject: (rec.subject || '').startsWith('Re:') ? rec.subject : `Re: ${rec.subject}`,
    defaultRecipients: rec.sender || '',
    defaultContent: rec.content || '',
  })
}

function replyAllPreview() {
  const rec = previewRecord.value
  if (!rec) return
  const selfEmail = getSenderEmailId()
  const allRecipients = splitEmailList(rec.recipients || '')
  const allCc = splitEmailList(rec.cc || '')
  const otherRecipients = [...allRecipients, ...allCc].filter(e => e !== selfEmail)
  composeRef.value?.open({
    pg: rec,
    lastEmail: rec,
    sender: getSenderEmailId(),
    attachments: previewAttachments.value,
    referencePagetype: rec.reference_pagetype,
    referenceName: rec.reference_name,
    isReply: true,
    replyAll: true,
    defaultSubject: (rec.subject || '').startsWith('Re:') ? rec.subject : `Re: ${rec.subject}`,
    defaultRecipients: rec.sender || '',
    defaultCc: otherRecipients.join(', '),
    defaultContent: rec.content || '',
  })
}

function forwardPreview() {
  const rec = previewRecord.value
  if (!rec) return
  composeRef.value?.open({
    pg: rec,
    lastEmail: rec,
    sender: getSenderEmailId(),
    attachments: previewAttachments.value,
    referencePagetype: rec.reference_pagetype,
    referenceName: rec.reference_name,
    isForward: true,
    defaultSubject: (rec.subject || '').startsWith('Fw:') ? rec.subject : `Fw: ${rec.subject}`,
    defaultRecipients: '',
    defaultContent: rec.content || '',
  })
}

// ===== 生命周期 =====
onMounted(() => {
  loadData()
})

// 监听分页变化
watch([page], () => {
  loadData()
  const currentPage = route.query.page
  const newPage = String(page.value)
  if (currentPage !== newPage) {
    router.replace({
      query: { ...route.query, page: page.value > 1 ? page.value : undefined }
    }).catch(() => {})
  }
})

// 监听搜索
let searchTimer: any = null
watch(searchQuery, () => {
  clearTimeout(searchTimer)
  searchTimer = setTimeout(() => {
    page.value = 1
    loadData()
  }, 300)
})

// 监听路由 entity 变化
watch(() => route.params.entity, async (newEntity, oldEntity) => {
  if (newEntity !== oldEntity) {
    page.value = 1
    searchQuery.value = ''
    selectedKeys.value = []
    activeFilter.value = 'all'
    previewVisible.value = false
    await loadData()
  }
})
</script>

<style scoped>
.email-list-page {
  padding: 0;
  height: calc(100vh - 104px);
  display: flex;
  flex-direction: column;
  background: #f8fafc;
  overflow: hidden;
}

/* ====== 页面头部 ====== */
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 24px;
  background: #ffffff;
  border-bottom: 1px solid #e5e7eb;
  flex-shrink: 0;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 12px;
}

.header-left h2 {
  font-size: 20px;
  font-weight: 600;
  color: #111827;
  margin: 0;
}

.header-right {
  display: flex;
  align-items: center;
}

/* ====== 过滤栏 ====== */
.filter-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 45px;
  padding: 0 12px;
  background: #ffffff;
  border-bottom: 1px solid #f0f0f0;
  flex-shrink: 0;
  overflow: hidden;
}

.filter-tabs {
  display: flex;
  align-items: center;
  gap: 0;
}

.select-all-label {
  display: inline-flex;
  align-items: center;
  padding-right: 4px;
  cursor: pointer;
  flex-shrink: 0;
}

.select-all-label input {
  width: 16px;
  height: 16px;
  cursor: pointer;
  accent-color: #3b82f6;
}

.filter-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 12px 16px;
  border: none;
  background: transparent;
  color: #6b7280;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: all 0.2s;
  white-space: nowrap;
}

.filter-tab:hover {
  color: #374151;
  background: #f9fafb;
}

.filter-tab.active {
  color: #1d4ed8;
  border-bottom-color: #1d4ed8;
}

.tab-count {
  font-size: 11px;
  background: #e5e7eb;
  color: #6b7280;
  padding: 1px 6px;
  border-radius: 10px;
  font-weight: 600;
}

.filter-tab.active .tab-count {
  background: #dbeafe;
  color: #1d4ed8;
}

/* 收件箱 tab 图标保持蓝色 */
.filter-tab.tab-inbox :deep(svg) {
  color: #3b82f6;
}

/* 收件箱激活态：文字和底部边框蓝色 */
.filter-tab.tab-inbox.active {
  color: #3b82f6;
  border-bottom-color: #3b82f6;
}

.filter-tab.tab-inbox.active .tab-count {
  background: #dbeafe;
  color: #3b82f6;
}

/* 已发送 tab 图标绿色，与列表行发件方向图标一致 */
.filter-tab.tab-sent :deep(svg) {
  color: #10b981;
}

/* 已发送激活态：文字和底部边框绿色 */
.filter-tab.tab-sent.active {
  color: #10b981;
  border-bottom-color: #10b981;
}

.filter-tab.tab-sent.active .tab-count {
  background: #d1fae5;
  color: #10b981;
}

/* 草稿 tab 图标琥珀色 */
.filter-tab.tab-draft :deep(svg) {
  color: #f59e0b;
}

/* 草稿激活态 */
.filter-tab.tab-draft.active {
  color: #f59e0b;
  border-bottom-color: #f59e0b;
}

.filter-tab.tab-draft.active .tab-count {
  background: #fef3c7;
  color: #f59e0b;
}

/* 垃圾邮件 tab 图标红色 */
.filter-tab.tab-spam :deep(svg) {
  color: #ef4444;
}

/* 垃圾邮件激活态 */
.filter-tab.tab-spam.active {
  color: #ef4444;
  border-bottom-color: #ef4444;
}

.filter-tab.tab-spam.active .tab-count {
  background: #fee2e2;
  color: #ef4444;
}

/* 回收站 tab 图标灰色 */
.filter-tab.tab-trash :deep(svg) {
  color: #6b7280;
}

/* 回收站激活态 */
.filter-tab.tab-trash.active {
  color: #6b7280;
  border-bottom-color: #6b7280;
}

.filter-tab.tab-trash.active .tab-count {
  background: #f3f4f6;
  color: #6b7280;
}

/* 存档 tab 图标棕色 */
.filter-tab.tab-archived :deep(svg) {
  color: #92400e;
}

/* 存档激活态 */
.filter-tab.tab-archived.active {
  color: #92400e;
  border-bottom-color: #92400e;
}

.filter-tab.tab-archived.active .tab-count {
  background: #fef3c7;
  color: #92400e;
}

.filter-actions {
  display: flex;
  align-items: center;
  gap: 4px;
}

.action-icon-btn {
  width: 32px;
  height: 32px;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: #6b7280;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s;
}

.action-icon-btn:hover {
  background: #f3f4f6;
  color: #374151;
}

.close-preview-btn:hover {
  background: #fee2e2;
  color: #dc2626;
}

.action-icon-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ====== 列表区域 ====== */
.list-content-wrapper {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  display: flex;
  transition: none;
}

/* 左侧列：过滤栏+列表 */
.left-column {
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  flex: 1;
}

.list-content-wrapper.three-col .left-column {
  min-width: 300px;
}

/* 预览标题区 */
.preview-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 0 8px 0 20px;
  height: 45px;
  background: #ffffff;
  border-bottom: 1px solid #f0f0f0;
  flex-shrink: 0;
}

.preview-subject {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #1f2937;
  line-height: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 三列布局：列表缩窄，预览面板占右侧 */
.list-content-wrapper.three-col {
  /* 保持默认flex布局 */
}

.list-content-wrapper.three-col .email-list-panel {
  flex: 1;
  min-width: 0;
  border-right: none;
}

.list-content-wrapper.three-col.preview-open .email-list-panel {
  flex: 1;
  min-width: 300px;
}

/* 拖拽分割线 */
.resize-handle {
  width: 4px;
  cursor: col-resize;
  background: transparent;
  flex-shrink: 0;
  transition: background 0.15s;
  z-index: 5;
}

.resize-handle:hover {
  background: #3b82f6;
}

/* 内嵌预览面板 */
.preview-panel {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: #fff;
  min-height: 0;
}

.preview-panel .preview-wrapper {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

.email-list-panel {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: #ffffff;
  margin: 0;
}

/* ====== 加载 & 空状态 ====== */
.loading-full {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 80px 0;
  gap: 16px;
  color: #9ca3af;
}

.loading-spinner {
  width: 32px;
  height: 32px;
  border: 3px solid #e5e7eb;
  border-top-color: #3b82f6;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

.spin-icon {
  animation: spin 0.8s linear infinite;
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 80px 0;
  gap: 12px;
  color: #9ca3af;
}

.empty-state p {
  font-size: 15px;
  margin: 0;
}

/* ====== 邮件行 ====== */
.email-rows {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

.email-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 12px 8px 12px;
  border-bottom: 1px solid #f5f5f5;
  cursor: pointer;
  transition: background-color 0.15s;
  position: relative;
}

.email-row:hover {
  background: #f8fafc;
}

.email-row.is-previewed {
  background: #eff6ff;
  border-left: 2px solid #3b82f6;
  border-radius: 6px 0 0 6px;
  border-bottom-color: transparent;
}

.email-row.is-previewed.is-outgoing {
  background: #f0fdf4;
  border-left: 2px solid #10b981;
}

.email-row.is-selected {
  background: #f0f9ff;
}

.email-row.is-unread .row-sender {
  font-weight: 700;
  color: #111827;
}

.email-row.is-unread .row-subject {
  font-weight: 600;
  color: #111827;
}

/* 复选框 */
.row-checkbox {
  flex-shrink: 0;
}

.row-checkbox input {
  width: 16px;
  height: 16px;
  cursor: pointer;
  accent-color: #3b82f6;
}

/* 头像 */
.row-avatar {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: #f3f4f6;
  display: flex;
  align-items: center;
  justify-content: center;
}

.email-row.is-incoming .row-avatar {
  background: #dbeafe;
}

.email-row.is-outgoing .row-avatar {
  background: #d1fae5;
}

.avatar-letter {
  font-size: 14px;
  font-weight: 600;
  color: #6b7280;
}

.email-row.is-incoming .avatar-letter {
  color: #1d4ed8;
}

.email-row.is-outgoing .avatar-letter {
  color: #065f46;
}

/* 行内容 */
.row-content {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.row-top {
  display: flex;
  align-items: center;
  gap: 8px;
}

.row-sender {
  font-size: 13px;
  font-weight: 500;
  color: #374151;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 200px;
}

.row-direction {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
}

.row-direction.dir-in {
  color: #3b82f6;
}

.row-direction.dir-out {
  color: #10b981;
}

.row-date {
  font-size: 12px;
  color: #9ca3af;
  white-space: nowrap;
  flex-shrink: 0;
}

.row-date-wrapper {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.row-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  opacity: 0;
  transition: opacity 0.15s;
  flex-shrink: 0;
}

.email-row:hover .row-actions {
  opacity: 1;
}

.delete-btn {
  width: 28px;
  height: 28px;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: #9ca3af;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s;
}

.delete-btn:hover {
  background: #fee2e2;
  color: #dc2626;
}

.restore-btn {
  width: 28px;
  height: 28px;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: #9ca3af;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s;
}

.restore-btn:hover {
  background: #d1fae5;
  color: #10b981;
}

.row-subject {
  font-size: 13px;
  color: #374151;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: 450;
}

/* ====== 分页 ====== */
.list-pagination {
  display: flex;
  justify-content: center;
  padding: 12px;
  border-top: 1px solid #f0f0f0;
  flex-shrink: 0;
}

/* ====== 预览抽屉 ====== */
.preview-wrapper {
  display: flex;
  flex-direction: column;
}

.preview-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 80px 0;
}

/* Activity 评论区 */
.activity-wrapper {
  padding: 0 32px;
  margin-top: 24px;
}

/* 抽屉内工具栏 */
.drawer-toolbar {
  padding: 8px 32px;
  background: #fff;
  z-index: 10;
  display: flex;
}
/* 用 margin-left:auto 将 n-space 推到右侧 */
.drawer-toolbar :deep(.n-space) {
  margin-left: auto;
}

/* ====== 响应式 ====== */
@media (max-width: 768px) {
  .page-header {
    padding: 12px 16px;
  }

  .header-left h2 {
    font-size: 17px;
  }

  .filter-bar {
    height: 45px;
    padding: 0 16px;
  }

  .filter-tab {
    padding: 10px 12px;
    font-size: 12px;
  }

  .email-row {
    padding: 12px 16px;
  }

  .row-sender {
    max-width: 120px;
  }
}

@media (min-width: 769px) and (max-width: 1024px) {
  .page-header {
    padding: 14px 20px;
  }

  .email-row {
    padding: 12px 12px 12px 16px;
  }
}
</style>
