<script setup lang="ts">
import { ref, onMounted, computed, watch, onBeforeUnmount } from 'vue'
import { storeToRefs } from 'pinia'
import { useI18n } from 'vue-i18n'
import { useDepositStore } from '@/stores/deposit'
import { rechargeStatusTranslate } from '@/utils/rechargeI18n'
import { useToast } from '@/composables/useToast'
import { useWalletConnectDeposit } from '@/composables/useWalletConnectDeposit'
import { useWalletConnectTronDeposit } from '@/composables/useWalletConnectTronDeposit'
import { resolveEvmChainId } from '@/utils/evmRecharge'
import { qrCodeImageUrl } from '@/utils/qr'
import { WalletFlowCancelledError } from '@/utils/reownConnectWait'

const DEPOSIT_MODE_KEY = 'ibit-deposit-mode'

function loadDepositMode(): 'manual' | 'wallet' {
  try {
    const stored = sessionStorage.getItem(DEPOSIT_MODE_KEY)
    if (stored === 'manual' || stored === 'wallet') {
      return stored
    }
  } catch {
    // ignore
  }
  return 'manual'
}

function saveDepositMode(mode: 'manual' | 'wallet') {
  try {
    sessionStorage.setItem(DEPOSIT_MODE_KEY, mode)
  } catch {
    // ignore
  }
}

const { t } = useI18n()
const store = useDepositStore()
const {
  parentCoins,
  selectedParentIndex,
  selectedNetworkId,
  selectedSubCoinIndex,
  networkOptions,
  subCoinOptions,
  loadingParents,
  childrenLoading,
  subCoinsLoading,
  error,
  currentOrder,
  orderSubmitting,
  hashSubmitting,
  selectedParent,
  selectedNetwork,
  selectedConfig,
} = storeToRefs(store)

const toast = useToast()
const { wcBusy, wcConfigured, resetWalletBusy, canPayWithWallet, connectAndPay } = useWalletConnectDeposit()
const { wcTronBusy, wcTronConfigured, resetTronWalletBusy, canPayTronWithWallet, connectAndPayTron } =
  useWalletConnectTronDeposit()

const canUseWalletConnect = computed(() =>
  canPayWithWallet(selectedNetwork.value, currentOrder.value),
)
const canUseTronWalletConnect = computed(() =>
  canPayTronWithWallet(selectedNetwork.value, currentOrder.value),
)
const anyWcBusy = computed(() => wcBusy.value || wcTronBusy.value)
const isTronLikeNetwork = computed(() => {
  const o = selectedNetwork.value
  if (!o) {
    return false
  }
  if (resolveEvmChainId(o.protocol, o.networkName) !== null) {
    return false
  }
  const p = o.protocol.toLowerCase()
  const n = o.networkName.toLowerCase()
  return p.includes('tron') || n === 'trc20'
})

const amount = ref('')
const amountError = ref('')
const txHashInput = ref('')
const txHashError = ref('')
const rechargeQrUrl = ref<string | null>(null)
const depositMode = ref<'manual' | 'wallet'>(loadDepositMode())
/** 创建订单后锁定充值方式，链上/手工不可再切换 */
const depositModeLocked = ref(false)
const walletAttemptSeq = ref(0)

watch(depositMode, (mode) => {
  if (!depositModeLocked.value) {
    saveDepositMode(mode)
  }
})

watch(
  () => currentOrder.value?.rechargeAddress?.trim() ?? '',
  async (addr) => {
    if (!addr) {
      rechargeQrUrl.value = null
      return
    }
    try {
      rechargeQrUrl.value = await qrCodeImageUrl(addr, 200)
    } catch {
      rechargeQrUrl.value = null
    }
  },
  { immediate: true },
)

onMounted(() => {
  if (currentOrder.value) {
    depositModeLocked.value = true
  }
  store.loadParentCoins().catch(() => {
    toast.error(store.error ?? t('common.loadFailed'))
  })
})

async function onSelectParent(i: number) {
  try {
    await store.selectParent(i)
  } catch {
    toast.error(store.error ?? t('deposit.loadNetworksFailed'))
  }
}

async function onSelectNetwork(networkId: number) {
  try {
    await store.selectNetwork(networkId)
  } catch {
    toast.error(store.error ?? t('deposit.loadNetworksFailed'))
  }
}

function onSelectSubCoin(i: number) {
  store.selectSubCoin(i)
}

function subCoinTabLabel(opt: { coinName: string; coinNameCn: string }) {
  const cn = opt.coinNameCn?.trim()
  if (cn && cn !== opt.coinName) {
    return `${cn} (${opt.coinName})`
  }
  return opt.coinName
}

function validateAmount(): boolean {
  amountError.value = ''
  const s = amount.value.trim()
  if (!s) {
    amountError.value = t('deposit.amountRequired')
    return false
  }
  const n = Number(s)
  if (!Number.isFinite(n) || n <= 0) {
    amountError.value = t('deposit.amountPositive')
    return false
  }
  return true
}

async function onCreateOrder() {
  if (!validateAmount()) {
    return
  }
  resetPendingWalletUi()
  try {
    await store.createRechargeOrder(amount.value)
    depositModeLocked.value = true
    saveDepositMode(depositMode.value)
    txHashInput.value = ''
    txHashError.value = ''
    toast.success(t('deposit.orderCreated'))
  } catch {
    toast.error(store.error ?? t('deposit.orderFailed'))
  }
}

function copyAddress() {
  const addr = currentOrder.value?.rechargeAddress
  if (!addr) {
    return
  }
  navigator.clipboard.writeText(addr).then(() => {
    toast.success(t('deposit.addressCopy'))
  })
}

function copyOrderNo() {
  const no = currentOrder.value?.orderNo
  if (!no) {
    return
  }
  navigator.clipboard.writeText(no).then(() => {
    toast.success(t('deposit.orderNoCopy'))
  })
}

// function validateTxHash(): boolean {
//   txHashError.value = ''
//   const s = txHashInput.value.trim()
//   if (!s) {
//     txHashError.value = t('deposit.hashRequired')
//     return false
//   }
//   return true
// }

onBeforeUnmount(() => {
  resetPendingWalletUi()
})

function isWalletConnectCancelError(e: unknown): boolean {
  if (e instanceof WalletFlowCancelledError) {
    return true
  }
  const msg = e instanceof Error ? e.message : typeof e === 'string' ? e : ''
  const normalized = msg.toLowerCase()
  const code = e && typeof e === 'object' && 'code' in e ? Number((e as { code?: unknown }).code) : NaN
  return (
    code === 4001 ||
    normalized.includes('connection request reset') ||
    normalized.includes('user rejected') ||
    normalized.includes('user denied') ||
    normalized.includes('user closed') ||
    normalized.includes('user cancelled') ||
    normalized.includes('user canceled') ||
    normalized.includes('rejected the request') ||
    normalized.includes('rejected transaction') ||
    normalized.includes('modal closed') ||
    normalized.includes('proposal expired') ||
    normalized.includes('action_rejected')
  )
}

// async function onSubmitHash() {
//   const o = currentOrder.value
//   if (!o?.orderNo) {
//     return
//   }
//   if (Number(o.status) !== 0) {
//     toast.error(t('deposit.statusNotSubmittable'))
//     return
//   }
//   if (!validateTxHash()) {
//     return
//   }
//   try {
//     await store.submitTxHash(o.orderNo, txHashInput.value)
//     toast.success(t('deposit.hashSubmitted'))
//   } catch {
//     toast.error(store.error ?? t('deposit.hashFailed'))
//   }
// }

async function onWalletPay() {
  const o = currentOrder.value
  const net = selectedNetwork.value
  if (!o?.orderNo || !net || Number(o.status) !== 0) {
    return
  }
  const seq = ++walletAttemptSeq.value
  try {
    const hash = await connectAndPay({ network: net, order: o })
    if (seq !== walletAttemptSeq.value || currentOrder.value?.orderNo !== o.orderNo) {
      return
    }
    txHashInput.value = hash
    await store.submitTxHash(o.orderNo, hash)
    toast.success(t('deposit.broadcastSuccess'))
  } catch (e) {
    if (isWalletConnectCancelError(e)) {
      resetWalletBusy()
      return
    }
    const msg = e instanceof Error ? e.message : t('deposit.walletPayFallback')
    toast.error(msg)
  }
}

async function onTronWalletPay() {
  const o = currentOrder.value
  const net = selectedNetwork.value
  if (!o?.orderNo || !net || Number(o.status) !== 0) {
    return
  }
  const seq = ++walletAttemptSeq.value
  try {
    const txid = await connectAndPayTron({ network: net, order: o })
    if (seq !== walletAttemptSeq.value || currentOrder.value?.orderNo !== o.orderNo) {
      return
    }
    txHashInput.value = txid
    await store.submitTxHash(o.orderNo, txid)
    toast.success(t('deposit.tronBroadcastSuccess'))
  } catch (e) {
    if (isWalletConnectCancelError(e)) {
      resetTronWalletBusy()
      return
    }
    const msg = e instanceof Error ? e.message : t('deposit.tronWalletPayFallback')
    toast.error(msg)
  }
}

function resetPendingWalletUi() {
  walletAttemptSeq.value += 1
  resetWalletBusy()
  resetTronWalletBusy()
}

function onNewDeposit() {
  resetPendingWalletUi()
  store.clearCurrentOrder()
  amount.value = ''
  amountError.value = ''
  txHashInput.value = ''
  txHashError.value = ''
  depositModeLocked.value = false
  depositMode.value = 'wallet'
}

function statusLabel(status: number) {
  return rechargeStatusTranslate(t, status)
}
</script>

<template>
  <main class="page-main">
    <div class="page-container content">
      <div class="page-header">
        <RouterLink to="/assets" class="back-link">{{ t('deposit.backWithArrow') }}</RouterLink>
        <div class="title-row">
          <h1 class="page-title">{{ t('deposit.title') }}</h1>
          <RouterLink to="/assets/deposit/history" class="hist-link">{{ t('deposit.histLink') }}</RouterLink>
        </div>
      </div>

      <div v-if="loadingParents" class="loading-state">
        <div class="spinner" />
      </div>

      <div v-else-if="error && !parentCoins.length" class="error-state dark-card">
        <p class="error-msg">{{ error }}</p>
        <button class="retry-btn" type="button" @click="store.loadParentCoins()">{{ t('deposit.retryBtn') }}</button>
      </div>

      <template v-else-if="parentCoins.length">
        <!-- 已创建订单：展示付款与回写 hash -->
        <template v-if="currentOrder">
          <div class="toolbar-row">
            <button type="button" class="link-btn" @click="onNewDeposit">{{ t('deposit.newDeposit') }}</button>
          </div>
          <div class="form-card dark-card order-detail-card">
              <h2 class="section-title order-title">{{ t('deposit.orderInfo') }}</h2>
              <div class="order-meta">
                <div class="meta-row">
                  <span class="meta-k">{{ t('deposit.orderNo') }}</span>
                  <span class="meta-v">{{ currentOrder.orderNo }}</span>
                  <button type="button" class="mini-copy" @click="copyOrderNo">{{ t('deposit.copyAddress') }}</button>
                </div>
                <div class="meta-row">
                  <span class="meta-k">{{ t('deposit.status') }}</span>
                  <span class="meta-v status" :class="'st-' + currentOrder.status">{{ statusLabel(Number(currentOrder.status)) }}</span>
                </div>
                <div class="meta-row">
                  <span class="meta-k">{{ t('deposit.coinLabel') }}</span>
                  <span class="meta-v">{{ currentOrder.coinName }}</span>
                </div>
                <div class="meta-row">
                  <span class="meta-k">{{ t('deposit.networkLabel') }}</span>
                  <span class="meta-v">{{ currentOrder.networkName }}</span>
                </div>
                <div class="meta-row">
                  <span class="meta-k">{{ t('deposit.amount') }}</span>
                  <span class="meta-v amt">{{ currentOrder.amount }}</span>
                </div>
              </div>

              <div class="pay-destination">
                <h3 class="sub-section-title">{{ t('deposit.payAddress') }}</h3>
                <p class="addr-hint">{{ t('deposit.payAddressHint') }}</p>
                <div class="addr-row">
                  <p class="addr-text">{{ currentOrder.rechargeAddress || '-' }}</p>
                  <button type="button" class="copy-btn" @click="copyAddress">{{ t('deposit.copyAddress') }}</button>
                </div>
                <div v-if="depositMode === 'manual' && rechargeQrUrl" class="qr-block">
                  <h3 class="sub-section-title qr-block-title">{{ t('deposit.qrTitle') }}</h3>
                  <p class="addr-hint">{{ t('deposit.qrHint') }}</p>
                  <div class="qr-frame">
                    <img class="qr-img" :src="rechargeQrUrl" :alt="t('deposit.qrAlt')" width="200" height="200">
                  </div>
                </div>
                <div v-if="depositMode === 'manual' && selectedNetwork?.contractAddress" class="contract-box">
                  <span class="meta-k">{{ t('deposit.contractAddress') }}</span>
                  <p class="mono small">{{ selectedNetwork.contractAddress }}</p>
                </div>
                <template v-if="depositMode === 'wallet' && Number(currentOrder.status) === 0">
                  <p class="wc-hint" v-if="canUseWalletConnect && wcConfigured">
                    {{ t('deposit.wcHintEvmConfigured') }}
                  </p>
                  <p class="wc-hint muted" v-if="canUseWalletConnect && !wcConfigured">
                    {{ t('deposit.wcHintEvmUnconfigured') }}
                  </p>
                  <p class="wc-hint" v-if="isTronLikeNetwork && canUseTronWalletConnect && wcTronConfigured">
                    {{ t('deposit.wcHintTronConfigured') }}
                  </p>
                  <p class="wc-hint muted" v-if="isTronLikeNetwork && canUseTronWalletConnect && !wcTronConfigured">
                    {{ t('deposit.wcHintTronUnconfigured') }}
                  </p>
                  <p class="wc-hint muted" v-if="isTronLikeNetwork && !canUseTronWalletConnect">
                    {{ t('deposit.wcHintTronManualOnly') }}
                  </p>
                  <button
                    v-if="canUseWalletConnect && wcConfigured"
                    type="button"
                    class="wc-btn"
                    :disabled="anyWcBusy || hashSubmitting"
                    @click="onWalletPay"
                  >
                    {{ wcBusy ? t('deposit.walletPayingEvm') : t('deposit.walletPayEvm') }}
                  </button>
                  <button
                    v-if="isTronLikeNetwork && canUseTronWalletConnect && wcTronConfigured"
                    type="button"
                    class="wc-btn"
                    :disabled="anyWcBusy || hashSubmitting"
                    @click="onTronWalletPay"
                  >
                    {{ wcTronBusy ? t('deposit.walletPayingTron') : t('deposit.walletPayTron') }}
                  </button>
                </template>
              </div>

              <!-- <div v-if="Number(currentOrder.status) === 0" class="hash-block">
                <p class="form-label hash-label">{{ t('deposit.orSubmitHash') }}</p>
                <input
                  v-model="txHashInput"
                  type="text"
                  class="text-input"
                  :placeholder="t('deposit.hashPlaceholder')"
                  autocomplete="off"
                >
                <p v-if="txHashError" class="field-err">{{ txHashError }}</p>
                <button
                  type="button"
                  class="primary-btn"
                  :disabled="hashSubmitting || anyWcBusy"
                  @click="onSubmitHash"
                >
                  {{ hashSubmitting ? t('deposit.submittingHash') : t('deposit.submitHash') }}
                </button>
              </div>
              <p v-else-if="currentOrder.txHash" class="hash-done">
                {{ t('deposit.submittedHash') }}<span class="mono">{{ currentOrder.txHash }}</span>
              </p> -->
          </div>
        </template>

        <!-- 未创建订单：选币种与网络、填金额 -->
        <template v-else>
          <div class="two-col">
            <div class="form-column">
              <div class="mode-tabs">
                <button
                  type="button"
                  class="mode-tab"
                  :class="{ active: depositMode === 'wallet' }"
                  @click="depositMode = 'wallet'"
                >
                  {{ t('deposit.walletDepositTab') }}
                </button>
                <button
                  type="button"
                  class="mode-tab"
                  :class="{ active: depositMode === 'manual' }"
                  @click="depositMode = 'manual'"
                >
                  {{ t('deposit.manualDepositTab') }}
                </button>
              </div>

              <div class="form-card dark-card">
              <div v-if="parentCoins.length > 1" class="form-group">
                <p class="form-label">{{ t('deposit.coin') }}</p>
                <div class="network-tabs">
                  <button
                    v-for="(p, i) in parentCoins"
                    :key="p.name"
                    type="button"
                    class="net-tab"
                    :class="{ active: selectedParentIndex === i }"
                    @click="onSelectParent(i)"
                  >
                    {{ p.nameCn || p.unit || p.name }}
                  </button>
                </div>
              </div>

              <div class="form-group">
                <p class="form-label">{{ t('deposit.protocol') }}</p>
                <div v-if="childrenLoading" class="sub-loading">
                  <div class="spinner sm" />
                </div>
                <div v-else-if="!networkOptions.length" class="empty-net">{{ t('deposit.noNetwork') }}</div>
                <div v-else class="network-tabs">
                  <button
                    v-for="net in networkOptions"
                    :key="net.id"
                    type="button"
                    class="net-tab"
                    :class="{ active: selectedNetworkId === net.id }"
                    @click="onSelectNetwork(net.id)"
                  >
                    {{ net.name }}{{ net.protocol ? ` · ${net.protocol}` : '' }}
                  </button>
                </div>
              </div>

              <div v-if="selectedNetworkId" class="form-group">
                <p class="form-label">{{ t('deposit.subCoin') }}</p>
                <div v-if="subCoinsLoading" class="sub-loading">
                  <div class="spinner sm" />
                </div>
                <div v-else-if="!subCoinOptions.length" class="empty-net">{{ t('deposit.noSubCoin') }}</div>
                <div v-else class="network-tabs">
                  <button
                    v-for="(opt, i) in subCoinOptions"
                    :key="opt.coinName + '-' + opt.networkConfigId"
                    type="button"
                    class="net-tab"
                    :class="{ active: selectedSubCoinIndex === i }"
                    @click="onSelectSubCoin(i)"
                  >
                    {{ subCoinTabLabel(opt) }}
                  </button>
                </div>
              </div>

              <div v-if="selectedNetwork?.contractAddress" class="net-detail">
                <div class="info-row">
                  <span class="info-label">{{ t('deposit.contract') }}</span>
                  <span class="info-val mono break">{{ selectedNetwork.contractAddress }}</span>
                </div>
              </div>

              <div class="form-group">
                <p class="form-label">{{ t('deposit.depositAmount') }}</p>
                <input
                  v-model="amount"
                  type="text"
                  inputmode="decimal"
                  class="text-input"
                  :placeholder="t('deposit.amountPlaceholder')"
                  autocomplete="off"
                >
                <p v-if="amountError" class="field-err">{{ amountError }}</p>
              </div>

              <button
                type="button"
                class="primary-btn full"
                :disabled="orderSubmitting || !selectedNetwork"
                @click="onCreateOrder"
              >
                {{ orderSubmitting ? t('deposit.generating') : t('deposit.generateOrder') }}
              </button>
              </div>
            </div>

            <div class="address-card dark-card muted-card">
              <h2 class="addr-title">{{ t('deposit.intro') }}</h2>
              <p class="hint-p">{{ t('deposit.introText') }}</p>
              <p v-if="selectedParent" class="hint-p">
                {{ t('deposit.currentPrefix') }}<strong>{{ selectedParent.nameCn || selectedParent.name }}</strong>
                <template v-if="selectedNetwork"> - {{ selectedNetwork.networkName }}{{ selectedConfig ? ` / ${selectedConfig.coinName}` : '' }}</template>
              </p>
            </div>
          </div>
        </template>
      </template>
    </div>
  </main>
</template>

<style scoped>
.content { padding-top: var(--space-8); padding-bottom: var(--space-16); max-width: 780px; }
.page-header { margin-bottom: var(--space-5); }
.back-link { font-size: var(--text-small); color: var(--color-text-secondary); display: inline-block; margin-bottom: var(--space-3); text-decoration: none; }
.back-link:hover { color: var(--color-primary); }
.title-row { display: flex; align-items: center; justify-content: space-between; }
.page-title { font-size: var(--text-h1); font-weight: var(--fw-bold); color: var(--color-text-primary); line-height: 1.15; }
.hist-link { font-size: var(--text-small); color: var(--color-primary); text-decoration: none; }
.loading-state { display: flex; justify-content: center; padding: var(--space-16); }
.spinner { width: 32px; height: 32px; border-radius: 50%; border: 2px solid var(--color-border); border-top-color: var(--color-primary); animation: spin .8s linear infinite; }
.spinner.sm { width: 22px; height: 22px; border-width: 2px; }
@keyframes spin { to { transform: rotate(360deg); } }
.sub-loading { display: flex; padding: var(--space-4); }
.error-state { padding: var(--space-8); text-align: center; }
.error-msg { color: var(--color-text-secondary); margin-bottom: var(--space-4); }
.retry-btn { background: transparent; border: 1px solid var(--color-primary); border-radius: var(--radius-md); color: var(--color-primary); padding: var(--space-2) var(--space-5); cursor: pointer; }
.toolbar-row { margin-bottom: var(--space-3); }
.link-btn { background: none; border: none; color: var(--color-primary); font-size: var(--text-small); cursor: pointer; padding: 0; }
.link-btn:hover { opacity: .85; }
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); align-items: start; }
.form-column { min-width: 0; }
.form-card, .address-card { background: #151515; padding: var(--space-5); border-color: rgba(255,255,255,.06); }
.address-card { min-height: 330px; }
.muted-card { opacity: .96; }
.mode-tabs { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); margin-bottom: var(--space-4); }
.mode-tab {
  height: 40px;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  background: #101010;
  color: var(--color-text-primary);
  font-size: var(--text-small);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition: all var(--transition);
}
.mode-tab.active { background: var(--color-primary); color: #0a0a0a; box-shadow: 0 6px 18px rgba(240,185,11,.18); }
.section-title { font-size: var(--text-body); font-weight: var(--fw-semibold); color: var(--color-text-primary); margin-bottom: var(--space-5); }
.order-detail-card { max-width: 720px; margin: 0 auto; padding: var(--space-6); }
.order-title { text-align: center; margin-bottom: var(--space-6); }
.form-group { margin-bottom: var(--space-5); }
.form-label { font-size: var(--text-small); color: var(--color-text-secondary); margin-bottom: var(--space-2); display: block; }
.network-tabs { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.net-tab {
  padding: 7px var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text-secondary);
  font-size: var(--text-caption);
  cursor: pointer;
  transition: all var(--transition);
}
.net-tab:hover { border-color: var(--color-primary); color: var(--color-primary); }
.net-tab.active { border-color: rgba(240,185,11,.7); background: rgba(240,185,11,.1); color: var(--color-primary); }
.empty-net { font-size: var(--text-small); color: var(--color-text-muted); padding: var(--space-3); }
.net-detail { background: rgba(255,255,255,.03); border-radius: var(--radius-md); padding: var(--space-4); margin-bottom: var(--space-5); }
.info-row { display: flex; justify-content: space-between; gap: var(--space-3); padding: var(--space-2) 0; align-items: flex-start; }
.info-label { font-size: var(--text-small); color: var(--color-text-secondary); flex-shrink: 0; }
.info-val { font-size: var(--text-small); color: var(--color-text-primary); font-weight: var(--fw-medium); text-align: right; }
.text-input {
  width: 100%;
  box-sizing: border-box;
  padding: var(--space-3) var(--space-4);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  outline: none;
  background: #202020;
  color: var(--color-text-primary);
  font-size: var(--text-small);
}
.text-input:focus { border-color: rgba(240,185,11,.35); }
.text-input::placeholder { color: var(--color-text-muted); }
.field-err { font-size: 12px; color: var(--color-down); margin-top: var(--space-2); }
.primary-btn {
  margin-top: var(--space-3);
  min-width: 150px;
  padding: 13px var(--space-6);
  border: none;
  border-radius: var(--radius-md);
  background: var(--color-primary);
  color: #0a0a0a;
  font-weight: var(--fw-semibold);
  cursor: pointer;
}
.primary-btn:disabled { opacity: .5; cursor: not-allowed; }
.primary-btn.full { width: 100%; margin-top: var(--space-5); }
.addr-title { font-size: var(--text-body); font-weight: var(--fw-semibold); color: var(--color-text-primary); margin-bottom: var(--space-4); }
.addr-hint { font-size: var(--text-caption); color: var(--color-text-muted); line-height: 1.6; margin-bottom: var(--space-4); }
.addr-row { display: flex; align-items: flex-start; gap: var(--space-3); }
.addr-text { flex: 1; font-size: var(--text-caption); color: var(--color-text-secondary); font-family: var(--font-family-num); word-break: break-all; line-height: 1.5; }
.copy-btn { white-space: nowrap; background: none; border: none; color: var(--color-text-secondary); font-size: var(--text-caption); cursor: pointer; flex-shrink: 0; }
.copy-btn:hover { color: var(--color-primary); }
.qr-block { margin-top: var(--space-5); }
.qr-block-title { margin-bottom: var(--space-2); }
.qr-frame { display: inline-flex; padding: var(--space-3); background: #fff; border-radius: var(--radius-md); }
.qr-img { display: block; width: 152px; height: 152px; }
.order-meta { display: flex; flex-direction: column; gap: var(--space-3); }
.meta-row { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; font-size: var(--text-small); }
.meta-k { color: var(--color-text-secondary); min-width: 64px; }
.meta-v { color: var(--color-text-primary); font-weight: var(--fw-medium); }
.meta-v.amt { font-family: var(--font-family-num); }
.meta-v.status.st-0, .meta-v.status.st-1 { color: var(--color-primary); }
.meta-v.status.st-2 { color: var(--color-up); }
.meta-v.status.st-3, .meta-v.status.st-4 { color: var(--color-text-muted); }
.mini-copy { font-size: 12px; padding: 2px 8px; border: none; border-radius: var(--radius-sm); background: rgba(255,255,255,.04); color: var(--color-text-secondary); cursor: pointer; }
.mini-copy:hover { color: var(--color-primary); }
.pay-destination { margin-top: var(--space-6); padding-top: var(--space-5); border-top: 1px solid var(--color-border); }
.hash-block { margin-top: var(--space-5); }
.sub-section-title { font-size: var(--text-small); font-weight: var(--fw-semibold); color: var(--color-text-primary); margin-bottom: var(--space-2); }
.wc-hint { font-size: var(--text-caption); color: var(--color-text-secondary); line-height: 1.6; margin: var(--space-4) 0 var(--space-3); }
.wc-hint.muted { color: var(--color-text-muted); }
.wc-btn {
  width: 100%;
  margin-bottom: var(--space-5);
  padding: var(--space-3) var(--space-6);
  border: 1px solid rgba(240,185,11,.5);
  border-radius: var(--radius-md);
  background: rgba(240,185,11,.14);
  color: var(--color-primary);
  font-weight: var(--fw-semibold);
  cursor: pointer;
}
.wc-btn:disabled { opacity: .5; cursor: not-allowed; }
.hash-label { margin-top: var(--space-4); }
.hash-done { margin-top: var(--space-5); font-size: var(--text-small); color: var(--color-text-secondary); word-break: break-all; }
.contract-box { margin-top: var(--space-5); padding: var(--space-4); background: rgba(255,255,255,.04); border-radius: var(--radius-md); }
.mono { font-family: var(--font-family-num); }
.mono.small { font-size: 12px; line-height: 1.5; word-break: break-all; }
.break { word-break: break-all; }
.hint-p { font-size: var(--text-small); color: var(--color-text-secondary); line-height: 1.8; margin-bottom: var(--space-4); }
.hint-p strong { color: var(--color-text-primary); font-weight: var(--fw-medium); }
@media (max-width: 768px) {
  .content { max-width: 100%; }
  .two-col { grid-template-columns: 1fr; }
  .address-card { min-height: 0; }
  .order-detail-card { padding: var(--space-5); }
}
</style>
