<script setup lang="ts">
/**
 * 财务票据中心 — 灵魂级 UX 重构
 * Tab 1: 统一票据池（报销/客户分流 + 拖拽上传 + AI 解析）
 * Tab 2: 购物车式新建报销（AI 一键生成草稿）
 * Tab 3: 报销大盘与审批（A4 打印 + Excel 导出 + 审批态只读）
 */
import { ref, reactive, computed, onMounted, onBeforeUnmount, nextTick, watch } from 'vue'
import { Search, Plus, Delete, View, Check, Close, RefreshLeft, Download, Printer, Link } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance, FormRules, UploadFile } from 'element-plus'
import request from '@/api/request'
import { useUserStore } from '@/store/user'
import { useRoute } from 'vue-router'

const userStore = useUserStore()
const route = useRoute()
// 支持 /finance?tab=dashboard 直接跳到报销大盘
const activeTab = ref((route.query.tab as string) || 'pool')

// ════════════════════════════════════════════════════════
// Tab 1: 统一票据池（报销/客户 两 Tab 分流）
// ════════════════════════════════════════════════════════
const invCategory = ref('expense')
const invLoading = ref(false)
const invList = ref<any[]>([])
const invTotal = ref(0)
const invPage = ref(1)
const invSize = ref(20)
const invUsedFilter = ref('' as '' | 'true' | 'false')

const fetchInvoices = async () => {
  invLoading.value = true
  try {
    const params: Record<string, any> = { page: invPage.value, size: invSize.value, category: invCategory.value }
    if (invUsedFilter.value !== '') params.is_used = invUsedFilter.value
    const data: any = await request.get('/api/finance/invoices', { params })
    invList.value = data?.items || []
    invTotal.value = data?.total || 0
  } catch {}
  finally { invLoading.value = false }
}

watch(invCategory, () => { invPage.value = 1; fetchInvoices() })

// ── 拖拽上传 + AI 解析链路（批量队列） ──
const uploadProcessing = ref(false)
const aiParsing = ref(false)

interface QueueItem {
  name: string
  status: 'waiting' | 'processing' | 'success' | 'error'
  message: string
}
const uploadQueue = ref<QueueItem[]>([])
let uploadAbortController: AbortController | null = null

const handleUploadChange = async (_file: UploadFile, fileList: any[]) => {
  // 收集所有新增文件的 raw
  const rawFiles = fileList.filter((f: any) => f.raw).map((f: any) => f.raw as File)
  if (!rawFiles.length) return

  // 初始化队列
  uploadQueue.value = rawFiles.map(f => ({ name: f.name, status: 'waiting' as const, message: '' }))
  uploadProcessing.value = true
  uploadAbortController = new AbortController()
  const signal = uploadAbortController.signal

  for (let i = 0; i < rawFiles.length; i++) {
    if (signal.aborted) break

    const file = rawFiles[i]
    uploadQueue.value[i].status = 'processing'
    uploadQueue.value[i].message = '🤖 AI 正在解析...'

    try {
      const formData = new FormData()
      formData.append('file', file)
      formData.append('scene', 'invoice')

      const response = await fetch('/api/finance/ocr', {
        method: 'POST',
        headers: { 'Authorization': `Bearer ${userStore.token}` },
        body: formData,
        signal,
      })

      if (!response.ok) throw new Error(`HTTP ${response.status}`)
      const result = await response.json()
      if (result.code !== 200) throw new Error(result.message || 'OCR 识别失败')

      const ocrResult = result.data || {}
      const aiData = ocrResult.ocr_data || {}
      const fileUrl = ocrResult.file_url || `/uploads/${file.name}`

      const ocrSuccess = !!(aiData.merchant || aiData.merchant_name || aiData.amount)
      const merchant = aiData.merchant || aiData.merchant_name || '（AI 未识别）'
      const amount = parseFloat(aiData.amount) || 0
      const invoiceDate = aiData.date || new Date().toISOString().slice(0, 10)

      await request.post('/api/finance/invoices', {
        merchant_name: merchant, amount, invoice_date: invoiceDate,
        type: invCategory.value, file_url: fileUrl, ai_extracted_data: aiData,
      })

      uploadQueue.value[i].status = 'success'
      uploadQueue.value[i].message = ocrSuccess
        ? `✅ ${merchant} ￥${amount}`
        : '⚠️ 已上传，AI未能识别'
    } catch (e: any) {
      if (e.name === 'AbortError') break
      uploadQueue.value[i].status = 'error'
      uploadQueue.value[i].message = `❌ ${e.message || '处理失败'}`
    }
  }

  uploadProcessing.value = false
  uploadAbortController = null
  if (!signal.aborted) {
    const successCount = uploadQueue.value.filter(q => q.status === 'success').length
    ElMessage.success(`批量处理完成：${successCount}/${rawFiles.length} 成功`)
    fetchInvoices()
  }

  // 3秒后清空队列
  setTimeout(() => { uploadQueue.value = [] }, 3000)
}

// 手动录入弹窗
const invDialogVisible = ref(false)
const invSubmitting = ref(false)
const invFormRef = ref<FormInstance>()
const invForm = reactive({ merchant_name: '', amount: 0, invoice_date: '', ai_json: '' })
const invRules = reactive<FormRules>({
  merchant_name: [{ required: true, message: '请输入开票方', trigger: 'blur' }],
  amount: [{ required: true, message: '请输入金额', trigger: 'blur' }],
})

const openAddInvoice = () => {
  Object.assign(invForm, { merchant_name: '', amount: 0, invoice_date: '', ai_json: '' })
  invDialogVisible.value = true
  nextTick(() => invFormRef.value?.clearValidate())
}

const submitInvoice = async () => {
  const valid = await invFormRef.value?.validate().catch(() => false)
  if (!valid) return
  invSubmitting.value = true
  try {
    let aiData = {}
    if (invForm.ai_json.trim()) {
      try { aiData = JSON.parse(invForm.ai_json) } catch { ElMessage.error('JSON 格式错误'); invSubmitting.value = false; return }
    }
    await request.post('/api/finance/invoices', {
      merchant_name: invForm.merchant_name, amount: invForm.amount,
      invoice_date: invForm.invoice_date || null, type: invCategory.value,
      ai_extracted_data: aiData,
    })
    ElMessage.success('发票录入成功'); invDialogVisible.value = false; fetchInvoices()
  } catch {}
  finally { invSubmitting.value = false }
}

const voidInvoice = (row: any) => {
  ElMessageBox.confirm(`确定作废「${row.merchant_name}」(￥${row.amount})？`, '作废确认', { type: 'warning' })
    .then(async () => { try { await request.delete(`/api/finance/invoices/${row.id}`); ElMessage.success('已作废'); fetchInvoices() } catch {} }).catch(() => {})
}

const linkOrder = () => { ElMessage.info('🔗 关联订单功能为远期规划，敬请期待') }

// ════════════════════════════════════════════════════════
// Tab 2: 购物车式新建报销（AI 一键生成草稿）
// ════════════════════════════════════════════════════════
const availableInvLoading = ref(false)
const availableInvList = ref<any[]>([])
const leftSelection = ref<any[]>([])

const fetchAvailableInvoices = async () => {
  availableInvLoading.value = true
  try {
    const data: any = await request.get('/api/finance/invoices', { params: { page: 1, size: 100, is_used: false, category: 'expense' } })
    availableInvList.value = data?.items || []
  } catch {}
  finally { availableInvLoading.value = false }
}

interface CartItem {
  invoice_id: string; merchant_name: string; invoice_amount: number
  expense_desc: string; expense_date: string; original_type: string; offset_type: string; amount: number
}
const cart = ref<CartItem[]>([])
const expRemark = ref('')
const expSubmitting = ref(false)
const cartTotal = computed(() => cart.value.reduce((s, r) => s + r.amount, 0))

const originalTypes = [
  { label: '办公费', value: '办公费' }, { label: '招待费', value: '招待费' },
  { label: '差旅费', value: '差旅费' }, { label: '交通费', value: '交通费' },
  { label: '物流费', value: '物流费' }, { label: '油费', value: '油费' },
  { label: '其他', value: '其他' },
]
const offsetTypes = [
  { label: '客户费用', value: '客户费用' }, { label: '税务费用', value: '税务费用' },
  { label: '工资提成', value: '工资提成' }, { label: '办公费', value: '办公费' },
  { label: '招待费', value: '招待费' }, { label: '差旅费', value: '差旅费' },
  { label: '交通费', value: '交通费' }, { label: '物流费', value: '物流费' },
  { label: '油费', value: '油费' }, { label: '福利费', value: '福利费' },
  { label: '其他', value: '其他' },
]

// AI 一键生成报销草稿
const aiGenerating = ref(false)
const aiGenerateDraft = async () => {
  if (!leftSelection.value.length) { ElMessage.warning('请先勾选需要报销的发票'); return }
  aiGenerating.value = true
  await new Promise(r => setTimeout(r, 800))
  for (const inv of leftSelection.value) {
    if (cart.value.find(c => c.invoice_id === inv.id)) continue
    const ai = inv.ai_extracted_data || {}
    cart.value.push({
      invoice_id: inv.id,
      merchant_name: ai.merchant || inv.merchant_name || '-',
      invoice_amount: ai.amount || inv.amount,
      expense_desc: '',
      expense_date: ai.date || inv.invoice_date || new Date().toISOString().slice(0, 10),
      original_type: '办公费',
      offset_type: '客户费用',
      amount: ai.amount || inv.amount,
    })
  }
  aiGenerating.value = false
  ElMessage.success(`🤖 已智能生成 ${leftSelection.value.length} 条报销草稿`)
}

const removeCartItem = (idx: number) => { cart.value.splice(idx, 1) }

const submitExpense = async () => {
  if (!cart.value.length) { ElMessage.warning('请先勾选发票生成草稿'); return }
  if (cart.value.some(r => r.amount <= 0)) { ElMessage.warning('报销金额必须大于 0'); return }
  try { await ElMessageBox.confirm(`确认提交？总金额 ￥${cartTotal.value.toFixed(2)}`, '提交确认', { type: 'info' }) } catch { return }
  expSubmitting.value = true
  try {
    await request.post('/api/finance/expenses', {
      total_amount: cartTotal.value, remark: expRemark.value || null,
      items: cart.value.map(r => ({
        invoice_id: r.invoice_id, expense_desc: r.expense_desc || null,
        expense_date: r.expense_date || null,
        original_type: r.original_type, offset_type: r.offset_type, amount: r.amount,
      })),
    })
    ElMessage.success('报销单提交成功！'); cart.value = []; expRemark.value = ''
    fetchAvailableInvoices(); activeTab.value = 'expenses'; fetchExpenses()
  } catch {}
  finally { expSubmitting.value = false }
}

// ════════════════════════════════════════════════════════
// Tab 3: 报销大盘（审批 + 打印 + 导出）
// ════════════════════════════════════════════════════════
const expLoading = ref(false)
const expList = ref<any[]>([])
const expTotal = ref(0)
const expPage = ref(1)
const expSize = ref(20)
const expStatusFilter = ref('')

const fetchExpenses = async () => {
  expLoading.value = true
  try {
    const params: Record<string, any> = { page: expPage.value, size: expSize.value }
    if (expStatusFilter.value) params.status = expStatusFilter.value
    const data: any = await request.get('/api/finance/expenses', { params })
    expList.value = data?.items || []
    expTotal.value = data?.total || 0
  } catch {}
  finally { expLoading.value = false }
}

const expDetailVisible = ref(false)
const expDetailLoading = ref(false)
const currentExp = ref<any>({})

const openExpDetail = async (row: any) => {
  expDetailVisible.value = true; expDetailLoading.value = true
  try { const data: any = await request.get(`/api/finance/expenses/${row.id}`); currentExp.value = data } catch {}
  finally { expDetailLoading.value = false }
}

const statusLabel = (s: string) => ({ submitted: '待审批', approved: '已通过', rejected: '已驳回', voided: '已撤回' }[s] || s)
const statusTagType = (s: string) => ({ submitted: 'warning', approved: 'success', rejected: 'danger', voided: 'info' }[s] || 'info')
const canWithdraw = (row: any) => row.status === 'submitted' && row.applicant_id === userStore.userInfo?.user_id
const canApprove = (row: any) => row.status === 'submitted' && (userStore.dataScope === 'all' || userStore.dataScope === 'dept_and_sub')
const isApprover = computed(() => userStore.dataScope === 'all' || userStore.dataScope === 'dept_and_sub')

const doAction = async (expenseId: string, action: string, label: string) => {
  let reason: string | null = null
  try {
    if (action === 'reject') {
      const res: any = await ElMessageBox.prompt('请输入驳回原因', '驳回', { confirmButtonText: '确认驳回', cancelButtonText: '取消', type: 'warning' })
      reason = res.value
    } else {
      await ElMessageBox.confirm(`确定${label}？`, '操作确认', { type: action === 'approve' ? 'success' : 'warning' })
    }
  } catch { return }
  try {
    await request.put(`/api/finance/expenses/${expenseId}/status`, { action, reason })
    ElMessage.success(`${label}成功`); fetchExpenses()
    if (expDetailVisible.value && currentExp.value.id === expenseId) openExpDetail({ id: expenseId })
  } catch {}
}

// ── A4 打印（独立 Iframe 无损排版） ──
const printExpense = async (row?: any) => {
  let expData = currentExp.value
  if (row && row.id && row.id !== currentExp.value.id) {
    try {
      const data: any = await request.get(`/api/finance/expenses/${row.id}`)
      expData = data
    } catch { return }
  } else if (!expData.id && row && row.id) {
    // maybe list row is passed directly but detail isn't open
    try {
      const data: any = await request.get(`/api/finance/expenses/${row.id}`)
      expData = data
    } catch { return }
  }
  if (!expData || !expData.id) {
    ElMessage.warning('未能获取打印数据')
    return
  }

  const fCurrency = (v: number) => `￥${v?.toLocaleString('zh-CN', { minimumFractionDigits: 2 })}`;
  const sLabel = (s: string) => ({ submitted: '待审批', approved: '已通过', rejected: '已驳回', voided: '已撤回' }[s] || s);

  const rowsHtml = (expData.details || []).map((d: any, i: number) => `
    <tr>
      <td>${i + 1}</td>
      <td style="text-align:left">${d.invoice_merchant || ''}</td>
      <td>${fCurrency(d.invoice_amount || 0)}</td>
      <td style="text-align:left">${d.expense_desc || '-'}</td>
      <td>${d.expense_date || '-'}</td>
      <td>${d.original_type || '-'}</td>
      <td>${d.offset_type || '-'}</td>
      <td>${fCurrency(d.amount)}</td>
    </tr>
  `).join('');

  const html = `<!DOCTYPE html>
<html>
<head>
  <title>打印报销单</title>
  <style>
    @page { size: A4; margin: 15mm; }
    body { font-family: 'SimSun', 'Songti SC', serif; color: #000; margin: 0; padding: 0; }
    .print-header { text-align: center; margin-bottom: 20px; }
    .print-header h1 { font-size: 24px; margin: 0 0 8px; letter-spacing: 6px; }
    .print-meta { text-align: center; font-size: 13px; color: #333; margin-bottom: 20px; }
    .print-meta span { margin: 0 16px; }
    table { width: 100%; border-collapse: collapse; margin-bottom: 16px; font-size: 13px; }
    th, td { border: 1px solid #000; padding: 6px 10px; text-align: center; }
    .info-table td:nth-child(odd) { background: #f0f0f0; font-weight: bold; width: 90px; }
    th { background: #e0e0e0; }
    tfoot td { border-top: 2px solid #000; }
    .signatures { display: flex; justify-content: space-between; margin-top: 50px; font-weight: bold; font-size: 14px; }
  </style>
</head>
<body>
  <div class="print-header">
    <h1>天津硕博霖报销单</h1>
    <div class="print-meta">
      <span>单号：${expData.system_no}</span>
      <span>日期：${expData.created_at?.slice(0, 10)}</span>
    </div>
  </div>
  <table class="info-table">
    <tr>
      <td>申请人</td><td>${expData.applicant_name}</td>
      <td>报销总额</td><td>${fCurrency(expData.total_amount)}</td>
    </tr>
    <tr>
      <td>审批状态</td><td>${sLabel(expData.status)}</td>
      <td>备注</td><td>${expData.remark || '-'}</td>
    </tr>
  </table>
  <table>
    <thead>
      <tr><th>#</th><th>开票方</th><th>发票金额</th><th>费用描述</th><th>发生时间</th><th>原始种类</th><th>冲顶类型</th><th>报销金额</th></tr>
    </thead>
    <tbody>
      ${rowsHtml}
    </tbody>
    <tfoot>
      <tr>
        <td colspan="7" style="text-align:right; font-weight:bold">合计</td>
        <td style="font-weight:bold">${fCurrency(expData.total_amount)}</td>
      </tr>
    </tfoot>
  </table>
  <div class="signatures">
    <span>本人签字：___________</span>
    <span>部门领导签字：___________</span>
    <span>财务签字：___________</span>
    <span>总经理签字：___________</span>
  </div>
</body>
</html>`;

  const iframe = document.createElement('iframe');
  iframe.style.display = 'none';
  document.body.appendChild(iframe);
  const iframeDoc = iframe.contentWindow?.document;
  if (iframeDoc) {
    iframeDoc.open();
    iframeDoc.write(html);
    iframeDoc.close();
    setTimeout(() => {
      iframe.contentWindow?.focus();
      iframe.contentWindow?.print();
      setTimeout(() => document.body.removeChild(iframe), 1000);
    }, 200);
  }
}

const exportExcel = async () => {
  if (!expList.value.length) { ElMessage.warning('暂无数据可导出'); return }
  ElMessage.info('正在拉取明细数据，请稍候...')
  
  const BOM = '\uFEFF'
  const header = '报销单号,申请人,报销总金额,状态,提交时间,备注,明细-开票方,明细-发票金额,明细-用途,明细-发生时间,明细-原始种类,明细-冲顶类型,明细-报销额\n'
  let rows = ''
  
  for (const exp of expList.value) {
    try {
      const detailRes: any = await request.get(`/api/finance/expenses/${exp.id}`)
      const baseInfo = `${exp.system_no},${exp.applicant_name},${exp.total_amount},${statusLabel(exp.status)},${exp.created_at},${detailRes.remark || ''}`
      if (detailRes.details && detailRes.details.length > 0) {
        for (const d of detailRes.details) {
          rows += `${baseInfo},${d.invoice_merchant || ''},${d.invoice_amount || 0},${d.expense_desc || ''},${d.expense_date || ''},${d.original_type || ''},${d.offset_type || ''},${d.amount}\n`
        }
      } else {
        rows += `${baseInfo},,,,,,,\n`
      }
    } catch {
      rows += `${exp.system_no},${exp.applicant_name},${exp.total_amount},${statusLabel(exp.status)},${exp.created_at},获取明细失败,,,,,,,\n`
    }
  }

  const blob = new Blob([BOM + header + rows], { type: 'text/csv;charset=utf-8' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url; a.download = `报销大盘_${new Date().toISOString().slice(0, 10)}.csv`; a.click()
  URL.revokeObjectURL(url)
  ElMessage.success('导出成功')
}

const formatCurrency = (v: number) => `￥${v?.toLocaleString('zh-CN', { minimumFractionDigits: 2 })}`

onMounted(() => { fetchInvoices() })
onBeforeUnmount(() => {
  if (uploadAbortController) { uploadAbortController.abort(); uploadAbortController = null }
})
watch(activeTab, (tab) => {
  if (tab === 'create') fetchAvailableInvoices()
  if (tab === 'expenses') fetchExpenses()
})
</script>

<template>
  <div class="finance-wrapper">
    <el-card shadow="never" class="main-card hide-on-print">
      <el-tabs v-model="activeTab" class="finance-tabs">

        <!-- ═══════ Tab 1: 统一票据池 ═══════ -->
        <el-tab-pane label="🎫 统一票据池" name="pool">
          <!-- 报销票据池 -->
          <div class="inv-sub-header" style="margin-bottom: 8px; font-size: 14px; color: #606266; font-weight: 500;">📄 报销发票池</div>

          <!-- 拖拽上传区（支持多文件） -->
          <div class="upload-zone">
            <el-upload drag :auto-upload="false" :show-file-list="false" accept=".pdf,.jpg,.jpeg,.png"
              multiple @change="handleUploadChange">
              <div class="upload-inner">
                <el-icon style="font-size:40px; color:#409eff"><Plus /></el-icon>
                <div class="upload-text">拖拽发票文件到此处，或 <em>点击上传</em></div>
                <div class="upload-hint">支持 PDF / JPG / PNG / MD，可一次选择多个文件批量上传，AI 自动排队解析</div>
              </div>
            </el-upload>
            <!-- 批量上传队列状态 -->
            <div v-if="uploadQueue.length" class="upload-queue">
              <div v-for="(item, idx) in uploadQueue" :key="idx" class="queue-item">
                <span class="queue-name">{{ item.name }}</span>
                <el-tag v-if="item.status === 'waiting'" size="small" type="info" effect="plain">等待中</el-tag>
                <el-tag v-else-if="item.status === 'processing'" size="small" type="warning" effect="dark">处理中...</el-tag>
                <el-tag v-else-if="item.status === 'success'" size="small" type="success" effect="dark">{{ item.message }}</el-tag>
                <el-tag v-else size="small" type="danger" effect="dark">{{ item.message }}</el-tag>
              </div>
            </div>
            <el-button v-if="!uploadQueue.length" type="primary" plain size="small" style="margin-top:8px" @click="openAddInvoice">
              ✏️ 手动录入
            </el-button>
          </div>

          <!-- 筛选 + 列表 -->
          <div class="tab-toolbar">
            <el-form :inline="true" class="filter-form">
              <el-form-item label="使用状态">
                <el-select v-model="invUsedFilter" clearable placeholder="全部" style="width:120px" @change="fetchInvoices">
                  <el-option label="未使用" value="false" /><el-option label="已报销" value="true" />
                </el-select>
              </el-form-item>
              <el-form-item><el-button type="primary" :icon="Search" @click="fetchInvoices">查询</el-button></el-form-item>
            </el-form>
          </div>

          <el-table :data="invList" v-loading="invLoading" stripe border style="width:100%" height="calc(100vh - 480px)">
            <el-table-column prop="merchant_name" label="开票方" min-width="180" show-overflow-tooltip />
            <el-table-column label="票面金额" width="130" align="right">
              <template #default="{ row }"><b style="color:#e6a23c">{{ formatCurrency(row.amount) }}</b></template>
            </el-table-column>
            <el-table-column prop="invoice_date" label="开票日期" width="110" align="center" />
            <el-table-column label="使用状态" width="90" align="center">
              <template #default="{ row }">
                <el-tag size="small" :type="row.is_used ? 'danger' : 'success'" effect="dark">{{ row.is_used ? '已报销' : '未使用' }}</el-tag>
              </template>
            </el-table-column>
            <el-table-column label="AI 提取" width="180" show-overflow-tooltip>
              <template #default="{ row }">
                <el-popover v-if="row.ai_extracted_data && Object.keys(row.ai_extracted_data).length" trigger="hover" width="320" placement="left">
                  <template #reference>
                    <el-tag size="small" type="success" effect="plain" style="cursor:pointer">🤖 查看 AI 数据</el-tag>
                  </template>
                  <pre style="font-size:12px; white-space:pre-wrap; max-height:300px; overflow:auto">{{ JSON.stringify(row.ai_extracted_data, null, 2) }}</pre>
                </el-popover>
                <span v-else style="color:#c0c4cc">-</span>
              </template>
            </el-table-column>
            <el-table-column prop="uploader_name" label="上传人" width="90" align="center" />
            <el-table-column label="操作" width="140" fixed="right">
              <template #default="{ row }">
                <el-button v-if="!row.is_used" type="danger" link :icon="Delete" @click="voidInvoice(row)">作废</el-button>
                <span v-if="row.is_used" style="color:#c0c4cc; font-size:12px">-</span>
              </template>
            </el-table-column>
          </el-table>
          <el-pagination style="margin-top:12px; justify-content:flex-end" background
            layout="total, sizes, prev, pager, next" :total="invTotal" :page-size="invSize" :current-page="invPage"
            :page-sizes="[10, 20, 50]" @current-change="(p: number) => { invPage = p; fetchInvoices() }"
            @size-change="(s: number) => { invSize = s; invPage = 1; fetchInvoices() }" />
        </el-tab-pane>

        <!-- ═══════ Tab 2: 新建报销（AI 一键生成草稿） ═══════ -->
        <el-tab-pane label="📝 新建报销" name="create">
          <el-row :gutter="20">
            <el-col :span="11">
              <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:12px">
                <h4>📋 可用发票（未使用）</h4>
                <el-button type="success" :loading="aiGenerating" @click="aiGenerateDraft">
                  🤖 AI 一键生成报销草稿
                </el-button>
              </div>
              <el-table :data="availableInvList" v-loading="availableInvLoading" stripe border height="450px"
                style="width:100%" @selection-change="(val: any[]) => { leftSelection = val }">
                <el-table-column type="selection" width="42" />
                <el-table-column prop="merchant_name" label="开票方" min-width="140" show-overflow-tooltip />
                <el-table-column label="金额" width="110" align="right">
                  <template #default="{ row }"><b>{{ formatCurrency(row.amount) }}</b></template>
                </el-table-column>
                <el-table-column prop="invoice_date" label="日期" width="100" align="center" />
                <el-table-column label="AI" width="60" align="center">
                  <template #default="{ row }">
                    <el-tag v-if="row.ai_extracted_data && Object.keys(row.ai_extracted_data).length" size="small" type="success" effect="plain">✓</el-tag>
                    <span v-else style="color:#c0c4cc">-</span>
                  </template>
                </el-table-column>
              </el-table>
            </el-col>

            <el-col :span="13">
              <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:12px">
                <h4>🛒 报销草稿</h4>
                <el-statistic title="总金额" :value="cartTotal" :precision="2" prefix="￥" style="text-align:right" />
              </div>
              <el-table :data="cart" border height="340px" style="width:100%">
                <el-table-column type="index" label="#" width="40" />
                <el-table-column prop="merchant_name" label="开票方" min-width="110" show-overflow-tooltip />
                <el-table-column label="票面" width="90" align="right">
                  <template #default="{ row }">{{ formatCurrency(row.invoice_amount) }}</template>
                </el-table-column>
                <el-table-column label="费用描述" min-width="110">
                  <template #default="{ row }">
                    <el-input v-model="row.expense_desc" size="small" placeholder="用途说明" />
                  </template>
                </el-table-column>
                <el-table-column label="发生时间" width="130">
                  <template #default="{ row }">
                    <el-date-picker v-model="row.expense_date" type="date" value-format="YYYY-MM-DD" placeholder="日期" size="small" style="width:100%" />
                  </template>
                </el-table-column>
                <el-table-column label="原始种类" width="110">
                  <template #default="{ row }">
                    <el-select v-model="row.original_type" size="small" style="width:100%">
                      <el-option v-for="t in originalTypes" :key="t.value" :label="t.label" :value="t.value" />
                    </el-select>
                  </template>
                </el-table-column>
                <el-table-column label="冲顶类型" width="110">
                  <template #default="{ row }">
                    <el-select v-model="row.offset_type" size="small" style="width:100%">
                      <el-option v-for="t in offsetTypes" :key="t.value" :label="t.label" :value="t.value" />
                    </el-select>
                  </template>
                </el-table-column>
                <el-table-column label="报销额" width="100">
                  <template #default="{ row }">
                    <el-input-number v-model="row.amount" :min="0.01" :max="row.invoice_amount" :precision="2" size="small" style="width:85px" />
                  </template>
                </el-table-column>
                <el-table-column label="" width="45">
                  <template #default="{ $index }">
                    <el-button type="danger" link :icon="Delete" size="small" @click="removeCartItem($index)" />
                  </template>
                </el-table-column>
              </el-table>
              <el-input v-model="expRemark" type="textarea" :rows="2" placeholder="报销备注（非必填）" style="margin-top:10px" />
              <el-button type="primary" size="large" :loading="expSubmitting" :disabled="!cart.length"
                style="width:100%; margin-top:10px" @click="submitExpense">
                ✅ 提交报销（{{ formatCurrency(cartTotal) }}）
              </el-button>
            </el-col>
          </el-row>
        </el-tab-pane>

        <!-- ═══════ Tab 3: 报销大盘与审批 ═══════ -->
        <el-tab-pane label="📊 报销大盘" name="expenses">
          <div class="tab-toolbar">
            <el-form :inline="true" class="filter-form">
              <el-form-item label="审批状态">
                <el-select v-model="expStatusFilter" clearable placeholder="全部" style="width:130px"
                  @change="() => { expPage = 1; fetchExpenses() }">
                  <el-option label="待审批" value="submitted" /><el-option label="已通过" value="approved" />
                  <el-option label="已驳回" value="rejected" /><el-option label="已撤回" value="voided" />
                </el-select>
              </el-form-item>
              <el-form-item><el-button type="primary" :icon="Search" @click="fetchExpenses">查询</el-button></el-form-item>
            </el-form>
            <el-button type="success" plain :icon="Download" @click="exportExcel">导出 Excel</el-button>
          </div>

          <el-table :data="expList" v-loading="expLoading" stripe border style="width:100%" height="calc(100vh - 350px)">
            <el-table-column prop="system_no" label="报销单号" width="200" fixed="left">
              <template #default="{ row }"><span class="exp-id-bold">{{ row.system_no }}</span></template>
            </el-table-column>
            <el-table-column prop="applicant_name" label="申请人" width="110" align="center" />
            <el-table-column label="报销金额" width="130" align="right">
              <template #default="{ row }"><b style="color:#e6a23c">{{ formatCurrency(row.total_amount) }}</b></template>
            </el-table-column>
            <el-table-column label="状态" width="100" align="center">
              <template #default="{ row }">
                <el-tag :type="(statusTagType(row.status) as any)" effect="dark" size="small">{{ statusLabel(row.status) }}</el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="created_at" label="提交时间" min-width="160" show-overflow-tooltip />
            <el-table-column label="操作" width="280" fixed="right">
              <template #default="{ row }">
                <el-button type="primary" link :icon="View" @click="openExpDetail(row)">详情</el-button>
                <el-button type="primary" link :icon="Printer" @click="printExpense(row)">打印</el-button>
                <el-button v-if="canWithdraw(row)" type="info" link :icon="RefreshLeft" @click="doAction(row.id, 'withdraw', '撤回')">撤回</el-button>
                <el-button v-if="canApprove(row)" type="success" link :icon="Check" @click="doAction(row.id, 'approve', '审批通过')">通过</el-button>
                <el-button v-if="canApprove(row)" type="danger" link :icon="Close" @click="doAction(row.id, 'reject', '驳回')">驳回</el-button>
              </template>
            </el-table-column>
          </el-table>
          <el-pagination style="margin-top:12px; justify-content:flex-end" background
            layout="total, sizes, prev, pager, next" :total="expTotal" :page-size="expSize" :current-page="expPage"
            :page-sizes="[10, 20, 50]" @current-change="(p: number) => { expPage = p; fetchExpenses() }"
            @size-change="(s: number) => { expSize = s; expPage = 1; fetchExpenses() }" />
        </el-tab-pane>
      </el-tabs>
    </el-card>

    <!-- ═══════ 手动录入发票弹窗 ═══════ -->
    <el-dialog v-model="invDialogVisible" title="手动录入发票" width="480px" destroy-on-close class="hide-on-print">
      <el-form ref="invFormRef" :model="invForm" :rules="invRules" label-width="80px">
        <el-form-item label="开票方" prop="merchant_name"><el-input v-model="invForm.merchant_name" /></el-form-item>
        <el-form-item label="票面金额" prop="amount"><el-input-number v-model="invForm.amount" :min="0" :precision="2" style="width:100%" /></el-form-item>
        <el-form-item label="开票日期"><el-date-picker v-model="invForm.invoice_date" type="date" value-format="YYYY-MM-DD" style="width:100%" /></el-form-item>
        <el-form-item label="AI 数据"><el-input v-model="invForm.ai_json" type="textarea" :rows="2" placeholder='JSON（可选）' /></el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="invDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="invSubmitting" @click="submitInvoice">录入</el-button>
      </template>
    </el-dialog>

    <!-- ═══════ 报销单详情 Drawer ═══════ -->
    <el-drawer v-model="expDetailVisible" title="报销单详情" size="700px">
      <div v-loading="expDetailLoading">
        <template v-if="currentExp.id">
          <el-descriptions :column="2" border>
            <el-descriptions-item label="报销单号"><span class="exp-id-bold">{{ currentExp.system_no }}</span></el-descriptions-item>
            <el-descriptions-item label="申请人">{{ currentExp.applicant_name }}</el-descriptions-item>
            <el-descriptions-item label="报销金额"><b style="color:#e6a23c">{{ formatCurrency(currentExp.total_amount) }}</b></el-descriptions-item>
            <el-descriptions-item label="状态">
              <el-tag :type="(statusTagType(currentExp.status) as any)" effect="dark" size="small">{{ statusLabel(currentExp.status) }}</el-tag>
            </el-descriptions-item>
            <el-descriptions-item label="审批人">{{ currentExp.approver_name || '-' }}</el-descriptions-item>
            <el-descriptions-item label="审批时间">{{ currentExp.approved_at || '-' }}</el-descriptions-item>
            <el-descriptions-item label="备注" :span="2">{{ currentExp.remark || '-' }}</el-descriptions-item>
          </el-descriptions>

          <el-divider content-position="left">📋 报销明细</el-divider>
          <el-table :data="currentExp.details || []" border stripe style="width:100%">
            <el-table-column prop="invoice_merchant" label="开票方" min-width="130" show-overflow-tooltip />
            <el-table-column label="发票金额" width="100" align="right">
              <template #default="{ row }">{{ formatCurrency(row.invoice_amount || 0) }}</template>
            </el-table-column>
            <el-table-column prop="original_type" label="原始种类" width="100" align="center" />
            <el-table-column prop="offset_type" label="冲顶类型" width="110" align="center">
              <template #default="{ row }">
                <el-tag v-if="row.offset_type && row.offset_type !== '常规报销'" type="warning" size="small" effect="dark">{{ row.offset_type }}</el-tag>
                <span v-else>{{ row.offset_type || '-' }}</span>
              </template>
            </el-table-column>
            <el-table-column prop="expense_desc" label="说明" min-width="100" show-overflow-tooltip>
              <template #default="{ row }">{{ row.expense_desc || '-' }}</template>
            </el-table-column>
            <el-table-column prop="expense_date" label="发生时间" width="110" align="center">
              <template #default="{ row }">{{ row.expense_date || '-' }}</template>
            </el-table-column>
            <el-table-column label="报销金额" width="100" align="right">
              <template #default="{ row }"><b style="color:#e6a23c">{{ formatCurrency(row.amount) }}</b></template>
            </el-table-column>
          </el-table>

          <div style="margin-top:16px; display:flex; justify-content:space-between">
            <el-button :icon="Printer" @click="printExpense">🖨️ 打印报销汇总单</el-button>
            <div>
              <el-button v-if="canWithdraw(currentExp)" :icon="RefreshLeft" @click="doAction(currentExp.id, 'withdraw', '撤回')">撤回</el-button>
              <el-button v-if="canApprove(currentExp)" type="success" :icon="Check" @click="doAction(currentExp.id, 'approve', '审批通过')">通过</el-button>
              <el-button v-if="canApprove(currentExp)" type="danger" :icon="Close" @click="doAction(currentExp.id, 'reject', '驳回')">驳回</el-button>
            </div>
          </div>
        </template>
      </div>
    </el-drawer>
  </div>
</template>

<style scoped>
.finance-wrapper { height: 100%; }
.main-card { height: calc(100vh - 100px); border-radius: 8px; border: none; box-shadow: 0 1px 4px rgba(0,21,41,0.08); }
.finance-tabs { height: 100%; }
.inv-sub-tabs { margin-bottom: 8px; }
.upload-zone { background: #f5f7fa; border-radius: 8px; padding: 16px; margin-bottom: 12px; text-align: center; }
.upload-inner { padding: 12px 0; }
.upload-text { margin-top: 8px; font-size: 14px; color: #606266; }
.upload-text em { color: #409eff; font-style: normal; cursor: pointer; }
.upload-hint { font-size: 12px; color: #909399; margin-top: 4px; }
.tab-toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.filter-form .el-form-item { margin-bottom: 0; }
.exp-id-bold { font-family: Consolas, 'Courier New', monospace; font-weight: bold; color: #409eff; }
.upload-queue { margin-top: 10px; text-align: left; }
.queue-item { display: flex; justify-content: space-between; align-items: center; padding: 6px 12px; border-bottom: 1px solid #f0f0f0; }
.queue-item:last-child { border-bottom: none; }
.queue-name { font-size: 13px; color: #606266; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 300px; }

</style>
