<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { ChatDotRound, CopyDocument, Loading } from '@element-plus/icons-vue'
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import QRCode from 'qrcode'

import { fetchOrderChat } from '@/features/chats/api/chats'
import { createDispute } from '@/features/disputes'
import { uploadFile } from '@/shared/api/files'
import { centToYuan, formatMoney } from '@/shared/utils/money'
import {
  acceptCheckout,
  cancelOrder,
  confirmCheckout,
  confirmReceive,
  counterCheckout,
  fetchHandoffRecords,
  fetchOrder,
  queryOrderPayment,
  startOrderPayment,
  submitCheckout,
  submitHandoff,
  type HandoffRecord,
  type Order,
  type PaymentOrder,
} from '@/features/orders'
import { useSessionStore } from '@/stores/session'
import { handoffStatusLabel, orderStatusLabel } from '@/utils/statusLabels'
import { formatDateTime } from '@/utils/time'
import { formatListingNo } from '@/utils/listingDisplay'

const route = useRoute()
const router = useRouter()
const session = useSessionStore()
const loading = ref(false)
const cancelling = ref(false)
const startingPayment = ref(false)
const handoffing = ref(false)
const confirming = ref(false)
const returning = ref(false)
const completing = ref(false)
const countering = ref(false)
const acceptingCheckout = ref(false)
const rejectingCheckout = ref(false)
const disputing = ref(false)
const uploadingEvidence = ref(false)
const order = ref<Order | null>(null)
const handoffRecords = ref<HandoffRecord[]>([])
const handoffContent = ref('')
const paymentDialogVisible = ref(false)
const activePayment = ref<PaymentOrder | null>(null)

const listingCode = computed(() =>
  order.value ? formatListingNo(order.value.listing_no, order.value.listing_id) : '-'
)
const paymentQRCodeURL = ref('')
const qrGenerating = ref(false)
const checkingPayment = ref(false)
let paymentPollingTimer: number | undefined
const checkoutForm = ref({
  content: '',
  consumable_amount: 0,
  coin_consumed_m: 0,
  other_amount: 0,
  evidenceText: '',
})
const resourceUsage = ref<Record<string, number>>({})
const counterForm = ref({
  consumable_amount: 0,
  coin_consumed_m: 0,
  other_amount: 0,
  deposit_deduct_amount: 0,
  reason: '',
  evidenceText: '',
})
const rejectReason = ref('')
const disputeType = ref('cannot_login')
const disputeDescription = ref('')
const disputeEvidenceText = ref('')
const openingChat = ref(false)
let autoPayHandled = false

const isOwner = computed(() => order.value?.owner_id === session.userId)
const isRenter = computed(() => order.value?.renter_id === session.userId)
const orderAmountLabel = computed(() => (isOwner.value ? '预计租金' : '支付租金'))
const orderRentDisplayAmount = computed(() => (order.value ? orderRentAmount(order.value) : 0))
const ownerIncomeDisplayAmount = computed(() =>
  order.value ? ownerActualIncome(order.value) : null
)
const ownerIncomeLabel = computed(() =>
  order.value?.status === 'completed' ? '实际到手' : '结账预计到手'
)
const canOpenDispute = computed(() => {
  if (!order.value || (!isOwner.value && !isRenter.value)) return false
  return ![
    'completed',
    'cancelled',
    'closed',
    'disputing',
    'checkout_disputing',
    'abnormal',
  ].includes(order.value.status)
})
const isCheckoutDisputeStage = computed(() => {
  return (
    !!order.value &&
    ['pending_checkout_confirm', 'pending_checkout_accept'].includes(order.value.status)
  )
})
const checkoutResources = computed(() => {
  const resources = readSnapshotResources()
  return resources.filter(item => item.quantity > 0)
})
const resourceChargeAmount = computed(() => {
  return roundMoney(
    checkoutResources.value.reduce((sum, item) => {
      if (!isChargedResource(item)) return sum
      const used = readResourceUsage(item.key)
      return sum + used * item.unitPrice
    }, 0)
  )
})
const snapshotHafCoinM = computed(() => {
  const snapshot = readSnapshot()
  return roundQuantity(readNumber(snapshot?.haf_coin_amount) / 1000000)
})
const remainingHafCoinM = computed(() => {
  return roundQuantity(
    Math.max(snapshotHafCoinM.value - Number(checkoutForm.value.coin_consumed_m || 0), 0)
  )
})

function getOrderStep(status: string) {
  const stepMap: Record<string, number> = {
    pending_payment: 0,
    pending_handoff: 1,
    renting: 2,
    overdue: 2,
    pending_checkout_confirm: 3,
    pending_checkout_accept: 3,
    completed: 5,
    cancelled: 0,
    closed: 4,
  }
  return stepMap[status] ?? 0
}

onMounted(loadOrder)
onBeforeUnmount(stopPaymentPolling)

async function loadOrder() {
  loading.value = true
  try {
    order.value = await fetchOrder(String(route.params.id))
    handoffRecords.value = await fetchHandoffRecords(String(route.params.id))
    hydrateResourceUsage()
    hydrateCounterForm()
    if (
      !autoPayHandled &&
      route.query.pay === '1' &&
      order.value?.status === 'pending_payment' &&
      order.value?.renter_id === session.userId
    ) {
      autoPayHandled = true
      void router.replace({ path: route.path })
      void handlePay()
    }
  } finally {
    loading.value = false
  }
}

async function handleCancel() {
  if (!order.value) return
  cancelling.value = true
  try {
    await cancelOrder(order.value.id)
    ElMessage.success('订单已取消，账号已释放')
    await router.push('/orders')
  } catch (error) {
    ElMessage.error(readError(error, '取消失败'))
  } finally {
    cancelling.value = false
  }
}

async function handlePay() {
  if (!order.value) return
  startingPayment.value = true
  try {
    const payment = await startOrderPayment(order.value.id)
    if (payment.paid) {
      ElMessage.success('支付成功，等待号主交接')
      await loadOrder()
    } else {
      showPaymentDialog(payment)
    }
  } catch (error) {
    ElMessage.error(readError(error, '支付失败'))
  } finally {
    startingPayment.value = false
  }
}

function showPaymentDialog(payment: PaymentOrder) {
  activePayment.value = payment
  paymentDialogVisible.value = true
  void renderPaymentQRCode(payment)
  startPaymentPolling()
}

function paymentPayURL(payment = activePayment.value) {
  return payment?.jspay_url || payment?.td_code || payment?.jspay_info || ''
}

async function renderPaymentQRCode(payment = activePayment.value) {
  const payURL = paymentPayURL(payment)
  paymentQRCodeURL.value = ''
  if (!payURL) {
    return
  }
  qrGenerating.value = true
  try {
    paymentQRCodeURL.value = await QRCode.toDataURL(payURL, {
      width: 240,
      margin: 1,
      errorCorrectionLevel: 'M',
      color: {
        dark: '#111827',
        light: '#ffffff',
      },
    })
  } catch {
    ElMessage.error('二维码生成失败')
  } finally {
    qrGenerating.value = false
  }
}

function startPaymentPolling() {
  stopPaymentPolling()
  paymentPollingTimer = window.setInterval(() => {
    void refreshPaymentStatus(true)
  }, 3000)
}

function stopPaymentPolling() {
  if (paymentPollingTimer !== undefined) {
    window.clearInterval(paymentPollingTimer)
    paymentPollingTimer = undefined
  }
}

async function refreshPaymentStatus(silent = false) {
  if (!order.value || checkingPayment.value) {
    return
  }
  checkingPayment.value = true
  const currentPayURL = paymentPayURL()
  try {
    const payment = await queryOrderPayment(order.value.id)
    if (payment.paid) {
      stopPaymentPolling()
      ElMessage.success('支付成功')
      paymentDialogVisible.value = false
      await loadOrder()
    } else {
      activePayment.value = payment
      if (paymentPayURL(payment) !== currentPayURL) {
        await renderPaymentQRCode(payment)
      }
      if (!silent) {
        ElMessage.info('支付未完成')
      }
    }
  } catch (error) {
    if (!silent) {
      ElMessage.error(readError(error, '刷新支付状态失败'))
    }
  } finally {
    checkingPayment.value = false
  }
}

async function handleRefreshPayment() {
  await refreshPaymentStatus(false)
}

async function handleSubmitHandoff() {
  if (!order.value) return
  handoffing.value = true
  try {
    await submitHandoff(order.value.id, handoffContent.value)
    handoffContent.value = ''
    ElMessage.success('交接说明已提交')
    await loadOrder()
  } catch (error) {
    ElMessage.error(readError(error, '提交交接失败'))
  } finally {
    handoffing.value = false
  }
}

async function handleConfirmReceive() {
  if (!order.value) return
  confirming.value = true
  try {
    await confirmReceive(order.value.id)
    ElMessage.success('已确认收号，订单进入使用中')
    await loadOrder()
  } catch (error) {
    ElMessage.error(readError(error, '确认收号失败'))
  } finally {
    confirming.value = false
  }
}

async function handleSubmitCheckout() {
  if (!order.value) return
  returning.value = true
  try {
    const consumableAmount = resourceChargeAmount.value
    checkoutForm.value.consumable_amount = consumableAmount
    await submitCheckout(order.value.id, {
      content: checkoutContentWithSummary(),
      consumable_amount: consumableAmount,
      coin_consumed_m: checkoutForm.value.coin_consumed_m,
      other_amount: checkoutForm.value.other_amount,
      evidence_urls: linesToList(checkoutForm.value.evidenceText),
    })
    checkoutForm.value = {
      content: '',
      consumable_amount: 0,
      coin_consumed_m: 0,
      other_amount: 0,
      evidenceText: '',
    }
    resourceUsage.value = {}
    ElMessage.success('结账已发起，等待号主确认')
    await loadOrder()
  } catch (error) {
    ElMessage.error(readError(error, '发起结账失败'))
  } finally {
    returning.value = false
  }
}

async function handleConfirmCheckout() {
  if (!order.value) return
  completing.value = true
  try {
    await confirmCheckout(order.value.id)
    ElMessage.success('结账已确认，订单完成')
    await loadOrder()
  } catch (error) {
    ElMessage.error(readError(error, '确认结账失败'))
  } finally {
    completing.value = false
  }
}

async function handleCounterCheckout() {
  if (!order.value) return
  countering.value = true
  try {
    const reasonText = counterForm.value.reason.trim()
    await counterCheckout(order.value.id, {
      content: reasonText,
      consumable_amount: counterForm.value.consumable_amount,
      coin_consumed_m: counterForm.value.coin_consumed_m,
      other_amount: counterForm.value.other_amount,
      deposit_deduct_amount: counterForm.value.deposit_deduct_amount,
      reason: reasonText,
      evidence_urls: linesToList(counterForm.value.evidenceText),
    })
    ElMessage.success('结账修正已提交，等待租客确认')
    await loadOrder()
  } catch (error) {
    ElMessage.error(readError(error, '修改结账失败'))
  } finally {
    countering.value = false
  }
}

async function handleAcceptCheckout() {
  if (!order.value) return
  acceptingCheckout.value = true
  try {
    await acceptCheckout(order.value.id)
    ElMessage.success('已确认修正结账，订单完成')
    await loadOrder()
  } catch (error) {
    ElMessage.error(readError(error, '确认修正失败'))
  } finally {
    acceptingCheckout.value = false
  }
}

async function handleRejectCheckout() {
  if (!order.value) return
  rejectingCheckout.value = true
  try {
    await createDispute(order.value.id, {
      type: 'checkout_dispute',
      description: rejectReason.value,
      evidence_urls: [],
    })
    rejectReason.value = ''
    ElMessage.success('已拒绝修正结账，订单进入争议处理')
    await loadOrder()
  } catch (error) {
    ElMessage.error(readError(error, '拒绝修正失败'))
  } finally {
    rejectingCheckout.value = false
  }
}

async function handleCreateDispute() {
  if (!order.value) return
  disputing.value = true
  try {
    const evidence_urls = linesToList(disputeEvidenceText.value)
    await createDispute(order.value.id, {
      type: isCheckoutDisputeStage.value ? 'checkout_dispute' : disputeType.value,
      description: disputeDescription.value,
      evidence_urls,
    })
    disputeDescription.value = ''
    disputeEvidenceText.value = ''
    ElMessage.success('申诉已提交，订单进入仲裁处理')
    await loadOrder()
  } catch (error) {
    ElMessage.error(readError(error, '提交申诉失败'))
  } finally {
    disputing.value = false
  }
}

async function handleEvidenceUpload(event: Event) {
  const input = event.target as HTMLInputElement
  const file = input.files?.[0]
  input.value = ''
  if (!file) return
  uploadingEvidence.value = true
  try {
    const uploaded = await uploadFile(file, 'dispute')
    disputeEvidenceText.value = [disputeEvidenceText.value, uploaded.url].filter(Boolean).join('\n')
    ElMessage.success('证据文件已上传')
  } catch (error) {
    ElMessage.error(readError(error, '上传失败'))
  } finally {
    uploadingEvidence.value = false
  }
}

async function openOrderChat() {
  if (!order.value || openingChat.value) return
  openingChat.value = true
  try {
    const chat = await fetchOrderChat(order.value.id)
    await router.push(`/messages/${chat.id}`)
  } catch {
    ElMessage.error('订单群聊暂不可用')
  } finally {
    openingChat.value = false
  }
}

function readError(error: unknown, fallback: string) {
  if (typeof error === 'object' && error && 'response' in error) {
    const response = (error as { response?: { data?: { message?: string } } }).response
    return response?.data?.message || fallback
  }
  return fallback
}

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

function orderEstimatedEndAt() {
  if (!order.value) return undefined
  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()
}

interface CheckoutResource {
  key: string
  label: string
  price: string
  mode: string
  quantity: number
  unitPrice: number
}

function readSnapshot() {
  const snapshot = order.value?.account_snapshot
  if (isRecord(snapshot)) return snapshot
  return null
}

function readAssetSummary() {
  const summary = readSnapshot()?.asset_summary
  if (isRecord(summary)) return summary
  return null
}

function readSnapshotResources(): CheckoutResource[] {
  const resources = readAssetSummary()?.resources
  if (!Array.isArray(resources)) return []
  return resources
    .filter(isRecord)
    .map(item => {
      const key = String(item.key || item.label || '')
      const label = String(item.label || key || '额外消耗品')
      const price = String(item.price || '')
      return {
        key,
        label,
        price,
        mode: String(item.mode || '收费'),
        quantity: readNumber(item.quantity),
        unitPrice: readUnitPrice(price),
      }
    })
    .filter(item => item.key && item.quantity > 0)
}

function hydrateResourceUsage() {
  const next: Record<string, number> = {}
  for (const item of checkoutResources.value) {
    next[item.key] = Math.min(
      Math.max(Number(resourceUsage.value[item.key] || 0), 0),
      item.quantity
    )
  }
  resourceUsage.value = next
}

function readResourceUsage(key: string) {
  return Math.max(Number(resourceUsage.value[key] || 0), 0)
}

function isChargedResource(item: CheckoutResource) {
  return item.mode !== '赠送'
}

function resourceLineAmount(item: CheckoutResource) {
  return roundMoney(readResourceUsage(item.key) * item.unitPrice)
}

function checkoutContentWithSummary() {
  const lines = [checkoutForm.value.content.trim()].filter(Boolean)
  const usedResources = checkoutResources.value.filter(item => readResourceUsage(item.key) > 0)
  if (usedResources.length) {
    lines.push(
      `额外消耗品：${usedResources
        .map(
          item =>
            `${item.label} ${readResourceUsage(item.key)}/${item.quantity}${
              isChargedResource(item) ? `，金额¥${money(resourceLineAmount(item))}` : '，赠送不扣款'
            }`
        )
        .join('；')}`
    )
  }
  if (Number(checkoutForm.value.coin_consumed_m || 0) > 0) {
    lines.push(
      `哈夫币消耗：${quantity(Number(checkoutForm.value.coin_consumed_m))}M，预计剩余${quantity(
        remainingHafCoinM.value
      )}M`
    )
  }
  if (lines.length === 0) {
    lines.push('租客发起结账。')
  }
  return lines.join('\n')
}

function readUnitPrice(priceText: string) {
  const normalized = priceText.replace(/，/g, ',').trim()
  const fractionMatch = normalized.match(/(\d+(?:\.\d+)?)\s*元\s*\/\s*(\d+(?:\.\d+)?)/)
  if (fractionMatch) {
    const amount = Number(fractionMatch[1])
    const count = Number(fractionMatch[2])
    return count > 0 ? roundMoney(amount / count) : 0
  }
  const singleMatch = normalized.match(/(\d+(?:\.\d+)?)\s*元/)
  if (singleMatch) return Number(singleMatch[1])
  const fallback = normalized.match(/(\d+(?:\.\d+)?)/)
  return fallback ? Number(fallback[1]) : 0
}

function roundMoney(value: number) {
  return Math.round(Number(value || 0) * 10) / 10
}

function roundQuantity(value: number) {
  return Math.round(value * 100) / 100
}

function money(value: unknown) {
  return formatMoney(readNumber(value))
}

function amountYuan(cent: unknown, legacyYuan?: unknown) {
  if (cent !== undefined && cent !== null) return centToYuan(readNumber(cent))
  return readNumber(legacyYuan)
}

function orderRentAmount(item: Order) {
  if (item.owner_id === session.userId)
    return amountYuan(item.owner_rent_amount_cent, item.owner_rent_amount ?? item.display_amount)
  if (item.renter_id === session.userId)
    return amountYuan(item.rent_amount_cent, item.rent_amount ?? item.display_amount)
  return amountYuan(item.display_amount_cent, item.display_amount)
}

function ownerActualIncome(item: Order) {
  if (item.owner_id !== session.userId) return null
  const value = item.checkout?.owner_income_amount_cent
  if (typeof value === 'number') return centToYuan(value)
  return typeof item.checkout?.owner_income_amount === 'number'
    ? item.checkout.owner_income_amount
    : null
}

function quantity(value: unknown) {
  const rounded = roundQuantity(readNumber(value))
  return Number.isInteger(rounded) ? `${rounded}` : rounded.toFixed(2)
}

function readNumber(value: unknown) {
  const number = Number(value || 0)
  return Number.isFinite(number) ? number : 0
}

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null
}

function hydrateCounterForm() {
  if (!order.value?.checkout) return
  const checkout = order.value.checkout
  counterForm.value.consumable_amount = amountYuan(
    checkout.consumable_amount_cent,
    checkout.consumable_amount
  )
  counterForm.value.coin_consumed_m = checkout.coin_consumed_m
  counterForm.value.other_amount = amountYuan(checkout.other_amount_cent, checkout.other_amount)
  counterForm.value.deposit_deduct_amount = amountYuan(
    checkout.deposit_deduct_amount_cent,
    checkout.deposit_deduct_amount
  )
}

function linesToList(value: string) {
  return value
    .split('\n')
    .map(item => item.trim())
    .filter(Boolean)
}

function scrollToDispute() {
  const disputeSection = document.querySelector('.dispute-section')
  if (disputeSection) {
    disputeSection.scrollIntoView({ behavior: 'smooth', block: 'start' })
  }
}

function scrollToCheckout() {
  const checkoutSection = document.querySelector('.checkout-form-section')
  if (checkoutSection) {
    checkoutSection.scrollIntoView({ behavior: 'smooth', block: 'start' })
  }
}

function scrollToCounterCheckout() {
  const counterSection = document.querySelector('.counter-checkout-section')
  if (counterSection) {
    counterSection.scrollIntoView({ behavior: 'smooth', block: 'start' })
  }
}

function scrollToRejectCheckout() {
  const rejectSection = document.querySelector('.reject-checkout-section')
  if (rejectSection) {
    rejectSection.scrollIntoView({ behavior: 'smooth', block: 'start' })
  }
}

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
}

async function copyListingCode() {
  if (!order.value) return
  try {
    await navigator.clipboard.writeText(listingCode.value)
    ElMessage.success('商品编号已复制')
  } catch {
    ElMessage.error('复制失败')
  }
}
</script>

<template>
  <section class="page order-detail-page" v-loading="loading">
    <div v-if="order" class="page-header">
      <div class="header-top">
        <div class="header-info">
          <p class="eyebrow">订单号：{{ order.order_no }}</p>
          <h1>{{ order.title }}</h1>
          <p class="order-meta">{{ order.server_region }} / {{ order.login_platform }}</p>
          <el-button size="small" plain :icon="CopyDocument" @click="copyListingCode">
            商品编号 {{ listingCode }}
          </el-button>
        </div>
        <el-button type="primary" :loading="openingChat" @click="openOrderChat">
          <el-icon style="margin-right: 4px"><ChatDotRound /></el-icon>
          联系对方
        </el-button>
      </div>
    </div>

    <div v-if="order" class="content-layout">
      <div class="main-content">
        <div v-if="order" class="order-progress-section">
          <el-steps
            :active="getOrderStep(order.status)"
            align-center
            finish-status="success"
            process-status="process"
          >
            <el-step
              title="待支付"
              :description="order.status === 'pending_payment' ? '等待租客支付' : ''"
            />
            <el-step
              title="待交接"
              :description="
                order.status === 'pending_handoff' ? handoffStatusLabel(order.handoff_status) : ''
              "
            />
            <el-step
              title="使用中"
              :description="['renting', 'overdue'].includes(order.status) ? '租赁进行中' : ''"
            />
            <el-step
              title="结账中"
              :description="
                ['pending_checkout_confirm', 'pending_checkout_accept'].includes(order.status)
                  ? '等待确认'
                  : ''
              "
            />
            <el-step title="已完成" :description="order.status === 'completed' ? '订单完成' : ''" />
          </el-steps>
        </div>

        <div v-if="order" class="detail-grid">
          <div class="metric-card primary">
            <span class="metric-label">订单状态</span>
            <strong class="metric-value">{{ orderStatusLabel(order.status) }}</strong>
          </div>
          <div class="metric-card">
            <span class="metric-label">交接状态</span>
            <strong class="metric-value">{{ handoffStatusLabel(order.handoff_status) }}</strong>
          </div>
          <div class="metric-card highlight">
            <span class="metric-label">{{ orderAmountLabel }}</span>
            <strong class="metric-value amount">¥{{ money(orderRentDisplayAmount) }}</strong>
          </div>
          <div v-if="isOwner && ownerIncomeDisplayAmount !== null" class="metric-card income">
            <span class="metric-label">{{ ownerIncomeLabel }}</span>
            <strong class="metric-value amount">¥{{ money(ownerIncomeDisplayAmount) }}</strong>
          </div>
          <div class="metric-card">
            <span class="metric-label">押金</span>
            <strong class="metric-value"
              >¥{{ money(amountYuan(order.deposit_amount_cent, order.deposit_amount)) }}</strong
            >
            <span
              v-if="amountYuan(order.deposit_waived_amount_cent, order.deposit_waived_amount) > 0"
              class="metric-note"
              >已免押 ¥{{
                money(amountYuan(order.deposit_waived_amount_cent, order.deposit_waived_amount))
              }}</span
            >
          </div>
        </div>

        <div v-if="order" class="info-section">
          <div class="info-card">
            <div class="info-row">
              <span class="info-label">开始时间</span>
              <span class="info-value">{{ formatDateTime(orderRentedAt(), '未开始') }}</span>
            </div>
            <div class="info-row">
              <span class="info-label">预计截止</span>
              <span class="info-value">{{ formatDateTime(orderEstimatedEndAt(), '未设置') }}</span>
            </div>
          </div>

          <div v-if="order.status === 'pending_payment'" class="action-card warning">
            <p class="action-message">订单待支付，支付后账号进入交接流程。</p>
            <div class="action-buttons">
              <el-button
                v-if="isRenter"
                type="primary"
                size="large"
                :loading="startingPayment"
                @click="handlePay"
              >
                立即支付订单
              </el-button>
              <el-button type="danger" plain :loading="cancelling" @click="handleCancel">
                取消订单并释放账号
              </el-button>
            </div>
          </div>

          <div v-if="order.status === 'pending_handoff'" class="action-card info">
            <div class="action-buttons">
              <el-button type="danger" plain :loading="cancelling" @click="handleCancel">
                取消订单并释放账号
              </el-button>
            </div>
          </div>
        </div>

        <div v-if="order" class="timeline-section">
          <div class="section-header">
            <h2>交接记录</h2>
            <span>商品编号 {{ listingCode }}</span>
          </div>
          <el-empty v-if="handoffRecords.length === 0" description="暂无交接记录" />
          <el-timeline v-else>
            <el-timeline-item
              v-for="record in handoffRecords"
              :key="record.id"
              :timestamp="formatDateTime(record.created_at)"
              placement="top"
            >
              <div class="timeline-content">
                <div class="timeline-title">{{ formatHandoffRecordType(record.type) }}</div>
                <div class="timeline-body">{{ record.content }}</div>
              </div>
            </el-timeline-item>
          </el-timeline>
        </div>

        <div
          v-if="order && isRenter && ['renting', 'overdue'].includes(order.status)"
          class="form-section checkout-form-section"
        >
          <div class="section-header">
            <h2>发起结账</h2>
          </div>
          <div class="form-card">
            <el-input
              v-model="checkoutForm.content"
              type="textarea"
              :rows="4"
              placeholder="填写结账说明、租后资产状态或注意事项"
            />
            <div class="checkout-resource-panel">
              <div class="checkout-resource-head">
                <strong>额外消耗品</strong>
                <span class="amount-highlight">已用金额：¥{{ money(resourceChargeAmount) }}</span>
              </div>
              <el-empty
                v-if="checkoutResources.length === 0"
                description="订单快照中暂无额外消耗品"
              />
              <div
                v-for="item in checkoutResources"
                v-else
                :key="item.key"
                class="checkout-resource-row"
              >
                <div class="checkout-resource-meta">
                  <strong>{{ item.label }}</strong>
                  <span
                    >库存 {{ item.quantity }}，{{ item.mode }}，{{
                      item.price || '未设置单价'
                    }}</span
                  >
                </div>
                <el-input-number
                  v-model="resourceUsage[item.key]"
                  :min="0"
                  :max="item.quantity"
                  :precision="0"
                  controls-position="right"
                />
                <span class="checkout-resource-amount">¥{{ money(resourceLineAmount(item)) }}</span>
              </div>
            </div>
            <el-form class="form-grid" label-position="top">
              <el-form-item label="消耗哈夫币（M）">
                <el-input-number
                  v-model="checkoutForm.coin_consumed_m"
                  class="full-control"
                  :min="0"
                  :max="snapshotHafCoinM"
                  :precision="2"
                  controls-position="right"
                />
                <span class="field-hint"
                  >订单快照 {{ quantity(snapshotHafCoinM) }}M，预计剩余
                  {{ quantity(remainingHafCoinM) }}M</span
                >
              </el-form-item>
              <el-form-item label="其他押金赔付（元）">
                <el-input-number
                  v-model="checkoutForm.other_amount"
                  class="full-control"
                  :min="0"
                  :precision="0"
                  controls-position="right"
                />
                <span class="field-hint"
                  >不含上方额外消耗品；仅填写封禁、违规、资产损坏等需要从押金赔付的费用。</span
                >
              </el-form-item>
            </el-form>
            <div class="checkout-deduct-preview">
              <div>
                <span>额外消耗品已用</span>
                <strong>¥{{ money(resourceChargeAmount) }}</strong>
                <em>按上方物资数量自动计算，计入实际结算租金</em>
              </div>
              <div>
                <span>其他押金赔付</span>
                <strong>¥{{ money(checkoutForm.other_amount) }}</strong>
                <em>作为押金赔付扣除，和额外消耗品分开展示</em>
              </div>
            </div>
            <el-input
              v-model="checkoutForm.evidenceText"
              type="textarea"
              :rows="3"
              placeholder="结账证据链接，一行一个。可填写截图地址或备注链接"
            />
            <el-button
              type="primary"
              size="large"
              :loading="returning"
              @click="handleSubmitCheckout"
              >发起结账</el-button
            >
          </div>
        </div>

        <div
          v-if="
            order &&
            order.checkout &&
            ['pending_checkout_confirm', 'pending_checkout_accept'].includes(order.status)
          "
          class="info-section"
        >
          <div class="section-header">
            <h2>结账明细</h2>
          </div>
          <div class="checkout-summary-card">
            <div class="summary-row">
              <span>实际结算租金</span>
              <strong
                >¥{{
                  money(
                    amountYuan(order.checkout.display_amount_cent, order.checkout.display_amount)
                  )
                }}</strong
              >
            </div>
            <div class="summary-row">
              <span>预收押金</span>
              <strong>
                ¥{{
                  money(
                    amountYuan(order.checkout.deposit_amount_cent, order.checkout.deposit_amount)
                  )
                }}
                <em
                  v-if="
                    amountYuan(order.deposit_waived_amount_cent, order.deposit_waived_amount) > 0
                  "
                  >已免押 ¥{{
                    money(amountYuan(order.deposit_waived_amount_cent, order.deposit_waived_amount))
                  }}</em
                >
              </strong>
            </div>
            <div class="summary-row">
              <span>额外消耗品已用</span>
              <strong class="warning"
                >¥{{
                  money(
                    amountYuan(
                      order.checkout.consumable_amount_cent,
                      order.checkout.consumable_amount
                    )
                  )
                }}</strong
              >
            </div>
            <div class="summary-row">
              <span>押金赔付扣除</span>
              <strong class="warning"
                >¥{{
                  money(
                    amountYuan(
                      order.checkout.deposit_deduct_amount_cent,
                      order.checkout.deposit_deduct_amount
                    )
                  )
                }}</strong
              >
            </div>
            <div v-if="isRenter" class="summary-row highlight">
              <span>退还租客（未使用租金 + 剩余押金）</span>
              <strong class="amount"
                >¥{{
                  money(
                    amountYuan(
                      order.checkout.renter_refund_amount_cent,
                      order.checkout.renter_refund_amount
                    )
                  )
                }}</strong
              >
            </div>
            <div v-if="isOwner" class="summary-row highlight">
              <span>号主最终收入（租金 + 押金赔付）</span>
              <strong class="amount"
                >¥{{
                  money(
                    amountYuan(
                      order.checkout.owner_income_amount_cent,
                      order.checkout.owner_income_amount
                    )
                  )
                }}</strong
              >
            </div>
            <div v-if="order.checkout.content" class="summary-note">
              <label>说明：</label>
              <p>{{ order.checkout.content }}</p>
            </div>
            <div v-if="order.checkout.owner_adjustment_reason" class="summary-note warning">
              <label>修正原因：</label>
              <p>{{ order.checkout.owner_adjustment_reason }}</p>
            </div>
          </div>
        </div>

        <div
          v-if="order && isOwner && order.status === 'pending_checkout_confirm'"
          class="form-section counter-checkout-section"
        >
          <div class="section-header">
            <h2>修改结账</h2>
          </div>
          <div class="form-card">
            <h3 class="sub-title">修改结账金额</h3>
            <el-form class="form-grid" label-position="top">
              <el-form-item label="额外消耗品已用金额">
                <el-input-number
                  v-model="counterForm.consumable_amount"
                  class="full-control"
                  :min="0"
                  :precision="0"
                  controls-position="right"
                />
              </el-form-item>
              <el-form-item label="消耗哈夫币（M）">
                <el-input-number
                  v-model="counterForm.coin_consumed_m"
                  class="full-control"
                  :min="0"
                  :precision="2"
                  controls-position="right"
                />
              </el-form-item>
              <el-form-item label="其他押金扣款（元）">
                <el-input-number
                  v-model="counterForm.other_amount"
                  class="full-control"
                  :min="0"
                  :precision="0"
                  controls-position="right"
                />
              </el-form-item>
              <el-form-item label="押金扣除（元）">
                <el-input-number
                  v-model="counterForm.deposit_deduct_amount"
                  class="full-control"
                  :min="0"
                  :max="amountYuan(order.deposit_amount_cent, order.deposit_amount)"
                  :precision="0"
                  controls-position="right"
                />
              </el-form-item>
            </el-form>
            <el-input
              v-model="counterForm.reason"
              type="textarea"
              :rows="3"
              placeholder="填写修改原因"
            />
            <el-input
              v-model="counterForm.evidenceText"
              type="textarea"
              :rows="3"
              placeholder="修正证据链接，一行一个"
            />
            <el-button
              type="warning"
              size="large"
              :loading="countering"
              @click="handleCounterCheckout"
              >提交修正给租客确认</el-button
            >
          </div>
        </div>

        <div
          v-if="order && isRenter && order.status === 'pending_checkout_accept'"
          class="form-section reject-checkout-section"
        >
          <div class="section-header">
            <h2>拒绝修正</h2>
          </div>
          <div class="form-card">
            <p class="form-hint">不同意修正时填写原因，订单会进入争议处理。</p>
            <el-input
              v-model="rejectReason"
              type="textarea"
              :rows="3"
              placeholder="不同意时填写原因，会进入争议处理"
            />
            <el-button
              type="danger"
              plain
              size="large"
              :loading="rejectingCheckout"
              @click="handleRejectCheckout"
              >拒绝修正并发起争议</el-button
            >
          </div>
        </div>
      </div>

      <!-- 右侧悬浮操作区 -->
      <div v-if="order" class="action-sidebar">
        <!-- 交接操作 -->
        <div
          v-if="
            isOwner &&
            order.status === 'pending_handoff' &&
            order.handoff_status === 'pending_owner'
          "
          class="sidebar-card"
        >
          <h3 class="sidebar-title">提交交接说明</h3>
          <el-input
            v-model="handoffContent"
            type="textarea"
            :rows="5"
            placeholder="填写登录方式、注意事项和交接说明"
          />
          <el-button type="primary" size="large" :loading="handoffing" @click="handleSubmitHandoff"
            >提交交接</el-button
          >
        </div>

        <!-- 确认收号 -->
        <div
          v-if="
            isRenter &&
            order.status === 'pending_handoff' &&
            order.handoff_status === 'pending_renter_confirm'
          "
          class="sidebar-card"
        >
          <h3 class="sidebar-title">确认收号</h3>
          <p class="sidebar-hint">
            确认账号可以正常登录后，订单会进入使用中并重新计算预计截止时间。
          </p>
          <el-button type="primary" size="large" :loading="confirming" @click="handleConfirmReceive"
            >确认已收到账号</el-button
          >
        </div>

        <!-- 发起结账 -->
        <div
          v-if="isRenter && ['renting', 'overdue'].includes(order.status)"
          class="sidebar-card highlight-card"
        >
          <h3 class="sidebar-title">快捷结账</h3>
          <el-button type="primary" size="large" :loading="returning" @click="handleSubmitCheckout">
            立即提交结账
          </el-button>
          <p class="sidebar-hint">
            如需修改消耗品、哈夫币等详细信息，请先向下滚动填写完整表单后再提交
          </p>
          <el-button type="default" size="small" @click="scrollToCheckout">
            查看详细结账表单
          </el-button>
        </div>

        <!-- 确认结账 -->
        <div v-if="isOwner && order.status === 'pending_checkout_confirm'" class="sidebar-card">
          <h3 class="sidebar-title">确认结账</h3>
          <el-button
            type="primary"
            size="large"
            :loading="completing"
            @click="handleConfirmCheckout"
          >
            确认结账并完成订单
          </el-button>
          <div class="section-divider-mini">
            <span>或者</span>
          </div>
          <el-button type="warning" plain size="large" @click="scrollToCounterCheckout">
            需要修改结账金额
          </el-button>
          <p class="sidebar-hint">如认为金额有误，点击上方按钮修改</p>
        </div>

        <!-- 确认修正结账 -->
        <div v-if="isRenter && order.status === 'pending_checkout_accept'" class="sidebar-card">
          <h3 class="sidebar-title">确认修正结账</h3>
          <el-button
            type="primary"
            size="large"
            :loading="acceptingCheckout"
            @click="handleAcceptCheckout"
          >
            同意修正并完成订单
          </el-button>
          <div class="section-divider-mini">
            <span>或者</span>
          </div>
          <el-button type="danger" plain size="large" @click="scrollToRejectCheckout">
            不同意，发起争议
          </el-button>
          <p class="sidebar-hint">不同意修正时需填写原因，将进入争议处理</p>
        </div>

        <!-- 发起申诉 -->
        <div v-if="canOpenDispute" class="sidebar-card dispute-card">
          <h3 class="sidebar-title">{{ isCheckoutDisputeStage ? '发起结账争议' : '发起申诉' }}</h3>
          <el-button type="warning" size="large" @click="scrollToDispute">
            {{ isCheckoutDisputeStage ? '提交结账争议' : '提交申诉' }}
          </el-button>
          <p class="sidebar-hint">点击后滚动到申诉表单填写详细信息</p>
        </div>
      </div>
    </div>

    <div v-if="order && canOpenDispute" class="form-section dispute-section">
      <div class="section-header">
        <h2>{{ isCheckoutDisputeStage ? '发起结账争议' : '发起申诉' }}</h2>
      </div>
      <div class="form-card">
        <el-select
          v-if="!isCheckoutDisputeStage"
          v-model="disputeType"
          class="full-control"
          placeholder="选择申诉类型"
        >
          <el-option label="无法登录" value="cannot_login" />
          <el-option label="虚假描述" value="false_description" />
          <el-option label="账号被封" value="account_banned" />
          <el-option label="资产损失" value="asset_loss" />
          <el-option label="哈夫币争议" value="haf_coin_dispute" />
          <el-option label="超时未交接" value="handoff_timeout" />
          <el-option label="超时未归还" value="return_timeout" />
        </el-select>
        <el-input
          v-model="disputeDescription"
          type="textarea"
          :rows="4"
          placeholder="说明争议经过、时间点和希望客服核查的证据"
        />
        <el-input
          v-model="disputeEvidenceText"
          type="textarea"
          :rows="3"
          placeholder="证据链接，一行一个。开发阶段可先填截图地址或备注链接"
        />
        <div class="upload-line">
          <input
            type="file"
            accept="image/jpeg,image/png,image/webp,application/pdf"
            :disabled="uploadingEvidence"
            @change="handleEvidenceUpload"
          />
        </div>
        <el-button type="warning" size="large" :loading="disputing" @click="handleCreateDispute">
          {{ isCheckoutDisputeStage ? '提交结账争议' : '提交申诉' }}
        </el-button>
      </div>
    </div>

    <el-dialog
      v-model="paymentDialogVisible"
      title="订单支付"
      width="560px"
      append-to-body
      :z-index="4000"
      class="order-pay-dialog"
      @closed="stopPaymentPolling"
    >
      <div v-if="activePayment" class="pay-dialog-body">
        <div class="pay-summary">
          <div class="pay-summary-row">
            <span>支付金额</span>
            <strong>¥{{ formatMoney(activePayment.amount_cent / 100) }}</strong>
          </div>
        </div>
        <div v-if="paymentPayURL()" class="pay-qr-section">
          <div class="pay-qr-box">
            <el-icon v-if="qrGenerating" class="is-loading" :size="32"><Loading /></el-icon>
            <img v-else-if="paymentQRCodeURL" :src="paymentQRCodeURL" alt="支付二维码" />
          </div>
          <div class="pay-instructions">
            <h3>请使用微信或支付宝扫码支付</h3>
            <p>扫码完成后将自动刷新，也可手动点击下方按钮确认。</p>
          </div>
        </div>
        <p v-else class="pay-hint">支付单已创建，请完成付款后刷新状态。</p>
      </div>
      <template #footer>
        <div class="pay-dialog-footer">
          <el-button type="primary" :loading="checkingPayment" @click="handleRefreshPayment">
            我已支付，刷新状态
          </el-button>
        </div>
      </template>
    </el-dialog>
  </section>
</template>

<style scoped>
.order-detail-page {
  max-width: 1400px;
  margin: 0 auto;
}

.page-header {
  margin-bottom: 32px;
}

.header-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
}

.header-info {
  flex: 1;
}

.order-meta {
  color: #64748b;
  margin-top: 8px;
}

.content-layout {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 24px;
  align-items: start;
}

.main-content {
  min-width: 0;
}

.action-sidebar {
  position: sticky;
  top: 24px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.sidebar-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 20px;
  background: #ffffff;
  border: 2px solid #e5e7eb;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.sidebar-card.highlight-card {
  background: #eff6ff;
  border-color: #3b82f6;
}

.sidebar-card.dispute-card {
  background: #fef2f2;
  border-color: #fecaca;
}

.sidebar-title {
  font-size: 16px;
  font-weight: 700;
  color: #1f2937;
  margin: 0;
}

.sidebar-hint {
  margin: 0;
  font-size: 13px;
  color: #64748b;
  line-height: 1.5;
}

.sidebar-card .el-button {
  width: 100%;
}

.order-progress-section {
  margin-bottom: 32px;
  padding: 24px;
  background: #ffffff;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
}

.detail-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
  margin-bottom: 32px;
}

.metric-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 20px;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  background: #ffffff;
  transition: all 0.2s;
}

.metric-card:hover {
  border-color: #cbd5e1;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}

.metric-card.primary {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: none;
  color: #ffffff;
}

.metric-card.primary .metric-label {
  color: rgba(255, 255, 255, 0.9);
}

.metric-card.primary .metric-value {
  color: #ffffff;
}

.metric-card.highlight {
  background: linear-gradient(135deg, #ff6a00 0%, #ee0979 100%);
  border: none;
  color: #ffffff;
}

.metric-card.highlight .metric-label {
  color: rgba(255, 255, 255, 0.9);
}

.metric-card.highlight .metric-value {
  color: #ffffff;
}

.metric-card.income {
  background: #f0fdf4;
  border-color: #bbf7d0;
}

.metric-card.income .metric-label {
  color: #15803d;
}

.metric-card.income .metric-value {
  color: #16a34a;
}

.metric-label {
  font-size: 13px;
  color: #64748b;
  font-weight: 500;
}

.metric-value {
  font-size: 24px;
  font-weight: 700;
  color: #1f2937;
}

.metric-value.amount {
  color: #ff6a00;
}

.metric-note {
  font-size: 12px;
  color: #2563eb;
}

.info-section {
  margin-bottom: 32px;
}

.info-card {
  display: grid;
  gap: 12px;
  padding: 20px;
  background: #ffffff;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
}

.info-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 0;
  border-bottom: 1px solid #f3f4f6;
}

.info-row:last-child {
  border-bottom: none;
}

.info-label {
  font-size: 14px;
  color: #64748b;
  font-weight: 500;
}

.info-value {
  font-size: 14px;
  color: #1f2937;
  font-weight: 600;
}

.action-card {
  margin-top: 16px;
  padding: 20px;
  background: #ffffff;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
}

.action-card.warning {
  background: #fffbeb;
  border-color: #fde68a;
}

.action-card.info {
  background: #eff6ff;
  border-color: #bfdbfe;
}

.action-message {
  margin: 0 0 16px 0;
  color: #1f2937;
  font-size: 14px;
}

.action-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
}

.section-header h2 {
  font-size: 20px;
  font-weight: 700;
  color: #1f2937;
  margin: 0;
}

.timeline-section {
  margin-bottom: 32px;
}

.timeline-section :deep(.el-timeline) {
  padding: 24px;
  background: #ffffff;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
}

.timeline-content {
  display: grid;
  gap: 8px;
}

.timeline-title {
  font-size: 15px;
  font-weight: 600;
  color: #1f2937;
}

.timeline-body {
  font-size: 14px;
  color: #64748b;
  line-height: 1.6;
  white-space: pre-wrap;
}

.form-section {
  margin-bottom: 32px;
}

.form-card {
  display: grid;
  gap: 16px;
  padding: 24px;
  background: #ffffff;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
}

.form-hint {
  margin: 0;
  padding: 12px 16px;
  background: #f8fafc;
  border-left: 3px solid #3b82f6;
  color: #475569;
  font-size: 14px;
  line-height: 1.6;
  border-radius: 4px;
}

.section-divider {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 24px 0;
  position: relative;
}

.section-divider::before,
.section-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: #e5e7eb;
}

.section-divider span {
  padding: 0 16px;
  color: #9ca3af;
  font-size: 14px;
  font-weight: 500;
}

.section-divider-mini {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 8px 0;
  position: relative;
}

.section-divider-mini::before,
.section-divider-mini::after {
  content: '';
  flex: 1;
  height: 1px;
  background: #e5e7eb;
}

.section-divider-mini span {
  padding: 0 12px;
  color: #9ca3af;
  font-size: 12px;
  font-weight: 500;
}

.sub-title {
  font-size: 16px;
  font-weight: 600;
  color: #374151;
  margin: 0 0 16px 0;
}

.checkout-resource-panel {
  display: grid;
  gap: 12px;
  padding: 16px;
  background: #f9fafb;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
}

.checkout-resource-head {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 12px;
  align-items: center;
  padding-bottom: 12px;
  border-bottom: 2px solid #e5e7eb;
}

.checkout-resource-head strong {
  color: #1f2937;
  font-size: 15px;
}

.amount-highlight {
  color: #ff6a00;
  font-weight: 700;
  font-size: 14px;
}

.checkout-resource-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 12px;
  align-items: center;
  padding: 12px;
  background: #ffffff;
  border: 1px solid #e5e7eb;
  border-radius: 6px;
}

.checkout-resource-meta {
  display: grid;
  gap: 4px;
}

.checkout-resource-meta strong {
  color: #1f2937;
  font-size: 14px;
}

.checkout-resource-meta span {
  color: #6b7785;
  font-size: 12px;
}

.checkout-resource-amount {
  min-width: 80px;
  text-align: right;
  color: #ff6a00;
  font-weight: 700;
  font-size: 16px;
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 16px;
}

.field-hint {
  display: block;
  margin-top: 6px;
  color: #6b7280;
  font-size: 12px;
}

.checkout-deduct-preview {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.checkout-deduct-preview div {
  display: grid;
  gap: 6px;
  padding: 12px;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  background: #f9fafb;
}

.checkout-deduct-preview span {
  color: #4b5563;
  font-size: 13px;
  font-weight: 700;
}

.checkout-deduct-preview strong {
  color: #ff6a00;
  font-size: 18px;
  font-weight: 800;
}

.checkout-deduct-preview em {
  color: #6b7280;
  font-size: 12px;
  font-style: normal;
  line-height: 1.45;
}

.checkout-summary-card {
  display: grid;
  gap: 12px;
  padding: 24px;
  background: #ffffff;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
}

.summary-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 0;
  border-bottom: 1px solid #f3f4f6;
}

.summary-row:last-child {
  border-bottom: none;
}

.summary-row.highlight {
  padding: 16px;
  background: #f0fdf4;
  border: 1px solid #bbf7d0;
  border-radius: 8px;
}

.summary-row span {
  font-size: 14px;
  color: #64748b;
}

.summary-row strong {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  font-size: 18px;
  font-weight: 700;
  color: #1f2937;
}

.summary-row strong em {
  font-style: normal;
  font-size: 12px;
  font-weight: 500;
  color: #2563eb;
}

.summary-row strong.amount {
  color: #10b981;
  font-size: 20px;
}

.summary-row strong.warning {
  color: #f59e0b;
}

.summary-note {
  padding: 16px;
  background: #f8fafc;
  border-left: 3px solid #94a3b8;
  border-radius: 4px;
}

.summary-note.warning {
  background: #fef3c7;
  border-left-color: #f59e0b;
}

.summary-note label {
  display: block;
  margin-bottom: 8px;
  color: #475569;
  font-size: 13px;
  font-weight: 600;
}

.summary-note p {
  margin: 0;
  color: #1f2937;
  font-size: 14px;
  line-height: 1.6;
  white-space: pre-wrap;
}

.dispute-section .form-card {
  background: #fef2f2;
  border-color: #fecaca;
}

.upload-line {
  padding: 12px;
  background: #f9fafb;
  border: 1px dashed #cbd5e1;
  border-radius: 6px;
}

.upload-line input[type='file'] {
  width: 100%;
  font-size: 14px;
}

.pay-dialog-body {
  display: grid;
  gap: 20px;
}

.pay-summary {
  padding: 16px 20px;
  background: #f8fafc;
  border-radius: 8px;
}

.pay-summary-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.pay-summary-row span {
  color: #64748b;
  font-size: 14px;
}

.pay-summary-row strong {
  color: #111a44;
  font-size: 28px;
  font-weight: 700;
}

.pay-qr-section {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  padding: 24px;
  background: #f8fafc;
  border-radius: 12px;
}

.pay-qr-box {
  width: 240px;
  height: 240px;
  display: grid;
  place-items: center;
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  background: #ffffff;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}

.pay-qr-box img {
  width: 220px;
  height: 220px;
  display: block;
}

.pay-instructions {
  text-align: center;
}

.pay-instructions h3 {
  margin: 0 0 8px 0;
  color: #111a44;
  font-size: 18px;
  font-weight: 600;
}

.pay-instructions p {
  margin: 0;
  color: #64748b;
  font-size: 14px;
  line-height: 1.7;
}

.pay-hint {
  margin: 0;
  padding: 16px;
  background: #f8fafc;
  color: #64748b;
  font-size: 14px;
  text-align: center;
  border-radius: 8px;
}

.pay-dialog-footer {
  display: flex;
  justify-content: center;
  padding-top: 8px;
}

:global(.order-pay-dialog) {
  border-radius: 16px;
}

:global(.order-pay-dialog .el-dialog__header) {
  padding: 20px 24px;
  border-bottom: 1px solid #e5e7eb;
}

:global(.order-pay-dialog .el-dialog__body) {
  padding: 24px;
}

:global(.order-pay-dialog .el-dialog__footer) {
  padding: 16px 24px;
  border-top: 1px solid #e5e7eb;
}

@media (max-width: 768px) {
  .content-layout {
    grid-template-columns: 1fr;
  }

  .action-sidebar {
    position: static;
    order: -1;
  }

  .header-top {
    flex-direction: column;
  }

  .detail-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .form-grid {
    grid-template-columns: 1fr;
  }

  .checkout-resource-row {
    grid-template-columns: 1fr;
  }

  .checkout-resource-amount {
    text-align: left;
  }

  .checkout-deduct-preview {
    grid-template-columns: 1fr;
  }

  .action-buttons {
    flex-direction: column;
  }

  .action-buttons .el-button {
    width: 100%;
  }

  .pay-qr-section {
    padding: 16px;
  }
}
</style>
