<template>
  <div style="max-width: 1200px;">
    <div style="margin-bottom: 20px;">
      <h1 style="margin: 0 0 4px; font-size: 20px; font-weight: 600; color: #111827;">表单提交</h1>
      <p style="margin: 0; font-size: 13px; color: #9ca3af;">查看、编辑、回复、删除客户提交的联系留言和定制咨询</p>
    </div>

    <NSpace vertical :size="16">
      <NSpace align="center" justify="space-between">
        <NSpace :size="8" align="center">
          <NButtonGroup>
            <NButton
              v-for="tab in tabs" :key="tab.value"
              :type="filterType === tab.value ? 'primary' : 'default'"
              @click="onFilterChange(tab.value)"
            >{{ tab.label }}</NButton>
          </NButtonGroup>
          <NButtonGroup>
            <NButton
              v-for="tab in statusTabs" :key="tab.value"
              :type="filterStatus === tab.value ? 'primary' : 'default'"
              @click="onStatusChange(tab.value)"
            >{{ tab.label }}</NButton>
          </NButtonGroup>
        </NSpace>
        <NInput
          v-model:value="search"
          placeholder="搜索姓名、手机..."
          clearable
          style="width: 240px;"
          @update:value="onSearch"
        />
      </NSpace>

      <NDataTable
        :columns="columns"
        :data="filteredList"
        :loading="loading"
        :row-key="row => row.id"
        :bordered="false"
        :single-line="false"
      />

      <NSpace justify="end" v-if="totalPages > 1">
        <NPagination
          :page="page"
          :page-count="totalPages"
          :page-size="20"
          @update:page="onPageChange"
        />
      </NSpace>
    </NSpace>

    <!-- 详情抽屉 -->
    <NDrawer v-model:show="drawerVisible" :width="520">
      <NDrawerContent title="提交详情" closable>
        <template v-if="currentItem">
          <NDescriptions bordered :column="1" label-placement="left" size="small">
            <NDescriptionsItem label="ID">{{ currentItem.id }}</NDescriptionsItem>
            <NDescriptionsItem label="类型">
              <NTag :type="currentItem.type === 'contact' ? 'info' : 'warning'" size="small">
                {{ currentItem.type === 'contact' ? '留言' : '定制' }}
              </NTag>
            </NDescriptionsItem>
            <NDescriptionsItem label="姓名">{{ currentItem.data?.name }}</NDescriptionsItem>
            <NDescriptionsItem label="手机">{{ currentItem.data?.phone }}</NDescriptionsItem>
            <NDescriptionsItem label="邮箱" v-if="currentItem.data?.email">{{ currentItem.data?.email }}</NDescriptionsItem>
            <NDescriptionsItem label="微信" v-if="currentItem.data?.wechat">{{ currentItem.data?.wechat }}</NDescriptionsItem>
            <NDescriptionsItem label="内容">
              <div style="white-space: pre-wrap;">{{ currentItem.data?.message || currentItem.data?.remarks || '(无)' }}</div>
            </NDescriptionsItem>
            <NDescriptionsItem label="状态">
              <NSpace :size="4">
                <NTag :type="statusTag(currentItem).type" size="small">{{ statusTag(currentItem).label }}</NTag>
                <NTag v-if="currentItem.repliedAt" type="default" size="small">
                  回复于 {{ formatTime(currentItem.repliedAt) }}
                </NTag>
              </NSpace>
            </NDescriptionsItem>
            <NDescriptionsItem label="提交时间">{{ formatTime(currentItem.createdAt) }}</NDescriptionsItem>
            <NDescriptionsItem label="IP" v-if="currentItem.ip">{{ currentItem.ip }}</NDescriptionsItem>
          </NDescriptions>
          <template v-if="extraFields.length > 0">
            <h4 style="margin: 16px 0 8px;">其他信息</h4>
            <NDescriptions bordered :column="1" label-placement="left" size="small">
              <NDescriptionsItem v-for="field in extraFields" :key="field.key" :label="field.key">
                {{ field.value }}
              </NDescriptionsItem>
            </NDescriptions>
          </template>
        </template>
        <template #footer>
          <NSpace>
            <NButton
              v-if="currentItem && !currentItem.read"
              @click="markRead(currentItem)"
            >标记已读</NButton>
            <NButton
              v-if="currentItem && !currentItem.replied"
              type="primary"
              @click="markReplied(currentItem)"
            >标记已回复</NButton>
            <NButton
              v-if="currentItem && currentItem.replied"
              @click="unmarkReplied(currentItem)"
            >撤销已回复</NButton>
            <NButton @click="openEdit(currentItem)">编辑</NButton>
          </NSpace>
        </template>
      </NDrawerContent>
    </NDrawer>

    <!-- 编辑弹窗 -->
    <NModal v-model:show="editVisible" preset="card" title="编辑提交" style="width: 540px;">
      <NForm
        ref="editFormRef"
        :model="editForm"
        :rules="editRules"
        label-placement="left"
        label-width="70"
      >
        <NFormItem label="姓名" path="name">
          <NInput v-model:value="editForm.name" placeholder="姓名" />
        </NFormItem>
        <NFormItem label="手机" path="phone">
          <NInput v-model:value="editForm.phone" placeholder="11 位手机号" />
        </NFormItem>
        <NFormItem label="邮箱">
          <NInput v-model:value="editForm.email" placeholder="可选" />
        </NFormItem>
        <NFormItem label="微信">
          <NInput v-model:value="editForm.wechat" placeholder="可选" />
        </NFormItem>
        <NFormItem label="内容">
          <NInput
            v-model:value="editForm.message"
            type="textarea"
            :rows="4"
            placeholder="留言内容 / 备注"
          />
        </NFormItem>
      </NForm>
      <template #footer>
        <NSpace justify="end">
          <NButton @click="editVisible = false">取消</NButton>
          <NButton type="primary" :loading="saving" @click="saveEdit">保存</NButton>
        </NSpace>
      </template>
    </NModal>
  </div>
</template>

<script setup>
import {
  NButton, NTag, NDataTable, NInput, NSpace, NDrawer, NDrawerContent,
  NDescriptions, NDescriptionsItem, NButtonGroup, NPagination,
  NModal, NForm, NFormItem, useDialog, useMessage
} from 'naive-ui'

definePageMeta({ layout: 'admin', middleware: 'admin' })
const { adminFetch } = useAdmin()
const message = useMessage()
const dialog = useDialog()

const list = ref([])
const total = ref(0)
const page = ref(1)
const totalPages = ref(1)
const loading = ref(false)
const search = ref('')
const filterType = ref('')
const filterStatus = ref('')
const drawerVisible = ref(false)
const currentItem = ref(null)
const editVisible = ref(false)
const editFormRef = ref(null)
const saving = ref(false)
const editingId = ref(null)
const editForm = reactive({ name: '', phone: '', email: '', wechat: '', message: '' })

const editRules = {
  name: { required: true, message: '请输入姓名', trigger: 'blur' },
  phone: {
    required: true,
    trigger: 'blur',
    validator(_rule, v) {
      if (!v) return new Error('请输入手机号')
      if (!/^\d{6,15}$/.test(v)) return new Error('手机号格式不正确')
      return true
    }
  }
}

const tabs = [
  { label: '全部类型', value: '' },
  { label: '留言', value: 'contact' },
  { label: '定制', value: 'customize' },
]
const statusTabs = [
  { label: '全部状态', value: '' },
  { label: '未读', value: 'unread' },
  { label: '已读未回', value: 'read' },
  { label: '已回复', value: 'replied' },
]

const filteredList = computed(() => {
  if (!filterStatus.value) return list.value
  return list.value.filter(r => {
    if (filterStatus.value === 'unread') return !r.read && !r.replied
    if (filterStatus.value === 'read') return r.read && !r.replied
    if (filterStatus.value === 'replied') return r.replied
    return true
  })
})

const extraFields = computed(() => {
  if (!currentItem.value?.data) return []
  const knownKeys = ['name', 'phone', 'email', 'wechat', 'message', 'remarks']
  return Object.entries(currentItem.value.data)
    .filter(([k]) => !knownKeys.includes(k))
    .map(([key, value]) => ({ key, value: typeof value === 'object' ? JSON.stringify(value) : String(value) }))
})

function formatTime(t) {
  if (!t) return ''
  return t.slice(0, 16).replace('T', ' ')
}

function statusTag(row) {
  if (row.replied) return { type: 'success', label: '已回复' }
  if (row.read) return { type: 'info', label: '已读' }
  return { type: 'warning', label: '未读' }
}

const columns = [
  {
    title: 'ID', key: 'id', width: 60,
    render: (row) => h('span', { style: 'color: #9ca3af; font-size: 12px;' }, row.id)
  },
  {
    title: '类型', key: 'type', width: 70,
    render: (row) => h(NTag, {
      type: row.type === 'contact' ? 'info' : 'warning',
      size: 'small',
    }, () => row.type === 'contact' ? '留言' : '定制')
  },
  {
    title: '姓名', key: 'name', width: 100,
    render: (row) => row.data?.name || ''
  },
  {
    title: '手机', key: 'phone', width: 130,
    render: (row) => h('span', { style: 'color: #9ca3af; font-size: 12px;' }, row.data?.phone || '')
  },
  {
    title: '内容', key: 'message', ellipsis: { tooltip: true },
    render: (row) => {
      const msg = row.data?.message || row.data?.remarks || ''
      return h('span', { style: 'color: #9ca3af; font-size: 12px;' }, msg.length > 50 ? msg.slice(0, 50) + '...' : msg)
    }
  },
  {
    title: '提交时间', key: 'createdAt', width: 150,
    render: (row) => h('span', { style: 'color: #9ca3af; font-size: 12px;' }, formatTime(row.createdAt))
  },
  {
    title: '状态', key: 'status', width: 80,
    render: (row) => {
      const s = statusTag(row)
      return h(NTag, { type: s.type, size: 'small' }, () => s.label)
    }
  },
  {
    title: '操作', key: 'actions', width: 260,
    render(row) {
      return h(NSpace, { size: 4 }, () => [
        h(NButton, { size: 'small', quaternary: true, type: 'info', onClick: () => openDetail(row) }, () => '查看'),
        h(NButton, { size: 'small', quaternary: true, onClick: () => openEdit(row) }, () => '编辑'),
        !row.replied
          ? h(NButton, { size: 'small', quaternary: true, type: 'primary', onClick: () => markReplied(row) }, () => '标记已回复')
          : h(NButton, { size: 'small', quaternary: true, onClick: () => unmarkReplied(row) }, () => '撤销回复'),
        h(NButton, { size: 'small', quaternary: true, type: 'error', onClick: () => confirmDelete(row) }, () => '删除'),
      ])
    }
  },
]

let searchTimer = null
async function loadData() {
  loading.value = true
  try {
    let url = `/api/admin/submissions?page=${page.value}&limit=20&search=${encodeURIComponent(search.value)}`
    if (filterType.value) url += `&type=${filterType.value}`
    const d = await adminFetch(url)
    list.value = d.items
    total.value = d.total
    totalPages.value = d.totalPages
  } catch (e) {
    message.error('加载失败')
  } finally {
    loading.value = false
  }
}

function onSearch() {
  clearTimeout(searchTimer)
  searchTimer = setTimeout(() => {
    page.value = 1
    loadData()
  }, 300)
}

function onPageChange(p) {
  page.value = p
  loadData()
}

function onFilterChange(type) {
  filterType.value = type
  page.value = 1
  loadData()
}

function onStatusChange(status) {
  filterStatus.value = status
}

function openDetail(row) {
  currentItem.value = row
  drawerVisible.value = true
  // 查看即标记已读
  if (!row.read) markRead(row, { silent: true })
}

function openEdit(row) {
  editingId.value = row.id
  editForm.name = row.data?.name || ''
  editForm.phone = row.data?.phone || ''
  editForm.email = row.data?.email || ''
  editForm.wechat = row.data?.wechat || ''
  editForm.message = row.data?.message || row.data?.remarks || ''
  editVisible.value = true
}

async function saveEdit() {
  if (!editFormRef.value) return
  try {
    await editFormRef.value.validate()
  } catch (e) {
    return
  }
  saving.value = true
  try {
    const row = list.value.find(r => r.id === editingId.value)
    if (!row) {
      message.error('记录不存在')
      editVisible.value = false
      return
    }
    // 合并：保留其它 data 字段，只覆盖已编辑字段
    const nextData = { ...(row.data || {}) }
    nextData.name = editForm.name
    nextData.phone = editForm.phone
    if (editForm.email !== undefined) nextData.email = editForm.email
    if (editForm.wechat !== undefined) nextData.wechat = editForm.wechat
    // message 字段：原始用 message 或 remarks，按原来有哪个更新哪个
    if ('remarks' in nextData && !('message' in nextData)) {
      nextData.remarks = editForm.message
    } else {
      nextData.message = editForm.message
    }

    const updated = await adminFetch(`/api/admin/submissions/${editingId.value}`, {
      method: 'PUT',
      body: { data: nextData },
    })
    Object.assign(row, updated)
    if (currentItem.value?.id === editingId.value) currentItem.value = updated
    message.success('已保存')
    editVisible.value = false
  } catch (e) {
    message.error('保存失败：' + (e.data?.message || e.message || '未知错误'))
  } finally {
    saving.value = false
  }
}

async function markRead(row, opts = {}) {
  try {
    await adminFetch(`/api/admin/submissions/${row.id}`, {
      method: 'PUT',
      body: { read: true },
    })
    row.read = true
    if (!opts.silent) message.success('已标记为已读')
  } catch (e) {
    if (!opts.silent) message.error('操作失败')
  }
}

async function markReplied(row) {
  try {
    const updated = await adminFetch(`/api/admin/submissions/${row.id}`, {
      method: 'PUT',
      body: { replied: true },
    })
    Object.assign(row, updated)
    if (currentItem.value?.id === row.id) currentItem.value = updated
    message.success('已标记为已回复')
  } catch (e) {
    message.error('操作失败')
  }
}

async function unmarkReplied(row) {
  try {
    const updated = await adminFetch(`/api/admin/submissions/${row.id}`, {
      method: 'PUT',
      body: { replied: false },
    })
    Object.assign(row, updated)
    if (currentItem.value?.id === row.id) currentItem.value = updated
    message.success('已撤销回复')
  } catch (e) {
    message.error('操作失败')
  }
}

function confirmDelete(row) {
  dialog.warning({
    title: '确认删除',
    content: `确定要删除来自「${row.data?.name || '匿名'}」(ID ${row.id}) 的提交记录吗？此操作不可恢复。`,
    positiveText: '删除',
    negativeText: '取消',
    onPositiveClick: async () => {
      try {
        await adminFetch(`/api/admin/submissions/${row.id}`, { method: 'DELETE' })
        list.value = list.value.filter(r => r.id !== row.id)
        if (currentItem.value?.id === row.id) {
          drawerVisible.value = false
          currentItem.value = null
        }
        total.value = Math.max(0, total.value - 1)
        message.success('已删除')
      } catch (e) {
        message.error('删除失败')
      }
    }
  })
}

onMounted(loadData)
</script>
