<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { useRoute } from 'vue-router'
import { useCoinsStore } from '@/stores/coins'
import { useMarketWs, type WsKlineBar } from '@/composables/useMarketWs'
import type { KlineResolution } from '@/stores/futures'
import PriceChart from '@/components/market/PriceChart.vue'

type ChartRange = '24h' | '1w' | '1m' | '1y'

const RANGE_RES: Record<ChartRange, KlineResolution> = {
  '24h': '15',
  '1w':  '60',
  '1m':  '240',
  '1y':  '1D',
}

const route   = useRoute()
const coinsStore = useCoinsStore()

const symbol = computed(() =>
  String(route.params.symbol).replace('-', '/').toUpperCase()
)
const coinInfo = computed(() =>
  coinsStore.coins.find(c => c.symbol === symbol.value)
)
const coinBase = computed(() => symbol.value.split('/')[0])

// ── Real-time data ─────────────────────────────────────
const currentPrice   = ref(0)
const open24h        = ref(0)
const high24h        = ref(0)
const low24h         = ref(0)
const volume24h      = ref(0)
const markPrice      = ref(0)
const fundingRate    = ref('0')

const priceChange    = computed(() =>
  open24h.value > 0 ? currentPrice.value - open24h.value : 0
)
const priceChangePct = computed(() =>
  open24h.value > 0 ? (priceChange.value / open24h.value) * 100 : 0
)

// ── Chart ──────────────────────────────────────────────
const chartRange = ref<ChartRange>('24h')
const klineBars  = ref<WsKlineBar[]>([])
const liveBar    = ref<WsKlineBar | null>(null)

// ── WebSocket ──────────────────────────────────────────
const ws = useMarketWs({
  onConnected() { ws.requestKlines(RANGE_RES[chartRange.value]) },
  onTicker(d) {
    currentPrice.value = parseFloat(d.close)
    open24h.value      = parseFloat(d.open)
    high24h.value      = parseFloat(d.high)
    low24h.value       = parseFloat(d.low)
    volume24h.value    = parseFloat(d.turnover)
  },
  onMark(d) {
    markPrice.value  = parseFloat(d.markPrice)
    fundingRate.value = d.fundingRate
  },
  onKline(bar)         { liveBar.value = bar },
  onKlineHistory(bars) { klineBars.value = bars; liveBar.value = null },
})

function seedFromStore() {
  const coin = coinInfo.value
  if (!coin) return
  currentPrice.value = parseFloat(coin.close   || '0')
  open24h.value      = parseFloat(coin.open    || '0')
  high24h.value      = parseFloat(coin.high    || '0')
  low24h.value       = parseFloat(coin.low     || '0')
  volume24h.value    = parseFloat(coin.turnover|| '0')
}

function onRangeChange(range: ChartRange) {
  chartRange.value = range
  klineBars.value  = []
  liveBar.value    = null
  ws.changeResolution(RANGE_RES[range])
}

onMounted(async () => {
  if (!coinsStore.fetched) await coinsStore.fetchCoins()
  seedFromStore()
  ws.connect(symbol.value, RANGE_RES[chartRange.value])
})
onUnmounted(() => ws.disconnect())

watch(() => route.params.symbol, () => {
  klineBars.value  = []
  liveBar.value    = null
  chartRange.value = '24h'
  seedFromStore()
  ws.connect(symbol.value, RANGE_RES['24h'])
})

// ── Format helpers ─────────────────────────────────────
function fmt(n: number, dp = 2) {
  if (!n) return '—'
  return n.toLocaleString('en-US', { minimumFractionDigits: dp, maximumFractionDigits: dp })
}
function fmtVol(n: number) {
  if (!n) return '—'
  if (n >= 1e8)  return (n / 1e8).toFixed(2) + '亿'
  if (n >= 1e4)  return (n / 1e4).toFixed(2) + '万'
  return n.toFixed(0)
}
function fmtRate(r: string) {
  const n = parseFloat(r)
  if (isNaN(n)) return '--'
  return (n >= 0 ? '+' : '') + (n * 100).toFixed(4) + '%'
}
</script>

<template>
  <main class="page-main">
    <div class="page-container detail-wrap">

      <!-- ── 标题行 ─────────────────────────── -->
      <div class="detail-head">
        <div class="head-left">
          <div class="coin-avatar">
            <img v-if="coinInfo?.icon" :src="coinInfo.icon" :alt="coinInfo.name" />
            <span v-else>{{ coinBase[0] }}</span>
          </div>
          <h1 class="coin-name">{{ coinInfo?.name ?? coinBase }}价格(USDT)</h1>
        </div>

        <div class="exchange-badge dark-card">
          1 {{ coinBase }} =
          <span class="badge-num num">{{ fmt(currentPrice) }}</span>
          USDT
        </div>
      </div>

      <!-- ── 元数据行 ───────────────────────── -->
      <div class="meta-row">
        <div class="meta-item">
          <span class="meta-label">24h成交额</span>
          <span class="meta-val num">{{ fmtVol(volume24h) }}</span>
        </div>
        <div class="meta-item">
          <span class="meta-label">24h最高</span>
          <span class="meta-val num">{{ fmt(high24h) }}</span>
        </div>
        <div class="meta-item">
          <span class="meta-label">24h最低</span>
          <span class="meta-val num">{{ fmt(low24h) }}</span>
        </div>
        <div class="meta-item">
          <span class="meta-label">标记价格</span>
          <span class="meta-val num">{{ fmt(markPrice) }}</span>
        </div>
        <div class="meta-item">
          <span class="meta-label">资金费率</span>
          <span class="meta-val num" :class="parseFloat(fundingRate) >= 0 ? 'text-up' : 'text-down'">
            {{ fmtRate(fundingRate) }}
          </span>
        </div>
      </div>

      <!-- ── 图表卡片 ───────────────────────── -->
      <PriceChart
        :current-price="currentPrice"
        :price-change="priceChange"
        :price-change-pct="priceChangePct"
        :bars="klineBars"
        :live-bar="liveBar"
        :chart-range="chartRange"
        @range-change="onRangeChange"
      />

      <!-- ── 统计卡片 ───────────────────────── -->
      <div class="stats-grid">
        <div class="stat-card dark-card">
          <div class="stat-label">24h涨跌幅</div>
          <div class="stat-pct" :class="priceChangePct >= 0 ? 'text-up' : 'text-down'">
            {{ priceChangePct >= 0 ? '+' : '' }}{{ priceChangePct.toFixed(2) }}%
          </div>
          <div class="stat-sub num">{{ fmt(currentPrice) }}</div>
        </div>
        <div class="stat-card dark-card">
          <div class="stat-label">24h最高价</div>
          <div class="stat-pct text-up">{{ fmt(high24h) }}</div>
          <div class="stat-sub">较开盘 +{{ high24h > 0 && open24h > 0 ? ((high24h - open24h) / open24h * 100).toFixed(2) : '0.00' }}%</div>
        </div>
        <div class="stat-card dark-card">
          <div class="stat-label">24h最低价</div>
          <div class="stat-pct text-down">{{ fmt(low24h) }}</div>
          <div class="stat-sub">较开盘 {{ low24h > 0 && open24h > 0 ? ((low24h - open24h) / open24h * 100).toFixed(2) : '0.00' }}%</div>
        </div>
        <div class="stat-card dark-card">
          <div class="stat-label">24h成交额</div>
          <div class="stat-pct" style="color:var(--color-text-primary)">{{ fmtVol(volume24h) }}</div>
          <div class="stat-sub">资金费率 {{ fmtRate(fundingRate) }}</div>
        </div>
      </div>

    </div>
  </main>
</template>

<style scoped>
.detail-wrap {
  padding-top: var(--space-8);
  padding-bottom: var(--space-16);
}

/* ── 标题行 ── */
.detail-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-5);
  flex-wrap: wrap;
  gap: var(--space-4);
}

.head-left {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

.coin-avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--color-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  font-weight: var(--fw-bold);
  color: #000;
  flex-shrink: 0;
  overflow: hidden;
}
.coin-avatar img { width: 100%; height: 100%; object-fit: cover; }
.coin-avatar span {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
}

.coin-name {
  font-size: 26px;
  font-weight: var(--fw-bold);
  color: var(--color-text-primary);
}

.exchange-badge {
  padding: 10px 20px;
  font-size: 14px;
  color: var(--color-text-secondary);
  white-space: nowrap;
}
.badge-num {
  font-weight: var(--fw-bold);
  color: var(--color-primary);
  font-size: 16px;
  margin: 0 6px;
}

/* ── 元数据行 ── */
.meta-row {
  display: flex;
  gap: var(--space-8);
  margin-bottom: var(--space-6);
  flex-wrap: wrap;
}
.meta-item { display: flex; flex-direction: column; gap: 2px; }
.meta-label { font-size: 12px; color: var(--color-text-muted); }
.meta-val   { font-size: 13px; color: var(--color-text-secondary); }

/* ── 统计卡片 ── */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-4);
  margin-top: var(--space-6);
}
.stat-card { padding: var(--space-5); }

.stat-label {
  font-size: 12px;
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}
.stat-pct {
  font-size: 22px;
  font-weight: var(--fw-bold);
  font-family: var(--font-family-num);
  line-height: 1.2;
  margin-bottom: var(--space-1);
}
.stat-sub {
  font-size: 12px;
  color: var(--color-text-muted);
  font-family: var(--font-family-num);
}

/* ── 移动端 ── */
@media (max-width: 860px) {
  .meta-row { gap: var(--space-5); }
  .stats-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 560px) {
  .coin-name { font-size: 20px; }
  .stats-grid { grid-template-columns: 1fr 1fr; gap: var(--space-3); }
  .stat-pct { font-size: 18px; }
}
</style>
