<script setup lang="ts">
import { readError } from '@/shared/utils/error'
import { ElMessage, ElMessageBox } from 'element-plus'
import { computed, onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'

import {
  adminCloseOrder,
  adminHoldDeposit,
  adminMarkOrderAbnormal,
  adminRefundOrder,
  adminRefundStatus,
  adminReleaseDeposit,
  adminResetHandoff,
  adminSealOrder,
  fetchAdminHandoffRecords,
  fetchAdminOrder,
  type HandoffRecord,
  type Order,
  type RefundStatus,
} from '@/features/orders'
import { fetchAdminPayments, type AdminPayment } from '@/features/admin/api/adminPayments'
import {
  getSnapshotHafCoinM,
  readSnapshot,
  readSnapshotResources,
} from '@/features/orders/composables/useOrderSnapshot'
import { adminPath } from '@/shared/utils/adminPath'
import { formatCentWithSymbol } from '@/shared/utils/money'
import {
  disputeStatusLabel,
  handoffStatusLabel,
  orderStatusLabel,
  refundStatusLabel,
  settlementStatusLabel,
} from '@/shared/utils/statusLabels'
import { formatDateTime } from '@/shared/utils/time'
import { formatListingNo } from '@/shared/utils/listingDisplay'

const route = useRoute()
const loading = ref(false)
const submitting = ref(false)
const order = ref<Order | null>(null)
const handoffRecords = ref<HandoffRecord[]>([])
const paymentRecords = ref<AdminPayment[]>([])
type OrderActionType =
  | 'close'
  | 'seal'
  | 'abnormal'
  | 'reset'
  | 'deposit_hold'
  | 'deposit_release'
  | ''
const actionType = ref<OrderActionType>('')
const reason = ref('')
const refundStatus = ref<RefundStatus | null>(null)

type FundSplitRow = {
  label: string
  amountCent: number | null | undefined
}

const listingCode = computed(() =>
  order.value ? formatListingNo(order.value.listing_no, order.value.listing_id) : '-'
)
const returnTarget = computed(() => {
  const from = firstQueryValue(route.query.from)
  const chatID = firstQueryValue(route.query.chat_id)
  const chatFilter = firstQueryValue(route.query.chat_filter)
  const chatStage = firstQueryValue(route.query.chat_stage)
  const chatKeyword = firstQueryValue(route.query.chat_keyword)
  if (from === 'chat' && chatID) {
    return {
      path: adminPath('chats'),
      query: {
        chat_id: chatID,
        ...(chatFilter ? { chat_filter: chatFilter } : {}),
        ...(chatStage ? { chat_stage: chatStage } : {}),
        ...(chatKeyword ? { chat_keyword: chatKeyword } : {}),
      },
    }
  }
  return adminPath('orders')
})
const returnLabel = computed(() =>
  firstQueryValue(route.query.from) === 'chat' && firstQueryValue(route.query.chat_id)
    ? '返回会话'
    : '返回列表'
)
const refunding = ref(false)

const snapshotText = computed(() => JSON.stringify(order.value?.account_snapshot || {}, null, 2))
const canOperate = computed(
  () => !!order.value && !['completed', 'cancelled', 'closed'].includes(order.value.status)
)
const resetAction = computed(() => order.value?.admin_actions?.reset_handoff)
const resetActionLabel = computed(() => {
  return resetAction.value?.label || '重置'
})
const canResetHandoff = computed(() => resetAction.value?.enabled === true)
// 押金暂扣：仅进行中、有实付押金、且未暂扣过的订单可暂扣。
const depositHoldStatus = computed(() => order.value?.deposit_hold_status || 'none')
const depositHoldAmountCent = computed(() => Number(order.value?.deposit_hold_amount_cent || 0))
const isDepositHeld = computed(() => depositHoldStatus.value === 'held')
const canHoldDeposit = computed(
  () =>
    canOperate.value &&
    depositHoldStatus.value === 'none' &&
    Number(order.value?.deposit_amount_cent || 0) > 0
)
const canReleaseDeposit = computed(() => isDepositHeld.value && depositHoldAmountCent.value > 0)
const depositHoldStatusLabel = computed(() => {
  switch (depositHoldStatus.value) {
    case 'held':
      return '押金已暂扣'
    case 'released':
      return '押金已归还'
    default:
      return ''
  }
})
const actionTitle = computed(() => {
  if (actionType.value === 'close') return '客服关闭订单'
  if (actionType.value === 'seal') return '封存订单'
  if (actionType.value === 'reset') return `${resetActionLabel.value}（恢复到对应待办）`
  if (actionType.value === 'deposit_hold') return '暂扣押金'
  if (actionType.value === 'deposit_release') return '归还暂扣押金'
  return '标记订单异常'
})
const actionConfirmButtonType = computed(() =>
  actionType.value === 'deposit_release' ? 'primary' : 'danger'
)
const closeActionTip =
  '关闭订单并归档商品/账号；已支付订单会原路退款，押金已暂扣时押金部分会继续挂起。'
const sealActionTip =
  '封存订单：终止订单并原路退款，自动解散关联群聊，关联商品永久封存；押金已暂扣时押金部分会继续挂起。'
const depositHoldActionTip = '暂扣后订单继续流转；后续本应退给租客的押金会挂起，需客服手动归还。'
const depositReleaseActionTip = computed(() =>
  depositHoldAmountCent.value > 0
    ? `将已暂扣的 ${moneyCent(depositHoldAmountCent.value)} 押金原路归还租客。`
    : '暂扣金额为 0，需订单结算/关闭/仲裁产生暂扣金额后才能归还。'
)
const refundActionTip =
  '仅发起后台人工原路退款，不关闭订单或调整商品/账号状态；押金已暂扣时仅退非暂扣部分。'
const refundButtonDisabled = computed(() => refundStatus.value?.refund_status === 'refunded')
const orderTotalCent = computed(
  () => Number(order.value?.rent_amount_cent || 0) + Number(order.value?.deposit_amount_cent || 0)
)
const latestPayment = computed(() => {
  return [...paymentRecords.value].sort(
    (a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
  )[0]
})
const paidOrderPayment = computed(() =>
  paymentRecords.value.find(item => item.biz_type === 'order_pay' && item.status === 'paid')
)
const currentSnapshot = computed(() => readSnapshot(order.value))
const snapshotHafCoinM = computed(() => getSnapshotHafCoinM(order.value))
const snapshotResources = computed(() => readSnapshotResources(order.value).slice(0, 6))
const assetSummary = computed(() => {
  const snapshot = order.value?.account_snapshot
  if (typeof snapshot !== 'object' || snapshot === null) return null
  const summary = (snapshot as Record<string, unknown>).asset_summary
  if (typeof summary !== 'object' || summary === null) return null
  return summary as Record<string, unknown>
})
const snapshotPriceBreakdown = computed(() => {
  const breakdown = assetSummary.value?.price_breakdown
  if (typeof breakdown !== 'object' || breakdown === null) return null
  return breakdown as Record<string, unknown>
})
const snapshotRatio = computed(() => {
  const row = snapshotPriceBreakdown.value
  if (!row) return null
  const sellerRatio = Number(row.seller_ratio || 0)
  const buyerRatio = Number(row.buyer_ratio || 0)
  const publishRatio = Number(assetSummary.value?.publish_ratio || 0)
  return {
    recycleRatio: sellerRatio > 0 ? sellerRatio : publishRatio > 0 ? publishRatio : 0,
    sellRatio: buyerRatio > 0 ? buyerRatio : 0,
  }
})
const ownerCoinBasePriceCent = computed(() => readPriceBreakdownCent('seller_coin_base_price'))
const ownerLossPriceCent = computed(() => {
  const consumableCent = readPriceBreakdownCent('consumable_price')
  if (consumableCent !== null) return consumableCent
  if (ownerCoinBasePriceCent.value === null || !order.value?.owner_rent_amount_cent) return null
  return Math.max(Number(order.value.owner_rent_amount_cent) - ownerCoinBasePriceCent.value, 0)
})
const hasOwnerRentBreakdown = computed(() => ownerCoinBasePriceCent.value !== null)
const fundSplitRows = computed(() => {
  if (!order.value) return []
  const rows: FundSplitRow[] = [{ label: '租客租金', amountCent: order.value.rent_amount_cent }]
  if (hasOwnerRentBreakdown.value) {
    rows.push(
      { label: '号主纯币价格', amountCent: ownerCoinBasePriceCent.value },
      { label: '号主损耗', amountCent: ownerLossPriceCent.value ?? 0 },
      { label: '号主租金合计', amountCent: order.value.owner_rent_amount_cent }
    )
  } else {
    rows.push({ label: '号主租金', amountCent: order.value.owner_rent_amount_cent })
  }
  rows.push(
    { label: '平台费用', amountCent: order.value.platform_fee_cent },
    { label: '实付押金', amountCent: order.value.deposit_amount_cent },
    { label: '原始押金', amountCent: order.value.deposit_original_amount_cent },
    { label: '免押额度', amountCent: order.value.deposit_waived_amount_cent }
  )
  return rows
})
const snapshotSeasonTags = computed(() => {
  const tags = currentSnapshot.value?.season_tags
  return Array.isArray(tags) ? tags.map(item => String(item)).filter(Boolean) : []
})
const accountSnapshotItems = computed(() => {
  const snapshot = currentSnapshot.value
  if (!snapshot) return []
  return [
    { label: '账号ID', value: displayValue(snapshot.account_id) },
    { label: '账号标题', value: displayValue(snapshot.title) },
    { label: '游戏名称', value: displayValue(snapshot.game_name) },
    { label: '所在区服', value: displayValue(snapshot.server_region) },
    { label: '登录平台', value: displayValue(snapshot.login_platform) },
    { label: '段位等级', value: displayValue(snapshot.rank_level) },
  ].filter(item => item.value !== '-')
})

onMounted(loadOrder)

async function loadOrder() {
  loading.value = true
  try {
    order.value = await fetchAdminOrder(String(route.params.id))
    handoffRecords.value = await fetchAdminHandoffRecords(String(route.params.id))
    paymentRecords.value = (await fetchAdminPayments({ order_id: String(route.params.id) })).items
    await loadRefundStatus()
  } finally {
    loading.value = false
  }
}

async function loadRefundStatus() {
  try {
    refundStatus.value = await adminRefundStatus(Number(route.params.id))
  } catch {
    refundStatus.value = null
  }
}

function openAction(type: Exclude<OrderActionType, ''>) {
  actionType.value = type
  reason.value = ''
}

async function confirmCloseAction() {
  if (!order.value || !canOperate.value) return
  try {
    await ElMessageBox.confirm(
      '客服关闭会终止订单，归档关联商品和账号；若订单已支付，将发起原路退款。若押金已暂扣，押金部分会继续挂起。确认继续？',
      '确认客服关闭',
      {
        confirmButtonText: '继续关闭',
        cancelButtonText: '取消',
        type: 'warning',
      }
    )
  } catch {
    return
  }
  openAction('close')
}

async function confirmSealAction() {
  if (!order.value || !canOperate.value) return
  try {
    await ElMessageBox.confirm(
      '封存会终止订单并发起原路退款，自动解散关联群聊，关联商品将被永久封存。若押金已暂扣，押金部分会继续挂起。确认继续？',
      '确认封存订单',
      {
        confirmButtonText: '继续封存',
        cancelButtonText: '取消',
        type: 'warning',
      }
    )
  } catch {
    return
  }
  openAction('seal')
}

async function confirmHoldDeposit() {
  if (!order.value || !canHoldDeposit.value) return
  try {
    await ElMessageBox.confirm(
      '暂扣后订单继续流转；后续结算、关闭或仲裁中本应退给租客的押金会被挂起，需客服手动归还。确认继续？',
      '确认暂扣押金',
      {
        confirmButtonText: '继续暂扣',
        cancelButtonText: '取消',
        type: 'warning',
      }
    )
  } catch {
    return
  }
  openAction('deposit_hold')
}

async function confirmReleaseDeposit() {
  if (!order.value || !isDepositHeld.value) return
  if (!canReleaseDeposit.value) {
    ElMessage.warning('暂扣押金尚未形成可归还金额')
    return
  }
  try {
    await ElMessageBox.confirm(
      `将已暂扣的 ${moneyCent(depositHoldAmountCent.value)} 押金原路归还租客。确认继续？`,
      '确认归还押金',
      {
        confirmButtonText: '继续归还',
        cancelButtonText: '取消',
        type: 'warning',
      }
    )
  } catch {
    return
  }
  openAction('deposit_release')
}

async function submitAction() {
  if (!order.value || !actionType.value) return
  submitting.value = true
  try {
    if (actionType.value === 'close') {
      await adminCloseOrder(order.value.id, reason.value)
      ElMessage.success('订单已关闭')
    } else if (actionType.value === 'seal') {
      await adminSealOrder(order.value.id, reason.value)
      ElMessage.success('订单已封存，群聊已解散')
    } else if (actionType.value === 'reset') {
      await adminResetHandoff(order.value.id, reason.value)
      ElMessage.success(`${resetActionLabel.value}成功`)
    } else if (actionType.value === 'deposit_hold') {
      await adminHoldDeposit(order.value.id, reason.value)
      ElMessage.success('押金已暂扣')
    } else if (actionType.value === 'deposit_release') {
      await adminReleaseDeposit(order.value.id, reason.value)
      ElMessage.success('暂扣押金已发起归还')
    } else {
      await adminMarkOrderAbnormal(order.value.id, reason.value)
      ElMessage.success('订单已标记异常')
    }
    actionType.value = ''
    await loadOrder()
  } catch (error) {
    ElMessage.error(readError(error, '操作失败'))
  } finally {
    submitting.value = false
  }
}

function orderRentedAt() {
  return order.value?.rented_at
}

function orderEstimatedEndAt() {
  if (!order.value) return undefined
  if (order.value.estimated_end_at) return order.value.estimated_end_at
  const rentedAt = orderRentedAt()
  const durationHours = Number(order.value.estimated_duration_hours || 0)
  if (!rentedAt || durationHours <= 0) return undefined
  return new Date(new Date(rentedAt).getTime() + durationHours * 60 * 60 * 1000).toISOString()
}

async function handleRefund() {
  if (!order.value) return
  refunding.value = true
  try {
    refundStatus.value = await adminRefundOrder(order.value.id)
    ElMessage.success('退款已发起')
    await loadOrder()
  } catch (error) {
    ElMessage.error(readError(error, '退款失败'))
  } finally {
    refunding.value = false
  }
}

async function confirmRefund() {
  if (!order.value || refundButtonDisabled.value) return
  const hasRefundInProgress = ['pending', 'refunding'].includes(
    refundStatus.value?.refund_status || ''
  )
  const message = hasRefundInProgress
    ? '当前订单已有退款处理中，继续人工退款可能导致重复全量退款。确认仍要发起？'
    : isDepositHeld.value
      ? '人工退款不会关闭订单或调整商品状态；当前押金已暂扣，本次仅退非暂扣部分。确认继续？'
      : '人工退款只会发起原路退款，不会关闭订单或调整商品状态。请确认该订单确实需要补发退款。'
  try {
    await ElMessageBox.confirm(message, '确认人工退款', {
      confirmButtonText: '确认退款',
      cancelButtonText: '取消',
      type: 'warning',
    })
  } catch {
    return
  }
  await handleRefund()
}

function paymentStatusLabel(status: string) {
  const map: Record<string, string> = {
    created: '已创建',
    paying: '支付中',
    paid: '已支付',
    refunding: '退款中',
    refunded: '已退款',
    failed: '失败',
  }
  return map[status] || status
}

function paymentStatusType(status: string) {
  if (['paid', 'refunded'].includes(status)) return 'success'
  if (status === 'failed') return 'danger'
  if (['paying', 'refunding'].includes(status)) return 'warning'
  return 'info'
}

function paymentBizTypeLabel(type: string) {
  const map: Record<string, string> = {
    order_pay: '订单支付',
    checkout_refund: '结账退款',
    arbitration_refund: '仲裁退款',
    admin_refund: '人工退款',
    cancel_refund: '取消退款',
    admin_close_refund: '客服关闭退款',
    admin_seal_refund: '封存退款',
    deposit_refund: '暂扣押金归还',
  }
  return map[type] || type
}

function moneyCent(value: number | undefined | null) {
  return formatCentWithSymbol(Number(value || 0))
}

function readPriceBreakdownCent(key: string) {
  const raw = snapshotPriceBreakdown.value?.[key]
  if (raw === undefined || raw === null || raw === '') return null
  const value = Number(raw)
  if (!Number.isFinite(value)) return null
  return Math.round(value * 100)
}

function firstQueryValue(value: unknown) {
  if (Array.isArray(value)) return typeof value[0] === 'string' ? value[0] : ''
  return typeof value === 'string' ? value : ''
}

function formatHandoffRecordType(type: string) {
  const typeMap: Record<string, string> = {
    owner_handoff: '卖家交接',
    renter_checkout: '买家结账',
    owner_counter_checkout: '卖家反驳结账',
    renter_confirm_checkout: '买家确认结账',
    owner_accept_checkout: '卖家接受结账',
    admin_arbitration: '客服仲裁',
  }
  return typeMap[type] || type
}

function orderStatusType(status: string) {
  if (['completed', 'renting'].includes(status)) return 'success'
  if (['overdue', 'abnormal', 'checkout_disputing'].includes(status)) return 'danger'
  if (['pending_payment', 'pending_handoff', 'pending_checkout_confirm'].includes(status)) {
    return 'warning'
  }
  if (['cancelled', 'closed'].includes(status)) return 'info'
  return 'primary'
}

function settlementStatusType(status: string) {
  if (['settled', 'refunded', 'arbitrated'].includes(status)) return 'success'
  if (['disputed', 'frozen'].includes(status)) return 'danger'
  if (['pending', 'unsettled'].includes(status)) return 'warning'
  return 'info'
}

function refundStatusType(status: string) {
  if (status === 'refunded') return 'success'
  if (status === 'failed') return 'danger'
  if (['pending', 'refunding'].includes(status)) return 'warning'
  return 'info'
}

function checkoutStatusLabel(status: string) {
  const map: Record<string, string> = {
    submitted: '待确认',
    countered: '号主已修正',
    accepted: '已接受',
    disputed: '争议中',
  }
  return map[status] || settlementStatusLabel(status)
}

function priceRoleLabel(role?: string) {
  const map: Record<string, string> = {
    renter: '租客视角',
    owner: '号主视角',
    admin: '客服处理',
  }
  return map[role || ''] || role || '-'
}

function disputeTypeLabel(type: string) {
  const map: Record<string, string> = {
    handoff: '交接申诉',
    checkout: '结账争议',
    order: '订单争议',
  }
  return map[type] || type || '-'
}

function userDisplay(phone: string | undefined, id: number) {
  return phone ? `${phone} / ID ${id}` : `ID ${id}`
}

function displayValue(value: unknown) {
  if (value === undefined || value === null || value === '') return '-'
  if (Array.isArray(value))
    return (
      value
        .map(item => String(item))
        .filter(Boolean)
        .join('、') || '-'
    )
  if (typeof value === 'object') return JSON.stringify(value)
  return String(value)
}

function quantity(value: unknown) {
  return Number(value || 0).toLocaleString('zh-CN', {
    maximumFractionDigits: 2,
  })
}

function formatRatioNumber(value: number) {
  const rounded = Math.round(value * 100) / 100
  return Number.isInteger(rounded) ? `${rounded}` : rounded.toFixed(2)
}

function paymentPaidAt(record: AdminPayment) {
  return record.paid_at || record.updated_at || record.created_at
}
</script>

<template>
  <section class="page" v-loading="loading">
    <div v-if="order" class="page-header-row">
      <div class="page-header">
        <p class="eyebrow">{{ order.order_no }}</p>
        <h1>订单详情</h1>
        <p>
          商品编号 {{ listingCode }} · {{ order.title }} · {{ order.server_region }} /
          {{ order.login_platform }}
        </p>
      </div>
      <div class="toolbar-actions">
        <RouterLink :to="returnTarget">
          <el-button>{{ returnLabel }}</el-button>
        </RouterLink>
        <el-button v-if="canResetHandoff" type="success" @click="openAction('reset')">
          {{ resetActionLabel }}
        </el-button>
        <el-button type="warning" :disabled="!canOperate" @click="openAction('abnormal')"
          >标记异常</el-button
        >
        <el-tooltip :content="closeActionTip" placement="top">
          <span>
            <el-button type="danger" :disabled="!canOperate" @click="confirmCloseAction"
              >客服关闭</el-button
            >
          </span>
        </el-tooltip>
        <el-tooltip :content="sealActionTip" placement="top">
          <span>
            <el-button type="danger" plain :disabled="!canOperate" @click="confirmSealAction"
              >封存订单</el-button
            >
          </span>
        </el-tooltip>
        <el-tooltip v-if="canHoldDeposit" :content="depositHoldActionTip" placement="top">
          <span>
            <el-button type="warning" plain @click="confirmHoldDeposit"> 暂扣押金 </el-button>
          </span>
        </el-tooltip>
        <el-tooltip v-if="isDepositHeld" :content="depositReleaseActionTip" placement="top">
          <span>
            <el-button
              type="success"
              plain
              :disabled="!canReleaseDeposit"
              @click="confirmReleaseDeposit"
            >
              归还押金
            </el-button>
          </span>
        </el-tooltip>
        <el-tooltip :content="refundActionTip" placement="top">
          <span>
            <el-button
              type="primary"
              :loading="refunding"
              :disabled="refundButtonDisabled"
              @click="confirmRefund"
            >
              {{ refundButtonDisabled ? '已退款' : '人工退款' }}
            </el-button>
          </span>
        </el-tooltip>
      </div>
    </div>

    <div v-if="order" class="metric-grid dashboard-metrics order-metrics">
      <div class="metric-card">
        <span>订单状态</span>
        <strong>{{ orderStatusLabel(order.status) }}</strong>
        <small>{{ handoffStatusLabel(order.handoff_status) }}</small>
      </div>
      <div class="metric-card">
        <span>结算状态</span>
        <strong>{{ settlementStatusLabel(order.settlement_status) }}</strong>
        <small>更新 {{ formatDateTime(order.updated_at) }}</small>
      </div>
      <div class="metric-card">
        <span>订单总额</span>
        <strong>{{ moneyCent(orderTotalCent) }}</strong>
        <small
          >租金 {{ moneyCent(order.rent_amount_cent) }} / 押金
          {{ moneyCent(order.deposit_amount_cent) }}</small
        >
      </div>
      <div class="metric-card">
        <span>支付状态</span>
        <strong>{{ latestPayment ? paymentStatusLabel(latestPayment.status) : '暂无流水' }}</strong>
        <small v-if="paidOrderPayment">支付 {{ moneyCent(paidOrderPayment.amount_cent) }}</small>
      </div>
      <div class="metric-card">
        <span>退款状态</span>
        <strong>{{ refundStatusLabel(refundStatus?.refund_status || '') }}</strong>
        <small v-if="refundStatus?.refund_amount_cent">
          {{ moneyCent(refundStatus.refund_amount_cent) }}
        </small>
      </div>
      <div class="metric-card">
        <span>预计截止</span>
        <strong>{{ formatDateTime(orderEstimatedEndAt(), '未设置') }}</strong>
        <small>{{ order.estimated_duration_hours }} 小时</small>
      </div>
    </div>

    <div v-if="order" class="order-detail-grid">
      <section class="dashboard-panel detail-panel">
        <div class="panel-heading">
          <h2>订单概览</h2>
          <div class="status-tags">
            <el-tag :type="orderStatusType(order.status)" effect="light">
              {{ orderStatusLabel(order.status) }}
            </el-tag>
            <el-tag :type="settlementStatusType(order.settlement_status)" effect="light">
              {{ settlementStatusLabel(order.settlement_status) }}
            </el-tag>
          </div>
        </div>
        <dl class="detail-list">
          <div>
            <dt>订单编号</dt>
            <dd>{{ order.order_no }}</dd>
          </div>
          <div>
            <dt>订单ID</dt>
            <dd>{{ order.id }}</dd>
          </div>
          <div>
            <dt>商品编号</dt>
            <dd>{{ listingCode }}</dd>
          </div>
          <div>
            <dt>账号ID</dt>
            <dd>{{ order.account_id }}</dd>
          </div>
          <div>
            <dt>游戏区服</dt>
            <dd>{{ order.server_region }}</dd>
          </div>
          <div>
            <dt>登录平台</dt>
            <dd>{{ order.login_platform }}</dd>
          </div>
          <div class="wide">
            <dt>商品标题</dt>
            <dd>{{ order.title }}</dd>
          </div>
        </dl>
      </section>

      <section class="dashboard-panel detail-panel">
        <div class="panel-heading">
          <h2>用户与时间</h2>
        </div>
        <dl class="detail-list">
          <div>
            <dt>租客</dt>
            <dd>{{ userDisplay(order.renter_phone, order.renter_id) }}</dd>
          </div>
          <div>
            <dt>号主</dt>
            <dd>{{ userDisplay(order.owner_phone, order.owner_id) }}</dd>
          </div>
          <div>
            <dt>创建时间</dt>
            <dd>{{ formatDateTime(order.created_at) }}</dd>
          </div>
          <div>
            <dt>支付截止</dt>
            <dd>{{ formatDateTime(order.payment_deadline_at, '未设置') }}</dd>
          </div>
          <div>
            <dt>开始租用</dt>
            <dd>{{ formatDateTime(orderRentedAt(), '未开始') }}</dd>
          </div>
          <div>
            <dt>预计结束</dt>
            <dd>{{ formatDateTime(orderEstimatedEndAt(), '未设置') }}</dd>
          </div>
        </dl>
      </section>

      <section class="dashboard-panel detail-panel">
        <div class="panel-heading">
          <h2>资金拆分</h2>
          <span class="panel-subtitle">{{ priceRoleLabel(order.price_role) }}</span>
        </div>
        <div class="money-list">
          <div v-for="row in fundSplitRows" :key="row.label" class="money-row">
            <span>{{ row.label }}</span>
            <strong>{{ moneyCent(row.amountCent) }}</strong>
          </div>
          <div class="money-row total">
            <span>订单实付合计</span>
            <strong>{{ moneyCent(orderTotalCent) }}</strong>
          </div>
        </div>
      </section>

      <section class="dashboard-panel detail-panel">
        <div class="panel-heading">
          <h2>退款概况</h2>
          <el-tag :type="refundStatusType(refundStatus?.refund_status || '')" effect="light">
            {{ refundStatusLabel(refundStatus?.refund_status || '') }}
          </el-tag>
        </div>
        <dl class="detail-list">
          <div>
            <dt>退款金额</dt>
            <dd>{{ moneyCent(refundStatus?.refund_amount_cent) }}</dd>
          </div>
          <div>
            <dt>可退上限</dt>
            <dd>{{ moneyCent(orderTotalCent) }}</dd>
          </div>
          <div>
            <dt>退款完成</dt>
            <dd>{{ formatDateTime(refundStatus?.refunded_at, '未完成') }}</dd>
          </div>
          <div>
            <dt>支付流水</dt>
            <dd>{{ paymentRecords.length }} 条</dd>
          </div>
          <div>
            <dt>押金暂扣</dt>
            <dd>{{ depositHoldStatusLabel || '未暂扣' }}</dd>
          </div>
          <div v-if="depositHoldStatus !== 'none'">
            <dt>已暂扣金额</dt>
            <dd>{{ moneyCent(depositHoldAmountCent) }}</dd>
          </div>
          <div v-if="order.deposit_hold_reason" class="wide">
            <dt>暂扣原因</dt>
            <dd>{{ order.deposit_hold_reason }}</dd>
          </div>
          <div v-if="order.deposit_held_at">
            <dt>暂扣时间</dt>
            <dd>{{ formatDateTime(order.deposit_held_at) }}</dd>
          </div>
          <div v-if="order.deposit_hold_released_at">
            <dt>归还时间</dt>
            <dd>{{ formatDateTime(order.deposit_hold_released_at) }}</dd>
          </div>
        </dl>
      </section>

      <section v-if="order.checkout" class="dashboard-panel detail-panel">
        <div class="panel-heading">
          <h2>结账明细</h2>
          <el-tag effect="light">{{ checkoutStatusLabel(order.checkout.status) }}</el-tag>
        </div>
        <dl class="detail-list">
          <div>
            <dt>结算租金</dt>
            <dd>{{ moneyCent(order.checkout.display_amount_cent) }}</dd>
          </div>
          <div>
            <dt>退还租客</dt>
            <dd>{{ moneyCent(order.checkout.renter_refund_amount_cent) }}</dd>
          </div>
          <div>
            <dt>号主收入</dt>
            <dd>{{ moneyCent(order.checkout.owner_income_amount_cent) }}</dd>
          </div>
          <div>
            <dt>押金扣除</dt>
            <dd>{{ moneyCent(order.checkout.deposit_deduct_amount_cent) }}</dd>
          </div>
          <div>
            <dt>消耗品金额</dt>
            <dd>{{ moneyCent(order.checkout.consumable_amount_cent) }}</dd>
          </div>
          <div>
            <dt>哈夫币消耗</dt>
            <dd>{{ quantity(order.checkout.coin_consumed_m) }}M</dd>
          </div>
          <div>
            <dt>发起人</dt>
            <dd>ID {{ order.checkout.initiated_by }}</dd>
          </div>
          <div>
            <dt>凭证数量</dt>
            <dd>{{ order.checkout.evidence_urls?.length || 0 }} 张</dd>
          </div>
          <div v-if="order.checkout.content" class="wide">
            <dt>结账说明</dt>
            <dd>{{ order.checkout.content }}</dd>
          </div>
          <div v-if="order.checkout.owner_adjustment_reason" class="wide">
            <dt>号主修正</dt>
            <dd>{{ order.checkout.owner_adjustment_reason }}</dd>
          </div>
        </dl>
      </section>

      <section v-if="order.active_dispute" class="dashboard-panel detail-panel">
        <div class="panel-heading">
          <h2>争议信息</h2>
          <el-tag type="warning" effect="light">
            {{ disputeStatusLabel(order.active_dispute.status) }}
          </el-tag>
        </div>
        <dl class="detail-list">
          <div>
            <dt>争议ID</dt>
            <dd>{{ order.active_dispute.id }}</dd>
          </div>
          <div>
            <dt>争议类型</dt>
            <dd>{{ disputeTypeLabel(order.active_dispute.type) }}</dd>
          </div>
          <div>
            <dt>发起人</dt>
            <dd>ID {{ order.active_dispute.initiator_id }}</dd>
          </div>
          <div>
            <dt>当前状态</dt>
            <dd>{{ disputeStatusLabel(order.active_dispute.status) }}</dd>
          </div>
        </dl>
      </section>

      <section class="dashboard-panel detail-panel order-wide-panel">
        <div class="panel-heading">
          <h2>支付与退款流水</h2>
          <span class="panel-subtitle">共 {{ paymentRecords.length }} 条</span>
        </div>
        <el-empty v-if="paymentRecords.length === 0" description="暂无支付流水" />
        <div v-else class="record-list">
          <article v-for="record in paymentRecords" :key="record.id" class="record-item">
            <div class="record-main">
              <strong>
                {{ paymentBizTypeLabel(record.biz_type) }} · {{ moneyCent(record.amount_cent) }}
              </strong>
              <el-tag :type="paymentStatusType(record.status)" size="small" effect="light">
                {{ paymentStatusLabel(record.status) }}
              </el-tag>
            </div>
            <div class="record-meta">
              <span>流水号：{{ record.payment_no }}</span>
              <span>用户：{{ record.user_phone || record.user_id }}</span>
              <span>渠道：{{ record.provider || '-' }}</span>
              <span>商户：{{ record.merchant_id || '-' }}</span>
              <span>三方单号：{{ record.third_order_id || '-' }}</span>
              <span>渠道单号：{{ record.provider_order_id || '-' }}</span>
              <span>创建：{{ formatDateTime(record.created_at) }}</span>
              <span>完成：{{ formatDateTime(paymentPaidAt(record), '-') }}</span>
            </div>
            <p v-if="record.error_message" class="danger-text">
              {{ record.error_code }} {{ record.error_message }}
            </p>
          </article>
        </div>
      </section>

      <section class="dashboard-panel detail-panel order-wide-panel">
        <div class="panel-heading">
          <h2>交接记录</h2>
          <span class="panel-subtitle">共 {{ handoffRecords.length }} 条</span>
        </div>
        <el-empty v-if="handoffRecords.length === 0" description="暂无交接记录" />
        <div v-else class="record-list">
          <article v-for="record in handoffRecords" :key="record.id" class="record-item">
            <div class="record-main">
              <strong>{{ formatHandoffRecordType(record.type) }}</strong>
              <span>{{ formatDateTime(record.created_at) }}</span>
            </div>
            <p>{{ record.content }}</p>
            <div class="record-meta">
              <span>发送：ID {{ record.from_user_id }}</span>
              <span>接收：ID {{ record.to_user_id }}</span>
              <span>租客确认：{{ formatDateTime(record.confirmed_by_renter_at, '-') }}</span>
              <span>号主确认：{{ formatDateTime(record.confirmed_by_owner_at, '-') }}</span>
            </div>
          </article>
        </div>
      </section>

      <section class="dashboard-panel detail-panel order-wide-panel">
        <div class="panel-heading">
          <h2>账号快照</h2>
          <span class="panel-subtitle">哈夫币 {{ quantity(snapshotHafCoinM) }}M</span>
        </div>
        <dl v-if="accountSnapshotItems.length" class="detail-list snapshot-detail-list">
          <div v-for="item in accountSnapshotItems" :key="item.label">
            <dt>{{ item.label }}</dt>
            <dd>{{ item.value }}</dd>
          </div>
        </dl>
        <div
          v-if="snapshotRatio && (snapshotRatio.recycleRatio > 0 || snapshotRatio.sellRatio > 0)"
          class="ratio-row"
        >
          <div v-if="snapshotRatio.recycleRatio > 0" class="ratio-item">
            <span class="ratio-label">回收比例</span>
            <strong class="ratio-value"
              >1:{{ formatRatioNumber(snapshotRatio.recycleRatio) }}</strong
            >
          </div>
          <div v-if="snapshotRatio.sellRatio > 0" class="ratio-item">
            <span class="ratio-label">售卖比例</span>
            <strong class="ratio-value">1:{{ formatRatioNumber(snapshotRatio.sellRatio) }}</strong>
          </div>
        </div>
        <div v-if="snapshotSeasonTags.length" class="snapshot-tags">
          <el-tag v-for="tag in snapshotSeasonTags" :key="tag" size="small" effect="plain">
            {{ tag }}
          </el-tag>
        </div>
        <div v-if="snapshotResources.length" class="snapshot-resources">
          <div v-for="resource in snapshotResources" :key="resource.key" class="resource-item">
            <strong>{{ resource.label }}</strong>
            <span>{{ quantity(resource.quantity) }} · {{ resource.price || resource.mode }}</span>
          </div>
        </div>
        <pre class="snapshot-json">{{ snapshotText }}</pre>
      </section>
    </div>

    <el-dialog
      :model-value="!!actionType"
      :title="actionTitle"
      width="560px"
      @update:model-value="actionType = ''"
    >
      <div v-if="order" class="dialog-body">
        <p>
          <strong>{{ order.order_no }}</strong> · 商品编号 {{ listingCode }} · {{ order.title }}
        </p>
        <el-input
          v-model="reason"
          type="textarea"
          :rows="4"
          placeholder="填写客服操作原因，会写入审计日志并通知双方"
        />
      </div>
      <template #footer>
        <el-button @click="actionType = ''">取消</el-button>
        <el-button :type="actionConfirmButtonType" :loading="submitting" @click="submitAction">
          确认操作
        </el-button>
      </template>
    </el-dialog>
  </section>
</template>

<style scoped>
.order-metrics {
  margin-bottom: 20px;
}

.order-metrics .metric-card strong {
  font-size: 20px;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

.metric-card small {
  display: block;
  margin-top: 8px;
  color: #8f9bba;
  font-size: 12px;
  line-height: 1.4;
  word-break: break-word;
}

.order-detail-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(360px, 0.9fr);
  gap: 20px;
  margin-bottom: 28px;
}

.detail-panel {
  min-width: 0;
}

.order-wide-panel {
  grid-column: 1 / -1;
}

.panel-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
}

.panel-heading h2 {
  margin: 0;
}

.panel-subtitle {
  color: #8f9bba;
  font-size: 13px;
  line-height: 1.6;
  text-align: right;
}

.status-tags,
.snapshot-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: flex-end;
}

.detail-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px 18px;
  margin: 0;
}

.detail-list div {
  min-width: 0;
  border-top: 1px solid #f0f2f5;
  padding-top: 10px;
}

.detail-list .wide {
  grid-column: 1 / -1;
}

.detail-list dt {
  margin-bottom: 5px;
  color: #8f9bba;
  font-size: 12px;
  font-weight: 600;
}

.detail-list dd {
  margin: 0;
  color: #1b2559;
  font-size: 14px;
  font-weight: 700;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.money-list {
  display: grid;
  gap: 8px;
}

.money-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  border-top: 1px solid #f0f2f5;
  padding-top: 9px;
  color: #52616f;
  font-size: 13px;
}

.money-row strong {
  color: #1b2559;
  font-size: 15px;
}

.money-row.total {
  margin-top: 4px;
  border-top-color: #d8e2f0;
  color: #1b2559;
  font-weight: 700;
}

.money-row.total strong {
  font-size: 18px;
}

.record-list {
  display: grid;
  gap: 12px;
}

.record-item {
  display: grid;
  gap: 8px;
  border: 1px solid #eef2f7;
  border-radius: 8px;
  background: #fbfcff;
  padding: 14px;
}

.record-main {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.record-main strong {
  color: #1b2559;
  font-size: 15px;
}

.record-main span {
  color: #8f9bba;
  font-size: 13px;
}

.record-meta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 6px 12px;
  color: #52616f;
  font-size: 12px;
  line-height: 1.5;
}

.record-item p {
  margin: 0;
  color: #52616f;
  line-height: 1.6;
  white-space: pre-wrap;
}

.snapshot-detail-list {
  margin-bottom: 14px;
}

.ratio-row {
  display: flex;
  gap: 24px;
  margin-bottom: 14px;
  padding: 12px 14px;
  border: 1px solid #eef2f7;
  border-radius: 8px;
  background: #fbfcff;
}

.ratio-item {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.ratio-label {
  font-size: 12px;
  color: #8f9bba;
  font-weight: 600;
}

.ratio-value {
  font-size: 20px;
  font-weight: 700;
  color: #1b2559;
}

.snapshot-tags {
  justify-content: flex-start;
  margin-bottom: 14px;
}

.snapshot-resources {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}

.resource-item {
  display: grid;
  gap: 4px;
  border: 1px solid #eef2f7;
  border-radius: 8px;
  background: #fbfcff;
  padding: 10px 12px;
}

.resource-item strong {
  color: #1b2559;
  font-size: 13px;
}

.resource-item span {
  color: #52616f;
  font-size: 12px;
}

.snapshot-json {
  overflow-x: auto;
  max-height: 360px;
  margin: 0;
  border-radius: 8px;
  background: #111827;
  color: #dbe4ee;
  padding: 14px;
  line-height: 1.6;
}

@media (max-width: 960px) {
  .order-detail-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 640px) {
  .panel-heading,
  .record-main {
    align-items: flex-start;
    flex-direction: column;
  }

  .detail-list {
    grid-template-columns: 1fr;
  }

  .status-tags {
    justify-content: flex-start;
  }
}
</style>
