<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import {
  getPaper, getEquity, getTrades, getStrategies,
  type BalancePoint, type PaperTrade, type StrategySummary, type PaperAccount,
} from '@/api/paper'
import type { EquityPoint } from '@/api/backtest'
import EquityChart from '@/components/charts/EquityChart.vue'

const route = useRoute()
const router = useRouter()
const aid = Number(route.params.id)
const loading = ref(true)
const account = ref<PaperAccount | null>(null)
const equity = ref<BalancePoint[]>([])
const trades = ref<PaperTrade[]>([])
const strategies = ref<StrategySummary[]>([])
let timer: ReturnType<typeof setInterval> | null = null

const running = computed(() => {
  const s = account.value?.status ?? ''
  return s === 'running' || s === 'pending' || s === 'created'
})

async function load(): Promise<void> {
  try {
    const [acc, eq, tr, st] = await Promise.all([
      getPaper(aid), getEquity(aid), getTrades(aid), getStrategies(aid),
    ])
    account.value = acc
    equity.value = eq
    trades.value = tr
    strategies.value = st
  } finally {
    loading.value = false
  }
}

onMounted(() => {
  void load()
  timer = setInterval(async () => {
    if (!running.value) {
      if (timer) clearInterval(timer)
      return
    }
    await load()
  }, 3000)
})
onUnmounted(() => {
  if (timer) clearInterval(timer)
})

// ----- 从净值序列计算关键指标（模拟盘无 metrics 端点） -----
function std(arr: number[]): number {
  if (arr.length < 2) return 0
  const m = arr.reduce((a, b) => a + b, 0) / arr.length
  const v = arr.reduce((a, b) => a + (b - m) ** 2, 0) / (arr.length - 1)
  return Math.sqrt(v)
}

const metrics = computed(() => {
  const eq = equity.value
  if (eq.length < 2) return null
  const cur = eq.map((p) => p.total_equity).filter((v) => Number.isFinite(v) && v > 0)
  if (cur.length < 2) return null
  const start = cur[0]
  const last = cur[cur.length - 1]
  const totalReturn = last / start - 1
  const n = cur.length
  const annFactor = 252 / n
  const annualReturn = Math.pow(1 + totalReturn, annFactor) - 1
  const rets: number[] = []
  for (let i = 1; i < cur.length; i++) rets.push(cur[i] / cur[i - 1] - 1)
  const vol = std(rets) * Math.sqrt(252)
  const sharpe = vol > 0 ? (rets.reduce((a, b) => a + b, 0) / rets.length * 252) / vol : 0
  let peak = cur[0]
  let mdd = 0
  for (const v of cur) {
    if (v > peak) peak = v
    const dd = (peak - v) / peak
    if (dd > mdd) mdd = dd
  }
  return { totalReturn, annualReturn, vol, sharpe, mdd, last }
})

const equitySeries = computed<EquityPoint[]>(() =>
  equity.value.map((p) => ({ date: p.date, balance: p.total_equity })),
)

function pct(v: number | undefined | null): string {
  if (v == null || !Number.isFinite(v)) return '—'
  return (v * 100).toFixed(2) + '%'
}
function num(v: number | undefined | null): string {
  if (v == null || !Number.isFinite(v)) return '—'
  return Math.round(v).toLocaleString('zh-CN')
}
function statusLabel(s: string): string {
  return ({ running: '运行中', done: '完成', failed: '失败', created: '已创建', pending: '排队', stopped: '已停止' } as Record<string, string>)[s] || s
}
function rowClass({ row }: { row: PaperTrade }): string {
  return row.rejected ? 'rejected-row' : ''
}
function toLive(): void {
  router.push(`/paper/live/${aid}`)
}
</script>

<template>
  <div v-loading="loading" class="page paper-result">
    <div class="page-head">
      <div>
        <h2 class="page-title">模拟盘结果 <span class="muted">#{{ aid }}</span></h2>
        <p class="page-subtitle">
          {{ account?.name ?? 'paper' }} ·
          模式 <span class="mono">{{ account?.mode ?? '—' }}</span> ·
          频率 <span class="mono">{{ account?.interval ?? '—' }}</span>
        </p>
      </div>
      <div class="head-actions">
        <span v-if="account" class="chip" :class="`st-${account.status}`">{{
          account.mode === 'live' && account.status === 'running'
            ? '实走中 · 每日 20:30 结算'
            : statusLabel(account.status)
        }}</span>
        <el-button v-if="account?.mode === 'live'" type="primary" @click="toLive">实走监控 →</el-button>
      </div>
    </div>

    <el-alert v-if="running" type="info" :closable="false">
      回放进行中（{{ account?.status }}）…每 3 秒刷新，完成自动停止
    </el-alert>
    <el-alert v-else-if="account?.status === 'failed'" type="error" :title="account?.error_msg || '回放失败'" :closable="false" />

    <!-- 指标卡 -->
    <div class="metric-row">
      <div class="metric-card">
        <div class="m-label">总收益</div>
        <div class="m-value mono" :class="metrics && metrics.totalReturn >= 0 ? 'up' : 'down'">{{ pct(metrics?.totalReturn) }}</div>
      </div>
      <div class="metric-card">
        <div class="m-label">年化收益</div>
        <div class="m-value mono" :class="metrics && metrics.annualReturn >= 0 ? 'up' : 'down'">{{ pct(metrics?.annualReturn) }}</div>
      </div>
      <div class="metric-card">
        <div class="m-label">最大回撤</div>
        <div class="m-value mono down">{{ pct(metrics?.mdd) }}</div>
      </div>
      <div class="metric-card">
        <div class="m-label">夏普比率</div>
        <div class="m-value mono">{{ metrics ? metrics.sharpe.toFixed(2) : '—' }}</div>
      </div>
      <div class="metric-card">
        <div class="m-label">年化波动</div>
        <div class="m-value mono">{{ pct(metrics?.vol) }}</div>
      </div>
      <div class="metric-card">
        <div class="m-label">最新净值</div>
        <div class="m-value mono">{{ num(metrics?.last ?? account?.initial_capital) }}</div>
      </div>
    </div>

    <!-- 净值曲线 -->
    <el-card class="blk" shadow="never">
      <template #header><span class="section-title">账户净值</span></template>
      <EquityChart :data="equitySeries" />
    </el-card>

    <!-- 分策略归因 -->
    <el-card class="blk" shadow="never">
      <template #header><span class="section-title">分策略归因</span></template>
      <el-table :data="strategies" size="small" empty-text="无策略数据">
        <el-table-column prop="strategy_id" label="策略" min-width="160" />
        <el-table-column prop="total_orders" label="总委托" width="90" class-name="num" />
        <el-table-column prop="filled" label="成交" width="80" class-name="num" />
        <el-table-column prop="rejected" label="拒单" width="80" class-name="num" />
        <el-table-column label="成交率" width="90">
          <template #default="{ row }">
            <span class="mono">{{ row.total_orders ? ((row.filled / row.total_orders) * 100).toFixed(1) + '%' : '—' }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="commission" label="费用" width="100" class-name="num" />
      </el-table>
    </el-card>

    <!-- 成交明细 -->
    <el-card class="blk" shadow="never">
      <template #header><span class="section-title">成交明细 <em class="muted">（拒单标红）</em></span></template>
      <el-table :data="trades" size="small" :row-class-name="rowClass" max-height="420" empty-text="无成交">
        <el-table-column prop="bar_date" label="时间" min-width="150" />
        <el-table-column prop="strategy_id" label="策略" min-width="140" show-overflow-tooltip />
        <el-table-column prop="symbol" label="标的" width="90" />
        <el-table-column label="方向" width="70">
          <template #default="{ row }">
            <span :class="row.direction === '买' ? 'up' : 'down'">{{ row.direction }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="price" label="价格" width="100" class-name="num" />
        <el-table-column prop="volume" label="数量" width="90" class-name="num" />
        <el-table-column prop="commission" label="费用" width="90" class-name="num" />
        <el-table-column prop="reject_reason" label="拒因" min-width="120" show-overflow-tooltip />
      </el-table>
    </el-card>
  </div>
</template>

<style scoped>
.paper-result { display: flex; flex-direction: column; gap: 16px; }
.head-actions { display: flex; align-items: center; gap: 12px; }

.metric-row {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 12px;
}
.metric-card {
  background: var(--bg-card);
  border: 1px solid var(--border-2);
  border-radius: var(--r-md);
  padding: 14px 16px;
}
.m-label { font-size: 12px; color: var(--text-3); }
.m-value { margin-top: 6px; font-size: 20px; font-weight: 700; color: var(--text); }

.blk { border: 1px solid var(--border-2); }
:deep(.num) { font-family: var(--mono); }
:deep(.rejected-row) { color: var(--danger); }

@media (max-width: 1200px) {
  .metric-row { grid-template-columns: repeat(3, 1fr); }
}
</style>
