<script setup lang="ts">
import { computed, nextTick, onMounted, ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { ChatDotRound, CopyDocument, Loading, Service } from '@element-plus/icons-vue'

import {
  amountYuan,
  money,
  OrderAccountSnapshot,
  OrderCheckoutSummary,
  OrderHandoffTimeline,
  OrderResourceUsageEditor,
} from '@/features/orders'
import { useOrderActions } from '@/features/orders/composables/useOrderActions'
import { useOrderPaymentCashier } from '@/features/orders/composables/useOrderPaymentCashier'
import { formatCent } from '@/shared/utils/money'
import { orderHandoffStatusLabel, orderStatusLabel } from '@/shared/utils/statusLabels'
import { formatDateTime } from '@/shared/utils/time'
import type { PaymentPayWay } from '@/features/orders/api/orders'

// 支付收银台：二维码渲染 + 轮询查询。PC 不做 App 浏览器跳转，直接渲染二维码弹窗。
const route = useRoute()
const disputeDialogVisible = ref(false)
const cashier = useOrderPaymentCashier({
  notifySuccess: message => ElMessage.success(message),
  notifyError: message => ElMessage.error(message),
  notifyInfo: message => ElMessage.info(message),
  notifyFallback: message => ElMessage.warning(message),
  paidMessage: '支付成功，正在进入群消息',
  pollIntervalMs: 3000,
  qrWidth: 240,
})

// 订单详情交互：业务逻辑、状态、计算属性、handler。
const {
  loading,
  cancelling,
  startingPayment,
  handoffing,
  confirming,
  returning,
  completing,
  countering,
  acceptingCheckout,
  rejectingCheckout,
  disputing,
  cancellingDispute,
  uploadingEvidence,
  openingChat,
  order,
  handoffRecords,
  handoffContent,
  checkoutForm,
  resourceUsage,
  counterForm,
  rejectReason,
  disputeType,
  disputeDescription,
  disputeEvidenceText,
  checkoutResources,
  resourceChargeAmount,
  snapshotHafCoinM,
  remainingHafCoinM,
  resourceLineAmount,
  isOwner,
  isRenter,
  listingCode,
  orderAmountLabel,
  orderRentDisplayAmount,
  renterDiscountDisplayCent,
  ownerIncomeDisplayAmount,
  ownerIncomeLabel,
  canOpenDispute,
  canCancelDispute,
  canCounterCheckout,
  canAcceptCheckoutProposal,
  checkoutShortfallCent,
  checkoutOvershootCent,
  checkoutRoundLabel,
  isCheckoutDisputeStage,
  handleCancel,
  handlePay,
  handleSubmitHandoff,
  handleConfirmReceive,
  handleSubmitCheckout,
  handleConfirmCheckout,
  handleCounterCheckout,
  handleAcceptCheckout,
  handleRejectCheckout,
  handleCreateDispute,
  handleCancelDispute,
  handleEvidenceUpload,
  openOrderChat,
  orderEstimatedEndAt,
  orderRentedAt,
} = useOrderActions({
  notifySuccess: message => ElMessage.success(message),
  notifyError: message => ElMessage.error(message),
  notifyWarning: message => ElMessage.warning(message),
  confirm: async ({ title, message }) => {
    try {
      await ElMessageBox.confirm(message, title, {
        confirmButtonText: '确认提交',
        cancelButtonText: '返回检查',
        type: 'warning',
        dangerouslyUseHTMLString: false,
      })
      return true
    } catch {
      return false
    }
  },
  actionsNeedingConfirm: ['submitCheckout'],
  selectPayWay,
  ordersPath: '/orders',
  chatPathPrefix: '/messages/',
  startCashier: (payment, onPaid) => cashier.openPaymentCashier(payment, onPaid),
  onCreateDisputeSuccess: closeDisputeDialog,
})

// 支付弹窗别名：保持 template 字段名不变。
const paymentDialogVisible = cashier.paymentPopupVisible
const activePayment = cashier.activePayment
const paymentQRCodeURL = cashier.paymentQRCodeURL
const qrGenerating = cashier.qrGenerating
const checkingPayment = cashier.checkingPayment
const paymentPayURL = cashier.payURL
const activePayWayLabel = computedPayWayLabel(activePayment)
const handoffFocused = ref(false)
const hasSidebarActions = computed(() => {
  if (!order.value) return false
  return (
    (isOwner.value && order.value.status === 'pending_checkout_confirm') ||
    (isRenter.value && order.value.status === 'pending_checkout_accept')
  )
})
const showCheckoutCounterForm = computed(
  () =>
    !!order.value &&
    canCounterCheckout.value &&
    ((isOwner.value && order.value.status === 'pending_checkout_confirm') ||
      (isRenter.value && order.value.status === 'pending_checkout_accept'))
)
const disputeSupportTitle = computed(() => {
  if (canCancelDispute.value) {
    return order.value?.status === 'checkout_disputing' ? '结账争议处理中' : '申诉处理中'
  }
  return isCheckoutDisputeStage.value ? '结账金额有异议？' : '遇到交接问题？'
})
const disputeSupportMessage = computed(() => {
  if (canCancelDispute.value) {
    return '客服正在处理当前争议，如问题已解决可取消申诉。'
  }
  return isCheckoutDisputeStage.value
    ? '可提交结账争议，客服会核查双方证据。'
    : '无法登录、超时交接等情况可申请客服介入。'
})
const disputeSupportActionText = computed(() => {
  if (canCancelDispute.value) {
    return order.value?.status === 'checkout_disputing' ? '取消结账争议' : '取消申诉'
  }
  return isCheckoutDisputeStage.value ? '发起结账争议' : '发起申诉'
})

// selectPayWay 在创建支付单前让用户选择支付宝或微信。
// 通过自定义对话框展示两个平级渠道卡片，返回 null 表示用户取消。
const payWayDialogVisible = ref(false)
let payWayResolver: ((value: PaymentPayWay | null) => void) | null = null

function selectPayWay(): Promise<PaymentPayWay | null> {
  payWayDialogVisible.value = true
  return new Promise(resolve => {
    payWayResolver = resolve
  })
}

function choosePayWay(payWay: PaymentPayWay) {
  payWayResolver?.(payWay)
  payWayResolver = null
  payWayDialogVisible.value = false
}

// 对话框关闭（含点 X、按 ESC）时，未选择则视为取消。
function handlePayWayDialogClosed() {
  payWayResolver?.(null)
  payWayResolver = null
}

// computedPayWayLabel 根据当前支付单展示支付方式名称。
function computedPayWayLabel(paymentRef: typeof activePayment) {
  return computed(() => {
    const map: Record<string, string> = {
      ZFBZF: '支付宝',
      WXZF: '微信',
    }
    return map[paymentRef.value?.pay_way || ''] || '当前方式'
  })
}
function handleRefreshPayment() {
  void cashier.refreshPaymentStatus(false)
}
function stopPaymentPolling() {
  cashier.stopPaymentPolling()
}

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
}

function openDisputeDialog() {
  disputeDialogVisible.value = true
}
function closeDisputeDialog() {
  disputeDialogVisible.value = false
}
function scrollToCounterCheckout() {
  scrollToSection('.counter-checkout-section')
}
function scrollToRejectCheckout() {
  scrollToSection('.reject-checkout-section')
}
function scrollToHandoff() {
  scrollToSection('.handoff-workspace')
}
function scrollToSection(selector: string) {
  const section = document.querySelector(selector)
  if (section) {
    section.scrollIntoView({ behavior: 'smooth', block: 'start' })
  }
}
async function focusHandoffFromQuery() {
  if (handoffFocused.value || loading.value || !order.value || route.query.focus !== 'handoff') {
    return
  }
  handoffFocused.value = true
  await nextTick()
  scrollToHandoff()
}

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

onMounted(() => {
  void focusHandoffFromQuery()
})

watch([() => route.query.focus, order, loading], () => {
  void focusHandoffFromQuery()
})
</script>

<template>
  <section class="page order-detail-page" v-loading="loading">
    <div v-if="order" class="page-header" :class="{ centered: !hasSidebarActions }">
      <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" :class="{ centered: !hasSidebarActions }">
      <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' ? orderHandoffStatusLabel(order) : ''
              "
            />
            <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="
            isOwner &&
            order.status === 'pending_handoff' &&
            order.handoff_status === 'pending_owner'
          "
          class="form-section handoff-action-section"
        >
          <div class="section-header compact">
            <h2>当前待办：提交交接说明</h2>
            <span>填写后租客即可确认收号</span>
          </div>
          <div class="handoff-action-card">
            <el-input
              v-model="handoffContent"
              type="textarea"
              :rows="4"
              placeholder="填写登录方式、注意事项和交接说明"
            />
            <el-button type="primary" :loading="handoffing" @click="handleSubmitHandoff">
              提交交接
            </el-button>
          </div>
        </div>

        <div
          v-if="
            isRenter &&
            order.status === 'pending_handoff' &&
            order.handoff_status === 'pending_renter_confirm'
          "
          class="handoff-confirm-strip"
        >
          <div>
            <strong>当前待办：确认收号</strong>
            <span>确认账号可以正常登录后，订单会进入使用中并重新计算预计截止时间。</span>
          </div>
          <el-button type="primary" :loading="confirming" @click="handleConfirmReceive">
            确认已收到账号
          </el-button>
        </div>

        <OrderResourceUsageEditor
          v-if="order && isRenter && ['renting', 'overdue'].includes(order.status)"
          v-model:checkout-form="checkoutForm"
          v-model:resource-usage="resourceUsage"
          :resources="checkoutResources"
          :resource-charge-amount="resourceChargeAmount"
          :snapshot-haf-coin-m="snapshotHafCoinM"
          :remaining-haf-coin-m="remainingHafCoinM"
          :returning="returning"
          :resource-line-amount="resourceLineAmount"
          @submit="handleSubmitCheckout"
        />

        <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">{{ orderHandoffStatusLabel(order) }}</strong>
          </div>
          <div class="metric-card highlight">
            <span class="metric-label">{{ orderAmountLabel }}</span>
            <strong class="metric-value amount">¥{{ money(orderRentDisplayAmount) }}</strong>
            <span v-if="isRenter && renterDiscountDisplayCent > 0" class="metric-note">
              {{ order.renter_growth_level_name || '成长等级' }}优惠 ¥{{
                money(amountYuan(renterDiscountDisplayCent))
              }}
            </span>
          </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)) }}</strong
            >
            <span v-if="amountYuan(order.deposit_waived_amount_cent) > 0" class="metric-note"
              >已免押 ¥{{ money(amountYuan(order.deposit_waived_amount_cent)) }}</span
            >
          </div>
          <div
            v-if="isRenter && order.status === 'completed' && !order.checkout"
            class="metric-card"
          >
            <span class="metric-label">实际纯币原价</span>
            <strong class="metric-value amount"
              >¥{{ money(amountYuan(order.actual_pure_coin_amount_cent)) }}</strong
            >
          </div>
          <div
            v-if="isRenter && order.status === 'completed' && !order.checkout"
            class="metric-card income"
          >
            <span class="metric-label">本单成长积分</span>
            <strong class="metric-value">+{{ order.growth_points_awarded || 0 }}</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' || canOpenDispute || canCancelDispute"
            class="secondary-actions"
          >
            <div v-if="order.status === 'pending_handoff'" class="secondary-action-card danger">
              <div>
                <strong>不继续交接？</strong>
                <span>取消后将提交退款申请，客服审核通过后账号才会恢复可租。</span>
              </div>
              <el-button type="danger" plain :loading="cancelling" @click="handleCancel">
                取消订单
              </el-button>
            </div>

            <div v-if="canOpenDispute || canCancelDispute" class="secondary-action-card support">
              <span class="support-dispute-icon">
                <el-icon><Service /></el-icon>
              </span>
              <div class="support-dispute-copy">
                <strong>{{ disputeSupportTitle }}</strong>
                <span>{{ disputeSupportMessage }}</span>
              </div>
              <el-button
                type="warning"
                plain
                :loading="cancellingDispute"
                @click="canCancelDispute ? handleCancelDispute() : openDisputeDialog()"
              >
                {{ disputeSupportActionText }}
              </el-button>
            </div>
          </div>
        </div>

        <div class="handoff-workspace">
          <OrderHandoffTimeline
            v-if="order"
            :records="handoffRecords"
            :listing-code="listingCode"
          />
        </div>

        <OrderCheckoutSummary
          v-if="
            order &&
            order.checkout &&
            [
              'pending_checkout_confirm',
              'pending_checkout_accept',
              'checkout_disputing',
              'completed',
            ].includes(order.status)
          "
          :order="order"
          :is-owner="isOwner"
          :is-renter="isRenter"
        />

        <div v-if="showCheckoutCounterForm" class="form-section counter-checkout-section">
          <div class="section-header">
            <h2>修改结账方案</h2>
            <span v-if="checkoutRoundLabel">{{ checkoutRoundLabel }}</span>
          </div>
          <div class="form-card">
            <p class="form-hint">
              双方最多协商 6 轮。可填写<strong>实际哈夫币消耗</strong>（允许超过发布量）。
              押金不足时无法自动完结，需改方案或发起争议。
            </p>
            <p v-if="checkoutShortfallCent > 0" class="form-hint" style="color: #dc2626">
              当前方案押金不足差额 ¥{{ money(amountYuan(checkoutShortfallCent)) }}，无法同意完结。
            </p>
            <p v-else-if="checkoutOvershootCent > 0" class="form-hint">
              当前打超 ¥{{ money(amountYuan(checkoutOvershootCent)) }}，将从押金扣除。
            </p>
            <h3 class="sub-title">调整消耗与扣款</h3>
            <el-form class="form-grid" label-position="top">
              <el-form-item label="额外消耗品已用金额">
                <el-input-number
                  v-model="counterForm.consumableAmountYuan"
                  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.depositDeductAmountYuan"
                  class="full-control"
                  :min="0"
                  :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"
            >
              {{ isOwner ? '提交修正给租客' : '提交还价给号主' }}
            </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>

        <!-- 账号快照放最下方，默认折叠 -->
        <OrderAccountSnapshot v-if="order" :order="order" variant="desktop" />
      </div>

      <!-- 右侧悬浮操作区 -->
      <div v-if="order && hasSidebarActions" class="action-sidebar">
        <!-- 确认结账 -->
        <div v-if="isOwner && order.status === 'pending_checkout_confirm'" class="sidebar-card">
          <h3 class="sidebar-title">确认结账</h3>
          <p v-if="checkoutRoundLabel" class="sidebar-hint">{{ checkoutRoundLabel }}</p>
          <p v-if="checkoutShortfallCent > 0" class="sidebar-hint" style="color: #dc2626">
            押金不足，无法同意完结
          </p>
          <el-button
            type="primary"
            size="large"
            :loading="completing"
            :disabled="!canAcceptCheckoutProposal"
            @click="handleConfirmCheckout"
          >
            确认结账并完成订单
          </el-button>
          <div v-if="canCounterCheckout" class="section-divider-mini">
            <span>或者</span>
          </div>
          <el-button
            v-if="canCounterCheckout"
            type="warning"
            plain
            size="large"
            @click="scrollToCounterCheckout"
          >
            修改结账方案
          </el-button>
          <p class="sidebar-hint">双方可多轮协商（最多 6 轮）；押金不足请改方案或争议</p>
        </div>

        <!-- 确认修正结账 -->
        <div v-if="isRenter && order.status === 'pending_checkout_accept'" class="sidebar-card">
          <h3 class="sidebar-title">确认结账方案</h3>
          <p v-if="checkoutRoundLabel" class="sidebar-hint">{{ checkoutRoundLabel }}</p>
          <p v-if="checkoutShortfallCent > 0" class="sidebar-hint" style="color: #dc2626">
            押金不足，无法同意完结
          </p>
          <el-button
            type="primary"
            size="large"
            :loading="acceptingCheckout"
            :disabled="!canAcceptCheckoutProposal"
            @click="handleAcceptCheckout"
          >
            同意并完成订单
          </el-button>
          <div v-if="canCounterCheckout" class="section-divider-mini">
            <span>或者</span>
          </div>
          <el-button
            v-if="canCounterCheckout"
            type="warning"
            plain
            size="large"
            @click="scrollToCounterCheckout"
          >
            还价修改方案
          </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>
    </div>

    <el-dialog
      v-model="disputeDialogVisible"
      :title="isCheckoutDisputeStage ? '发起结账争议' : '发起申诉'"
      width="720px"
      append-to-body
      class="dispute-dialog"
    >
      <div v-if="order && canOpenDispute" class="dispute-dialog-body">
        <div class="dispute-dialog-tip">
          <span class="support-dispute-icon">
            <el-icon><Service /></el-icon>
          </span>
          <p>
            {{
              isCheckoutDisputeStage
                ? '提交后客服会核查结账金额和双方证据。'
                : '请尽量写清楚时间点、问题经过和证据，便于客服快速处理。'
            }}
          </p>
        </div>
        <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>
      </div>
      <template #footer>
        <div class="dispute-dialog-footer">
          <el-button @click="closeDisputeDialog">取消</el-button>
          <el-button type="warning" :loading="disputing" @click="handleCreateDispute">
            {{ isCheckoutDisputeStage ? '提交结账争议' : '提交申诉' }}
          </el-button>
        </div>
      </template>
    </el-dialog>

    <el-dialog
      v-model="payWayDialogVisible"
      title="选择支付方式"
      width="420px"
      append-to-body
      :z-index="4000"
      class="pay-way-dialog"
      @closed="handlePayWayDialogClosed"
    >
      <p class="pay-way-tip">选择渠道后将生成对应的支付二维码</p>
      <div class="pay-way-options">
        <button type="button" class="pay-way-option wechat" @click="choosePayWay('WXZF')">
          <span class="pay-way-icon">
            <van-icon name="wechat-pay" :size="30" />
          </span>
          <span class="pay-way-text">
            <strong>微信支付</strong>
            <small>使用微信扫码完成支付</small>
          </span>
        </button>
        <button type="button" class="pay-way-option alipay" @click="choosePayWay('ZFBZF')">
          <span class="pay-way-icon">
            <van-icon name="alipay" :size="30" />
          </span>
          <span class="pay-way-text">
            <strong>支付宝支付</strong>
            <small>使用支付宝扫码完成支付</small>
          </span>
        </button>
      </div>
    </el-dialog>

    <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>¥{{ formatCent(activePayment.amount_cent) }}</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>请使用{{ activePayWayLabel }}扫码支付</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: 1280px;
  margin: 0 auto;
}

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

.page-header.centered {
  max-width: 940px;
  margin-right: auto;
  margin-left: auto;
}

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

.header-info {
  flex: 1;
}

.header-info h1 {
  margin: 4px 0 0;
  font-size: 26px;
  line-height: 1.25;
}

.order-meta {
  color: #64748b;
  margin: 6px 0 10px;
}

.content-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 280px;
  gap: 16px;
  align-items: start;
}

.content-layout.centered {
  grid-template-columns: minmax(0, 1fr);
  max-width: 940px;
  margin: 0 auto;
}

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

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

.sidebar-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  background: #ffffff;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  box-shadow: 0 1px 4px rgba(15, 23, 42, 0.05);
}

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

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

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

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

.support-dispute-icon {
  display: grid;
  flex: none;
  width: 32px;
  height: 32px;
  place-items: center;
  border-radius: 8px;
  background: #fff1d6;
  color: #d97706;
  font-size: 18px;
}

.support-dispute-copy {
  display: grid;
  gap: 2px;
  min-width: 0;
  flex: 1;
}

.support-dispute-copy strong {
  color: #1f2937;
  font-size: 14px;
  line-height: 1.3;
}

.support-dispute-copy span {
  color: #7c5a16;
  font-size: 12px;
  line-height: 1.45;
}

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

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

.metric-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-height: 86px;
  padding: 14px;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  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: 12px;
  color: #64748b;
  font-weight: 500;
}

.metric-value {
  font-size: 20px;
  font-weight: 700;
  color: #1f2937;
  line-height: 1.2;
}

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

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

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

.info-card {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  padding: 14px 16px;
  background: #ffffff;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
}

.info-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0;
}

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

.info-value {
  font-size: 13px;
  color: #1f2937;
  font-weight: 600;
  text-align: right;
}

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

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

.action-message {
  margin: 0 0 12px 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: 10px;
}

.section-header.compact span {
  color: #64748b;
  font-size: 12px;
}

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

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

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

.handoff-action-section {
  margin-bottom: 14px;
}

.handoff-action-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 160px;
  gap: 12px;
  align-items: stretch;
  padding: 16px;
  border: 1px solid #bfdbfe;
  border-radius: 8px;
  background: linear-gradient(180deg, #f8fbff 0%, #eff6ff 100%);
}

.handoff-action-card .el-button {
  height: 100%;
  min-height: 96px;
}

.handoff-confirm-strip {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
  padding: 16px;
  border: 1px solid #bfdbfe;
  border-radius: 8px;
  background: linear-gradient(180deg, #f8fbff 0%, #eff6ff 100%);
}

.handoff-confirm-strip div {
  display: grid;
  gap: 4px;
  flex: 1;
  min-width: 0;
}

.handoff-confirm-strip strong {
  color: #1f2937;
  font-size: 14px;
}

.handoff-confirm-strip span {
  color: #475569;
  font-size: 12px;
  line-height: 1.45;
}

.secondary-actions {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 10px;
  margin-top: 12px;
}

.secondary-action-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 8px;
}

.secondary-action-card > div {
  display: grid;
  gap: 2px;
  min-width: 0;
  flex: 1;
}

.secondary-action-card strong {
  color: #1f2937;
  font-size: 13px;
  line-height: 1.3;
}

.secondary-action-card span {
  color: #64748b;
  font-size: 12px;
  line-height: 1.45;
}

.secondary-action-card.danger {
  border: 1px solid #fecaca;
  background: #fff7f7;
}

.secondary-action-card.support {
  border: 1px solid #f8d99b;
  background: #fffaf0;
}

.form-hint {
  margin: 0;
  padding: 10px 12px;
  background: #f8fafc;
  border-left: 3px solid #3b82f6;
  color: #475569;
  font-size: 13px;
  line-height: 1.5;
  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: 15px;
  font-weight: 600;
  color: #374151;
  margin: 0 0 6px 0;
}

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

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

.dispute-dialog-body {
  display: grid;
  gap: 12px;
}

.dispute-dialog-tip {
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 10px 12px;
  border: 1px solid #f8d99b;
  border-radius: 8px;
  background: #fffaf0;
}

.dispute-dialog-tip p {
  margin: 0;
  color: #7c5a16;
  font-size: 13px;
  line-height: 1.5;
}

.dispute-dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

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

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

:global(.dispute-dialog) {
  border-radius: 12px;
}

:global(.dispute-dialog .el-dialog__body) {
  padding: 14px 20px 8px;
}

:global(.dispute-dialog .el-dialog__footer) {
  padding: 12px 20px 18px;
}

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

.pay-way-tip {
  margin: 0 0 16px 0;
  color: #64748b;
  font-size: 14px;
}

.pay-way-options {
  display: grid;
  gap: 12px;
}

.pay-way-option {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 18px;
  background: #ffffff;
  border: 2px solid #e5e7eb;
  border-radius: 12px;
  cursor: pointer;
  text-align: left;
  transition: all 0.18s ease;
}

.pay-way-option:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08);
}

.pay-way-icon {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 12px;
  color: #ffffff;
  flex-shrink: 0;
}

.pay-way-option.wechat:hover {
  border-color: #07c160;
}

.pay-way-option.wechat .pay-way-icon {
  background: #07c160;
}

.pay-way-option.alipay:hover {
  border-color: #1677ff;
}

.pay-way-option.alipay .pay-way-icon {
  background: #1677ff;
}

.pay-way-text {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.pay-way-text strong {
  font-size: 16px;
  font-weight: 600;
  color: #1f2937;
}

.pay-way-text small {
  font-size: 13px;
  color: #94a3b8;
}

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

:global(.pay-way-dialog .el-dialog__header) {
  padding: 20px 24px 0;
}

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

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

  .handoff-action-card,
  .handoff-confirm-strip,
  .secondary-action-card {
    grid-template-columns: 1fr;
    flex-direction: column;
    align-items: stretch;
  }

  .handoff-action-card .el-button {
    min-height: 40px;
  }

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

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

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