<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { ChatDotRound, 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 {
  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'

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 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': 4,
    '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 {
    await counterCheckout(order.value.id, {
      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: counterForm.value.reason,
      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(value)
}

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

function money(value: unknown) {
  return `${roundMoney(readNumber(value))}`
}

function orderRentAmount(item: Order) {
  if (item.owner_id === session.userId) return Number(item.owner_rent_amount ?? item.display_amount ?? 0)
  if (item.renter_id === session.userId) return Number(item.rent_amount ?? item.display_amount ?? 0)
  return Number(item.display_amount ?? 0)
}

function ownerActualIncome(item: Order) {
  if (item.owner_id !== session.userId) return null
  const value = item.checkout?.owner_income_amount
  return typeof value === 'number' ? value : 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 = checkout.consumable_amount
  counterForm.value.coin_consumed_m = checkout.coin_consumed_m
  counterForm.value.other_amount = checkout.other_amount
  counterForm.value.deposit_deduct_amount = 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: '卖家接受结账',
  }
  return typeMap[type] || type
}
</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>
        </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(order.deposit_amount) }}</strong>
      </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>
      </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(order.checkout.display_amount) }}</strong>
        </div>
        <div class="summary-row">
          <span>预收押金</span>
          <strong>¥{{ money(order.checkout.deposit_amount) }}</strong>
        </div>
        <div class="summary-row">
          <span>额外消耗品已用</span>
          <strong class="warning">¥{{ money(order.checkout.consumable_amount) }}</strong>
        </div>
        <div class="summary-row">
          <span>押金赔付扣除</span>
          <strong class="warning">¥{{ money(order.checkout.deposit_deduct_amount) }}</strong>
        </div>
        <div v-if="isRenter" class="summary-row highlight">
          <span>退还租客（未使用租金 + 剩余押金）</span>
          <strong class="amount">¥{{ money(order.checkout.renter_refund_amount) }}</strong>
        </div>
        <div v-if="isOwner" class="summary-row highlight">
          <span>号主最终收入（租金 + 押金赔付）</span>
          <strong class="amount">¥{{ money(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="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>¥{{ (activePayment.amount_cent / 100).toFixed(2) }}</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;
}

.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 {
  font-size: 18px;
  font-weight: 700;
  color: #1f2937;
}

.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>
