<template>
  <section class="approval-page">
    <div class="approval-detail">
      <div class="detail-scroll">
        <article class="detail-hero panel">
          <div class="hero-banner">
            <div class="hero-banner-main">
              <div class="applicant-card">
                <div class="portrait">
                  <img src="/assets/person.png" alt="" />
                </div>
                <div class="applicant-copy">
                  <div class="applicant-name-row">
                    <h2>{{ profile.name }}</h2>
                    <span class="identity-badge">{{ profile.identity }}</span>
                  </div>
                  <div class="applicant-profile-meta">
                    <div class="applicant-profile-meta__org">
                      <span class="applicant-meta-item">
                        <em>部门</em>
                        <strong>{{ profile.department }}</strong>
                      </span>
                      <span class="applicant-meta-item applicant-meta-item--sub">
                        <em>直属上司</em>
                        <strong>{{ profile.manager }}</strong>
                      </span>
                    </div>
                    <div class="applicant-profile-meta__role">
                      <span class="applicant-meta-item">
                        <em>职级</em>
                        <strong>{{ profile.grade }}</strong>
                      </span>
                      <span class="applicant-meta-item">
                        <em>岗位</em>
                        <strong>{{ profile.position }}</strong>
                      </span>
                    </div>
                  </div>
                </div>
              </div>
              <div class="hero-fact-grid">
                <div v-for="item in heroFactItems" :key="item.key" class="hero-fact">
                  <div class="hero-fact-label">
                    <i v-if="item.icon" :class="item.icon"></i>
                    <span>{{ item.label }}</span>
                  </div>
                  <strong :class="item.valueClass">{{ item.value }}</strong>
                </div>
              </div>
            </div>
          </div>
        </article>
        <article class="progress-card panel">
          <div class="progress-block">
            <div class="progress-head">
              <h3>{{ isApplicationDocument ? '申请进度' : '报销进度' }}</h3>
            </div>
            <div class="progress-line" :style="{ '--progress-columns': progressSteps.length }">
              <div
                v-for="step in progressSteps"
                :key="step.label"
                class="progress-step"
                :class="{ active: step.active, current: step.current, done: step.done }"
              >
                <span>
                  <i
                    v-if="step.current"
                    v-motion
                    class="current-progress-ring"
                    :initial="currentProgressRingMotion.initial"
                    :enter="currentProgressRingMotion.enter"
                    aria-hidden="true"
                  ></i>
                  <i v-if="step.done" class="mdi mdi-check"></i>
                  <template v-else>{{ step.index }}</template>
                </span>
                <div class="progress-step-copy" :title="step.title || step.detail || step.time">
                  <strong>{{ step.label }}</strong>
                  <small class="progress-step-status">{{ step.time }}</small>
                  <em v-if="step.detail" class="progress-step-meta">{{ step.detail }}</em>
                </div>
              </div>
            </div>
          </div>
        </article>
        <div class="detail-grid">
          <section class="detail-left">
            <article v-if="!isApplicationDocument" class="detail-card panel">
              <div class="detail-card-head">
                <div>
                  <h3>关联单据信息</h3>
                  <p>展示本次报销关联的前置申请，便于核对申请内容、天数、事由和预计金额。</p>
                </div>
              </div>
              <div v-if="relatedApplicationFactItems.length" class="application-detail-facts related-application-facts">
                <div
                  v-for="item in relatedApplicationFactItems"
                  :key="item.key"
                  class="application-detail-fact related-application-fact"
                  :class="{ highlight: item.highlight, emphasis: item.emphasis }"
                >
                  <span>{{ item.label }}</span>
                  <strong>{{ item.value }}</strong>
                </div>
              </div>
              <div v-else class="related-application-empty">
                <strong>暂未识别到关联申请单</strong>
                <p>差旅报销应先关联已审批的申请单，请核对本单据是否由申请单生成或已在智能录入中完成关联。</p>
              </div>
            </article>
            <article class="detail-card panel">
              <div class="detail-card-head">
                <div>
                  <h3 class="detail-card-title-with-icon">
                    <i v-if="isApplicationDocument" class="mdi mdi-file-document-outline"></i>
                    <span>{{ isApplicationDocument ? '申请详情' : '费用明细' }}</span>
                  </h3>
                  <p>
                    {{
                      isApplicationDocument
                        ? '展示本次申请的事实信息、职级规则测算和用户预估费用。'
                        : isTravelRequest
                          ? '按出行时间逐笔核对票据与差旅规则。'
                          : '按业务发生时间逐笔核对票据、用途说明与 AI 识别结果。'
                    }}
                  </p>
                </div>
                <div v-if="!isApplicationDocument" class="detail-card-actions">
                  <button v-if="canOpenAiEntry" class="smart-entry-btn" type="button" :disabled="actionBusy" @click="triggerSmartEntryUpload">
                    <i class="mdi mdi-robot-outline"></i>
                    <span>{{ uploadingExpenseId ? '识别中' : '智能录入' }}</span>
                  </button>
                </div>
              </div>
              <div v-if="isApplicationDocument" class="application-detail-facts">
                <div
                  v-for="item in applicationDetailFactItems"
                  :key="item.key"
                  class="application-detail-fact"
                  :class="{ highlight: item.highlight, emphasis: item.emphasis }"
                >
                  <span>{{ item.label }}</span>
                  <strong>{{ item.value }}</strong>
                </div>
              </div>
              <TravelRequestBudgetAnalysis
                v-if="showBudgetAnalysis"
                :claim-id="request.claimId"
              />
              <div v-if="showApplicationLeaderOpinion" class="application-leader-opinion">
                <div class="application-leader-opinion-head">
                  <span><i class="mdi mdi-account-tie-outline"></i>领导意见</span>
                  <strong v-if="leaderApprovalReadonlyMeta">{{ leaderApprovalReadonlyMeta }}</strong>
                </div>
                <div
                  v-if="hasLeaderApprovalEvents"
                  class="application-leader-opinion-timeline"
                  :class="{ 'is-single': hasSingleLeaderApprovalEvent }"
                  aria-label="领导批复事件流"
                >
                  <article
                    v-for="event in leaderApprovalEvents"
                    :key="event.id"
                    class="application-leader-opinion-event"
                    :class="event.tone"
                  >
                    <div class="application-leader-opinion-event-head">
                      <span>
                        <i :class="event.type === 'returned' ? 'mdi mdi-arrow-u-left-top' : 'mdi mdi-check-circle-outline'"></i>
                        {{ event.title }}
                      </span>
                      <time v-if="event.time">{{ event.time }}</time>
                    </div>
                    <p>{{ event.opinion }}</p>
                    <footer>
                      <span>{{ event.operator }}</span>
                      <span v-if="event.returnCount">第 {{ event.returnCount }} 次退回</span>
                    </footer>
                  </article>
                </div>
              </div>
              <div v-if="!isApplicationDocument" class="detail-expense-table">
                <div v-if="smartEntryRecognitionBusy" class="expense-recognition-banner">
                  <i class="mdi mdi-loading mdi-spin"></i>
                  <span>{{ smartEntryRecognitionText }}</span>
                </div>
                <table>
                  <thead>
                    <tr>
                      <th class="col-filled-at">填写时间</th>
                      <th class="col-time">发生时间</th>
                      <th class="col-type">费用项目</th>
                      <th class="col-desc">说明</th>
                      <th class="col-amount">金额</th>
                      <th class="col-attachment">附件材料</th>
                      <th class="col-risk-note">异常说明</th>
                      <th v-if="isEditableRequest" class="col-action">操作</th>
                    </tr>
                  </thead>
                  <tbody>
                    <template v-for="item in expenseItems" :key="item.id">
                      <tr :class="{ 'system-generated-row': item.isSystemGenerated }">
                        <td class="expense-filled-at col-filled-at">
                          <strong>{{ item.filledAt }}</strong>
                          <span>条款填写时间</span>
                        </td>
                        <td :class="['expense-time col-time', { 'has-major-risk': hasExpenseRiskIndicator(item) }]">
                          <button
                            v-if="hasExpenseRiskIndicator(item)"
                            class="expense-risk-indicator"
                            type="button"
                            :title="resolveExpenseRiskIndicatorTitle(item)"
                            :aria-label="resolveExpenseRiskIndicatorTitle(item)"
                            @click="focusExpenseRisk(item)"
                          >
                            <i class="mdi mdi-alert"></i>
                          </button>
                          <template v-if="editingExpenseId === item.id">
                            <div class="cell-editor">
                              <input v-model="expenseEditor.itemDate" class="editor-input" type="date" />
                              <span>{{ item.dayLabel }}</span>
                            </div>
                          </template>
                          <template v-else>
                            <strong>{{ item.time }}</strong>
                            <span>{{ item.dayLabel }}</span>
                          </template>
                        </td>
                        <td class="expense-type col-type">
                          <template v-if="editingExpenseId === item.id">
                            <div class="cell-editor">
                              <EnterpriseSelect v-model="expenseEditor.itemType" class="editor-select" :options="expenseTypeOptions" size="small" />
                              <span>编辑费用项目</span>
                            </div>
                          </template>
                          <template v-else>
                            <strong>{{ item.name }}</strong>
                            <span>{{ item.category }}</span>
                          </template>
                        </td>
                        <td class="expense-desc col-desc">
                          <template v-if="editingExpenseId === item.id">
                            <div class="cell-editor">
                              <input
                                v-model="expenseEditor.itemReason"
                                class="editor-input"
                                type="text"
                                :placeholder="resolveExpenseReasonPlaceholder(expenseEditor.itemType)"
                              />
                              <span>{{ resolveExpenseReasonHelper(expenseEditor.itemType) }}</span>
                            </div>
                          </template>
                          <template v-else>
                            <strong>{{ item.desc }}</strong>
                            <span>{{ item.detail }}</span>
                          </template>
                        </td>
                        <td class="expense-amount col-amount">
                          <template v-if="editingExpenseId === item.id">
                            <div class="cell-editor">
                              <label class="currency-editor">
                                <span>￥</span>
                                <input
                                  v-model="expenseEditor.itemAmount"
                                  class="editor-input"
                                  type="number"
                                  min="0"
                                  step="0.01"
                                  placeholder="输入金额"
                                />
                              </label>
                              <span>保存后自动格式化为人民币</span>
                            </div>
                          </template>
                          <template v-else>
                            <strong>{{ item.amount }}</strong>
                            <span v-if="item.tone !== 'ok'" :class="['over-tag', item.tone]">{{ item.status }}</span>
                          </template>
                        </td>
                        <td class="expense-attachment col-attachment">
                          <template v-if="editingExpenseId === item.id">
                            <div class="cell-editor editor-stack">
                              <div v-if="uploadingExpenseId === item.id" class="system-attachment-note pending">
                                <i class="mdi mdi-loading mdi-spin"></i>
                                <span>识别中</span>
                              </div>
                              <div class="attachment-action-group">
                              <button
                                  v-if="isEditableRequest && !item.invoiceId && !item.isSystemGenerated"
                                  class="icon-action upload"
                                  type="button"
                                  title="上传单据"
                                  aria-label="上传单据"
                                  :disabled="actionBusy"
                                  @click="triggerExpenseUpload(item)"
                                >
                                  <i :class="uploadingExpenseId === item.id ? 'mdi mdi-loading mdi-spin' : 'mdi mdi-file-upload-outline'"></i>
                                </button>
                                <button
                                  v-if="canPreviewAttachment(item)"
                                  class="icon-action preview"
                                  type="button"
                                  :title="resolveAttachmentPreviewTitle(item)"
                                  :aria-label="resolveAttachmentPreviewTitle(item)"
                                  @click="openAttachmentPreview(item)"
                                >
                                  <i class="mdi mdi-eye-outline"></i>
                                </button>
                              <button
                                  v-if="isEditableRequest && item.invoiceId && !item.isSystemGenerated"
                                  class="icon-action danger"
                                  type="button"
                                  title="删除附件"
                                  aria-label="删除附件"
                                  :disabled="deletingAttachmentId === item.id"
                                  @click="removeExpenseAttachment(item)"
                                >
                                  <i :class="deletingAttachmentId === item.id ? 'mdi mdi-loading mdi-spin' : 'mdi mdi-close-thick'"></i>
                                </button>
                              </div>
                            </div>
                          </template>
                          <template v-else>
                            <div v-if="uploadingExpenseId === item.id" class="system-attachment-note pending">
                              <i class="mdi mdi-loading mdi-spin"></i>
                              <span>识别中</span>
                            </div>
                            <div v-else-if="item.isSystemGenerated" class="system-attachment-note">
                              <i class="mdi mdi-calculator-variant-outline"></i>
                              <span>无需附件</span>
                            </div>
                            <div v-else class="attachment-action-group">
                              <button
                                v-if="isEditableRequest && !item.invoiceId && !item.isSystemGenerated"
                                class="icon-action upload"
                                type="button"
                                title="上传单据"
                                aria-label="上传单据"
                                :disabled="actionBusy"
                                @click="triggerExpenseUpload(item)"
                              >
                                <i :class="uploadingExpenseId === item.id ? 'mdi mdi-loading mdi-spin' : 'mdi mdi-file-upload-outline'"></i>
                              </button>
                              <button
                                v-if="canPreviewAttachment(item)"
                                class="icon-action preview"
                                type="button"
                                :title="resolveAttachmentPreviewTitle(item)"
                                :aria-label="resolveAttachmentPreviewTitle(item)"
                                @click="openAttachmentPreview(item)"
                              >
                                <i class="mdi mdi-eye-outline"></i>
                              </button>
                              <button
                                v-if="isEditableRequest && item.invoiceId && !item.isSystemGenerated"
                                class="icon-action danger"
                                type="button"
                                title="删除附件"
                                aria-label="删除附件"
                                :disabled="deletingAttachmentId === item.id"
                                @click="removeExpenseAttachment(item)"
                              >
                                <i :class="deletingAttachmentId === item.id ? 'mdi mdi-loading mdi-spin' : 'mdi mdi-close-thick'"></i>
                              </button>
                            </div>
                          </template>
                        </td>
                        <td class="expense-risk-note col-risk-note">
                          <template v-if="editingExpenseId === item.id">
                            <div class="cell-editor">
                              <textarea
                                v-model="expenseEditor.itemNote"
                                class="editor-textarea"
                                rows="3"
                                placeholder="如票据存在异常或风险，请补充原因"
                              ></textarea>
                              <span>用于说明改签、绕行、超标、票据异常等情况</span>
                            </div>
                          </template>
                          <template v-else>
                            <strong v-if="item.itemNote">{{ item.itemNote }}</strong>
                            <span v-else-if="hasExpenseRiskOrAbnormal(item)" class="risk-note-missing">待补充异常说明</span>
                            <span v-else>无异常说明</span>
                          </template>
                        </td>
                        <td v-if="isEditableRequest" class="expense-action-cell col-action">
                          <div v-if="item.isSystemGenerated" class="system-row-lock">
                            <i class="mdi mdi-lock-outline"></i>
                            <span>系统计算</span>
                          </div>
                          <div v-else-if="editingExpenseId === item.id" class="row-action-group">
                            <button
                              class="inline-action primary"
                              type="button"
                              :disabled="actionBusy"
                              @click="saveExpenseEdit(item)"
                            >
                              {{ savingExpenseId === item.id ? '保存中' : '保存' }}
                            </button>
                            <button
                              class="inline-action danger"
                              type="button"
                              :disabled="actionBusy"
                              @click="removeExpenseItem(item)"
                            >
                              {{ deletingExpenseId === item.id ? '删除中' : '删除' }}
                            </button>
                          </div>
                          <div v-else class="row-action-group">
                            <button
                              class="inline-action"
                              type="button"
                              :disabled="actionBusy"
                              @click="startExpenseEdit(item)"
                            >
                              编辑
                            </button>
                            <button
                              class="inline-action danger"
                              type="button"
                              :disabled="actionBusy"
                              @click="removeExpenseItem(item)"
                            >
                              {{ deletingExpenseId === item.id ? '删除中' : '删除' }}
                            </button>
                          </div>
                        </td>
                      </tr>
                    </template>
                    <tr v-if="!expenseItems.length" class="empty-row">
                      <td :colspan="expenseTableColumnCount" class="empty-row-cell">
                        当前还没有费用明细，请通过智能录入上传票据后由系统自动归集。
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
              <div v-if="expenseItems.length && !isApplicationDocument" class="expense-total-under-table">
                <span>金额合计</span>
                <strong>{{ expenseTotal }}</strong>
              </div>
            </article>
            <article v-if="showAiAdvicePanel" class="detail-card panel validation-card">
              <div class="validation-head">
                <div>
                  <h3>{{ aiAdviceTitle }}</h3>
                  <p v-if="aiAdviceHint">{{ aiAdviceHint }}</p>
                </div>
                <span :class="['validation-pill', aiAdvice.tone]">{{ aiAdvice.badge }}</span>
              </div>
              <p class="validation-summary">{{ aiAdvice.summary }}</p>
              <div v-if="aiAdvice.sections.length" class="validation-sections">
                <section
                  v-for="section in aiAdvice.sections"
                  :key="section.kind"
                  :class="['validation-section', `validation-section--${section.kind}`]"
                >
                  <h4 class="validation-section-title">{{ section.title }}</h4>
                  <ul v-if="section.kind !== 'risk'" class="validation-list">
                    <li v-for="item in section.items" :key="item">{{ item }}</li>
                  </ul>
                  <div v-else class="risk-advice-list">
                    <article
                      v-for="card in section.items"
                      :key="card.id"
                      :id="resolveRiskCardDomId(card)"
                      :data-risk-card-id="card.id"
                      :class="['risk-advice-card', card.tone, { 'is-highlighted': isHighlightedRiskCard(card) }]"
                    >
                      <div class="risk-advice-card-main">
                        <div class="risk-advice-card-head">
                          <span>{{ card.label }}</span>
                          <strong>{{ card.title }}</strong>
                        </div>
                        <p class="risk-advice-point">{{ card.risk }}</p>
                      </div>
                      <div class="risk-advice-compact-meta">
                        <span v-if="card.ruleBasis?.length">{{ card.ruleBasis[0] }}</span>
                        <em>{{ card.suggestion }}</em>
                      </div>
                    </article>
                  </div>
                </section>
              </div>
            </article>
            <StageRiskAdviceCard
              v-if="showStageRiskAdvice"
              :request="request"
              :expense-items="expenseItems"
              :ai-advice="aiAdvice"
              :is-application-document="isApplicationDocument"
            />
          </section>
        </div>
      </div>
      <footer class="detail-actions">
        <button class="back-action" type="button" @click="emit('backToRequests')">
          <i class="mdi mdi-arrow-left"></i>
          <span>{{ backLabel }}</span>
        </button>
        <div v-if="isEditableRequest" class="approval-action-group" aria-label="申请操作">
          <button class="reject-action" type="button" :disabled="actionBusy" @click="handleDeleteRequest">
            <i class="mdi mdi-trash-can-outline"></i>
            {{ deleteBusy ? '删除中' : deleteActionLabel }}
          </button>
          <button
            v-if="canModifyReturnedApplication"
            class="secondary-action"
            type="button"
            :disabled="actionBusy"
            @click="handleModifyApplication"
          >
            <i class="mdi mdi-pencil-outline"></i>
            修改申请
          </button>
          <button class="approve-action" type="button" :disabled="!canSubmit" @click="handleSubmit">
            <i :class="submitActionIcon"></i>
            {{ submitActionLabel }}
          </button>
        </div>
        <div v-else-if="canReturnRequest || canApproveRequest || canPayRequest || canDeleteRequest" class="approval-action-group" aria-label="单据管理操作">
          <button
            v-if="canReturnRequest"
            class="return-action"
            type="button"
            :disabled="actionBusy"
            @click="handleReturnRequest"
          >
            <i class="mdi mdi-undo"></i>
            {{ returnBusy ? '退回中' : isApplicationDocument ? '退回申请' : '退回单据' }}
          </button>
          <button
            v-if="canApproveRequest"
            class="approve-action"
            type="button"
            :disabled="actionBusy"
            @click="handleApproveRequest"
          >
            <i class="mdi mdi-check-circle-outline"></i>
            {{ approveBusy ? approveBusyLabel : approveActionLabel }}
          </button>
          <button
            v-if="canPayRequest"
            class="approve-action"
            type="button"
            :disabled="actionBusy"
            @click="handlePayRequest"
          >
            <i class="mdi mdi-cash-check"></i>
            {{ payBusy ? '付款中' : '确认付款' }}
          </button>
          <button
            v-if="canDeleteRequest"
            class="reject-action"
            type="button"
            :disabled="actionBusy"
            @click="handleDeleteRequest"
          >
            <i class="mdi mdi-trash-can-outline"></i>
            {{ deleteBusy ? '删除中' : isApplicationDocument ? '删除申请' : '删除单据' }}
          </button>
        </div>
        <p v-else class="detail-action-hint">
          {{ isApplicationDocument ? '当前申请单已进入流程，详情页仅展示状态与申请信息。' : '当前单据已进入流程，详情页仅展示状态与费用明细。' }}
        </p>
      </footer>
    </div>
    <input
      ref="expenseUploadInput"
      class="expense-upload-input"
      type="file"
      accept="image/*,.pdf"
      @change="handleExpenseFileChange"
    />
    <input
      ref="smartEntryUploadInput"
      class="expense-upload-input"
      type="file"
      accept="image/*,.pdf"
      multiple
      @change="handleSmartEntryFileChange"
    />
    <ConfirmDialog
      :open="smartEntryUploadDialogOpen"
      badge="智能录入"
      title="上传报销附件"
      description="请选择需要识别并归集到当前草稿的票据附件，确认前可以清除或重新选择。"
      cancel-text="取消"
      confirm-text="确认识别"
      busy-text="识别中"
      confirm-icon="mdi mdi-file-search-outline"
      :busy="smartEntryUploadBusy"
      @close="closeSmartEntryUploadDialog"
      @confirm="confirmSmartEntryUpload"
    >
      <div class="smart-entry-upload-panel">
        <button
          class="smart-entry-upload-picker"
          type="button"
          :disabled="smartEntryUploadBusy"
          @click="chooseSmartEntryFile"
        >
          <i class="mdi mdi-tray-arrow-up"></i>
          <span>{{ smartEntrySelectedFileCount ? '重新选择附件' : '选择附件' }}</span>
        </button>
        <div class="smart-entry-upload-file">
          <i :class="smartEntrySelectedFileCount ? 'mdi mdi-file-check-outline' : 'mdi mdi-file-outline'"></i>
          <div>
            <strong>{{ smartEntrySelectedFileSummary || '尚未选择附件' }}</strong>
            <span>支持 JPG、PNG、PDF；确认后系统会逐张识别并归集到草稿明细。</span>
            <ul v-if="smartEntrySelectedFileNames.length" class="smart-entry-upload-list">
              <li v-for="fileName in smartEntrySelectedFileNames" :key="fileName">{{ fileName }}</li>
            </ul>
          </div>
          <button
            v-if="smartEntrySelectedFileCount"
            class="smart-entry-upload-clear"
            type="button"
            :disabled="smartEntryUploadBusy"
            @click="clearSmartEntryFile"
          >
            清除
          </button>
        </div>
      </div>
    </ConfirmDialog>
    <Transition name="shared-confirm">
      <div
        v-if="attachmentPreviewOpen"
        class="attachment-preview-mask"
        role="presentation"
        @click.self="closeAttachmentPreview"
      >
        <section class="attachment-preview-card" role="dialog" aria-modal="true" @click.stop>
          <div class="attachment-preview-head">
            <div>
              <span class="attachment-preview-badge">附件预览</span>
              <h4>{{ attachmentPreviewName || '当前附件' }}</h4>
            </div>
            <div class="attachment-preview-toolbar">
              <button
                v-if="canNavigateAttachmentPreview"
                class="attachment-preview-nav"
                type="button"
                title="上一份附件"
                :disabled="attachmentPreviewLoading"
                @click="goToPreviousAttachmentPreview"
              >
                <i class="mdi mdi-chevron-left"></i>
              </button>
              <span v-if="attachmentPreviewIndexLabel" class="attachment-preview-count">{{ attachmentPreviewIndexLabel }}</span>
              <button
                v-if="canNavigateAttachmentPreview"
                class="attachment-preview-nav"
                type="button"
                title="下一份附件"
                :disabled="attachmentPreviewLoading"
                @click="goToNextAttachmentPreview"
              >
                <i class="mdi mdi-chevron-right"></i>
              </button>
            </div>
            <button class="attachment-preview-close" type="button" @click="closeAttachmentPreview">
              <i class="mdi mdi-close"></i>
            </button>
          </div>
          <div class="attachment-preview-body">
            <div class="attachment-source-pane">
              <div v-if="attachmentPreviewLoading" class="attachment-preview-state">
                <i class="mdi mdi-loading mdi-spin"></i>
                <span>正在加载附件预览…</span>
              </div>
              <div v-else-if="attachmentPreviewError" class="attachment-preview-state error">
                <i class="mdi mdi-alert-circle-outline"></i>
                <span>{{ attachmentPreviewError }}</span>
              </div>
              <img
                v-else-if="attachmentPreviewUrl && attachmentPreviewMediaType.startsWith('image/')"
                :src="attachmentPreviewUrl"
                :alt="attachmentPreviewName || '附件图片'"
                class="attachment-preview-image"
              />
              <iframe
                v-else-if="attachmentPreviewUrl && attachmentPreviewMediaType === 'application/pdf'"
                :src="attachmentPreviewUrl"
                class="attachment-preview-frame"
                title="附件预览"
              ></iframe>
              <div v-else class="attachment-preview-state">
                <i class="mdi mdi-file-outline"></i>
                <span>当前附件暂不支持直接预览。</span>
              </div>
            </div>
            <aside class="attachment-insight-pane">
              <div class="attachment-insight-head">
                <span>识别信息</span>
                <strong>{{ currentAttachmentPreviewInsight?.documentTypeLabel || '待识别' }}</strong>
              </div>
              <div v-if="currentAttachmentPreviewInsight" class="attachment-insight-content">
                <div class="attachment-insight-pills">
                  <span :class="['attachment-recognition-pill', currentAttachmentPreviewInsight.requirementTone]">
                    {{ currentAttachmentPreviewInsight.requirementLabel }}
                  </span>
                </div>
                <p v-if="currentAttachmentPreviewInsight.message" class="attachment-recognition-message">
                  {{ currentAttachmentPreviewInsight.message }}
                </p>
                <div v-if="currentAttachmentPreviewInsight.fields.length" class="attachment-insight-section">
                  <span>字段结果</span>
                  <ul>
                    <li v-for="field in currentAttachmentPreviewInsight.fields" :key="field">{{ field }}</li>
                  </ul>
                </div>
                <div v-if="currentAttachmentPreviewInsight.ruleBasis.length" class="attachment-insight-section">
                  <span>规则依据</span>
                  <ul>
                    <li v-for="basis in currentAttachmentPreviewInsight.ruleBasis" :key="basis">{{ basis }}</li>
                  </ul>
                </div>
                <div v-if="currentAttachmentPreviewRiskCards.length" class="attachment-insight-section risk">
                  <span>风险点</span>
                  <article
                    v-for="card in currentAttachmentPreviewRiskCards"
                    :key="card.id"
                    :class="['attachment-risk-card', card.tone]"
                  >
                    <strong>{{ card.risk }}</strong>
                    <p>{{ card.suggestion }}</p>
                  </article>
                </div>
              </div>
              <div v-else class="attachment-preview-state compact">
                <i class="mdi mdi-file-search-outline"></i>
                <span>预览打开后会在这里展示票据字段、规则依据和风险提示。</span>
              </div>
            </aside>
          </div>
        </section>
      </div>
    </Transition>
    <ConfirmDialog
      :open="submitConfirmDialogOpen"
      badge="提交确认"
      badge-tone="warning"
      :title="`确认提交 ${request.id} 吗？`"
      :description="submitConfirmDescription"
      cancel-text="返回核对"
      :confirm-text="submitConfirmText"
      busy-text="提交中..."
      confirm-tone="primary"
      confirm-icon="mdi mdi-send-circle-outline"
      :busy="submitBusy"
      @close="closeSubmitConfirmDialog"
      @confirm="confirmSubmitRequest"
    >
      <div class="submit-confirm-summary" aria-label="提交前核对摘要">
        <div class="submit-confirm-row">
          <span>单据编号</span>
          <strong>{{ request.documentNo || request.id }}</strong>
        </div>
        <div class="submit-confirm-row">
          <span>{{ isApplicationDocument ? '申请类型' : '报销类型' }}</span>
          <strong>{{ request.typeLabel }}</strong>
        </div>
        <div class="submit-confirm-row">
          <span>{{ isApplicationDocument ? '预计金额' : '报销金额' }}</span>
          <strong>{{ request.amountDisplay || expenseTotal }}</strong>
        </div>
        <div v-if="!isApplicationDocument" class="submit-confirm-row">
          <span>费用明细</span>
          <strong>{{ expenseItems.length }} 条 / {{ uploadedExpenseCount }} 张单据</strong>
        </div>
      </div>
    </ConfirmDialog>
    <ConfirmDialog
      :open="riskOverrideDialogOpen"
      badge="重大风险"
      badge-tone="danger"
      :title="`当前存在 ${submitRiskWarnings.length} 条重大风险`"
      description="如仍需提交审批，请逐条填写每一个重大风险的原因，系统会写入附加说明并用于后续风险统计。"
      cancel-text="返回整改"
      confirm-text="保存原因并继续"
      busy-text="保存中..."
      confirm-tone="danger"
      confirm-icon="mdi mdi-alert-circle-outline"
      :busy="riskOverrideBusy"
      @close="closeRiskOverrideDialog"
      @confirm="confirmRiskOverrideReasons"
    >
      <div v-if="currentSubmitRiskWarning" class="risk-override-panel" aria-label="重大风险说明">
        <div class="risk-override-nav">
          <button
            type="button"
            class="risk-override-nav-btn"
            :disabled="submitRiskWarnings.length <= 1 || riskOverrideBusy"
            aria-label="上一条风险"
            @click="goToPreviousSubmitRisk"
          >
            <i class="mdi mdi-chevron-left"></i>
          </button>
          <span>{{ riskOverrideIndexLabel }}</span>
          <button
            type="button"
            class="risk-override-nav-btn"
            :disabled="submitRiskWarnings.length <= 1 || riskOverrideBusy"
            aria-label="下一条风险"
            @click="goToNextSubmitRisk"
          >
            <i class="mdi mdi-chevron-right"></i>
          </button>
        </div>
        <article :class="['risk-override-card', currentSubmitRiskWarning.tone]">
          <div class="risk-override-card-head">
            <span>{{ currentSubmitRiskWarning.label }}</span>
            <strong>{{ currentSubmitRiskWarning.title }}</strong>
          </div>
          <p>{{ currentSubmitRiskWarning.risk }}</p>
          <textarea
            v-model="riskOverrideReasons[currentSubmitRiskWarning.id]"
            maxlength="160"
            placeholder="请说明为什么仍需提交，例如客户指定酒店、会议高峰、协议酒店满房等"
            aria-label="违规提交原因"
          ></textarea>
        </article>
      </div>
    </ConfirmDialog>
    <TravelRequestDeleteDialog :open="deleteDialogOpen" :badge="deleteActionLabel" :title="deleteDialogTitle" :description="deleteDialogDescription" :busy="deleteBusy" @close="closeDeleteDialog" @confirm="confirmDeleteRequest" />
    <TravelRequestApprovalDialog
      :open="approveConfirmDialogOpen"
      :badge="approvalConfirmBadge"
      :title="approveConfirmTitle"
      :description="approvalConfirmDescription"
      :confirm-text="approveConfirmText"
      :busy-text="approveBusyText"
      :busy="approveBusy"
      :opinion-title="approvalOpinionTitle"
      v-model:opinion="leaderOpinion"
      :opinion-placeholder="approvalOpinionPlaceholder"
      :opinion-hint="approvalOpinionHint"
      :opinion-required="requiresApprovalOpinion"
      @close="closeApproveConfirmDialog"
      @confirm="confirmApproveRequest"
    />
    <ConfirmDialog
      :open="payConfirmDialogOpen"
      badge="付款确认"
      badge-tone="warning"
      :title="`确认 ${request.id} 已付款吗？`"
      description="确认后该报销单会进入已付款状态，并汇总到归档视图。"
      cancel-text="返回核对"
      confirm-text="确认已付款"
      busy-text="付款中..."
      confirm-tone="primary"
      confirm-icon="mdi mdi-cash-check"
      :busy="payBusy"
      @close="closePayConfirmDialog"
      @confirm="confirmPayRequest"
    />
    <TravelRequestReturnDialog :open="returnDialogOpen" :title="`确认退回 ${request.id} 吗？`" :description="returnDialogDescription" :busy="returnBusy" :application="isApplicationDocument" @close="closeReturnDialog" @confirm="confirmReturnRequest" />
  </section>
</template>
<script src="./scripts/TravelRequestDetailView.js"></script>
<style scoped src="../assets/styles/views/travel-request-detail-view.css"></style>
<style scoped src="../assets/styles/views/travel-request-detail-view-part2.css"></style>
<style scoped src="../assets/styles/views/travel-request-detail-responsive.css"></style>
