<template>
  <div>
    <div class="mk-card" style="padding: 16px 20px; margin-bottom: 16px;">
      <div style="display:flex; align-items:center; gap:12px; flex-wrap:wrap;">
        <el-select v-model="form.symbol" size="small" filterable style="width: 180px;">
          <el-option v-for="c in store.symbolList" :key="c.symbol" :label="`${c.name} (${c.exchange})`" :value="c.symbol" />
        </el-select>
        <div class="interval-group">
          <button v-for="tf in timeframes" :key="tf.v" :class="['interval-btn', { active: form.interval === tf.v }]" @click="form.interval = tf.v">{{ tf.l }}</button>
        </div>
        <el-input-number v-model="form.capital" :min="10000" :step="100000" size="small" style="width: 150px;" />
        <el-input-number v-model="form.commission" :min="0" :max="0.01" :step="0.0001" :precision="4" size="small" style="width: 120px;" />
        <el-button type="success" size="small" @click="runBacktest" :loading="running" style="font-weight:600;">
          <el-icon><CaretRight /></el-icon> 运行回测
        </el-button>
        <el-select v-model="selectedTemplate" size="small" style="width: 200px;" placeholder="选择模板" @change="loadTemplate">
          <el-option v-for="(t, key) in templates" :key="key" :label="t.name" :value="key" />
        </el-select>
      </div>
    </div>

    <div style="display:grid; grid-template-columns: 1.2fr 1fr; gap:16px; margin-bottom:16px;">
      <div class="mk-card" style="padding:0; overflow:hidden;">
        <div style="padding:10px 16px; border-bottom:1px solid var(--border-light); font-weight:700;">策略代码</div>
        <div style="height: 360px;">
          <Codemirror v-model="form.code" :extensions="cmExtensions" :style="{ height: '100%', fontSize: '13px' }" />
        </div>
      </div>
      <div style="display:grid; grid-template-columns: repeat(3, 1fr); gap:10px;">
        <div v-for="m in metricCards" :key="m.label" class="mk-stat" style="padding: 10px 12px;">
          <p style="font-size:11px; color:var(--text-light); margin-bottom:4px;">{{ m.label }}</p>
          <h5 :style="{ fontSize: '18px', fontWeight: 700, color: m.color || 'var(--text-dark)' }">{{ m.value }}</h5>
        </div>
      </div>
    </div>

    <div v-if="error" class="mk-card" style="padding: 12px 16px; border-left: 4px solid var(--red); margin-bottom: 16px;">
      <strong style="color: var(--red);">回测错误：</strong>
      <pre style="font-size:12px; margin-top:6px; white-space:pre-wrap;">{{ error }}</pre>
    </div>

    <div v-if="result" style="display:grid; gap:16px;">
      <div class="mk-card" style="padding:0; overflow:hidden;">
        <div style="padding:10px 16px; border-bottom:1px solid var(--border-light); font-weight:700;">Cumulative Returns</div>
        <v-chart :option="equityChartOpt" autoresize style="height: 300px; padding:6px;" />
      </div>

      <div class="mk-card" style="padding:0; overflow:hidden;">
        <div style="padding:10px 16px; border-bottom:1px solid var(--border-light); font-weight:700;">Drawdown (Max: {{ result.metrics?.max_drawdown }}%)</div>
        <v-chart :option="drawdownChartOpt" autoresize style="height: 260px; padding:6px;" />
      </div>

      <div style="display:grid; grid-template-columns: 1fr 1fr; gap:16px;">
        <div class="mk-card" style="padding:0; overflow:hidden;">
          <div style="padding:10px 16px; border-bottom:1px solid var(--border-light); font-weight:700;">Weekly Return Distribution</div>
          <v-chart :option="distChartOpt" autoresize style="height: 260px; padding:6px;" />
        </div>
        <div class="mk-card" style="padding:0; overflow:hidden;">
          <div style="padding:10px 16px; border-bottom:1px solid var(--border-light); font-weight:700;">Rolling Stats</div>
          <v-chart :option="rollingChartOpt" autoresize style="height: 260px; padding:6px;" />
        </div>
      </div>

      <div class="mk-card" style="padding:0; overflow:hidden;">
        <div style="padding:10px 16px; border-bottom:1px solid var(--border-light); font-weight:700;">Turnover Rate (Avg: {{ result.metrics?.turnover_rate || 0 }}%)</div>
        <v-chart :option="turnoverChartOpt" autoresize style="height: 220px; padding:6px;" />
      </div>

      <div class="mk-card" style="padding:0; overflow:hidden;">
        <div style="padding:10px 16px; border-bottom:1px solid var(--border-light); font-weight:700;">Trade Log</div>
        <el-table :data="result?.trades || []" style="width: 100%;" size="small" :max-height="260">
          <el-table-column prop="timestamp" label="时间" width="160"><template #default="{ row }">{{ row.timestamp?.substring(0, 16) }}</template></el-table-column>
          <el-table-column label="操作" width="110"><template #default="{ row }"><span :class="['badge-pill', row.action.includes('LONG') || row.action === 'BUY' ? 'green' : 'red']">{{ row.action }}</span></template></el-table-column>
          <el-table-column label="价格" width="90"><template #default="{ row }">{{ row.price }}</template></el-table-column>
          <el-table-column label="数量" width="70"><template #default="{ row }">{{ row.quantity }}</template></el-table-column>
          <el-table-column label="盈亏"><template #default="{ row }"><span :class="row.pnl >= 0 ? 'price-up' : 'price-down'" style="font-weight:600;">{{ row.pnl?.toFixed(2) }}</span></template></el-table-column>
          <el-table-column label="资金"><template #default="{ row }">{{ row.capital?.toFixed ? row.capital.toFixed(2) : row.capital }}</template></el-table-column>
        </el-table>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { Codemirror } from 'vue-codemirror'
import { python } from '@codemirror/lang-python'
import { oneDark } from '@codemirror/theme-one-dark'
import VChart from 'vue-echarts'
import { use } from 'echarts/core'
import { LineChart, BarChart } from 'echarts/charts'
import { GridComponent, TooltipComponent, DataZoomComponent, MarkLineComponent, LegendComponent } from 'echarts/components'
import { CanvasRenderer } from 'echarts/renderers'
import { useTradingStore } from '../stores/trading'
import { backtestApi } from '../api'
import { ElMessage } from 'element-plus'

use([LineChart, BarChart, GridComponent, TooltipComponent, DataZoomComponent, MarkLineComponent, LegendComponent, CanvasRenderer])

const store = useTradingStore()
const cmExtensions = [python(), oneDark]
const templates = ref({})
const selectedTemplate = ref('')
const running = ref(false)
const result = ref(null)
const error = ref('')

const form = ref({
  symbol: '螺纹钢',
  interval: '1d',
  capital: 1000000,
  commission: 0.0003,
  code: '',
})

const timeframes = [
  { l: '15分', v: '15m' }, { l: '30分', v: '30m' }, { l: '1时', v: '1h' },
  { l: '4时', v: '4h' }, { l: '日线', v: '1d' }, { l: '周线', v: '1w' },
]

const metricCards = computed(() => {
  const m = result.value?.metrics
  if (!m) return []
  return [
    { label: '总收益率', value: m.total_return + '%', color: m.total_return >= 0 ? 'var(--green)' : 'var(--red)' },
    { label: '最大回撤', value: m.max_drawdown + '%', color: 'var(--red)' },
    { label: 'Sharpe Ratio', value: m.sharpe_ratio?.toString(), color: m.sharpe_ratio > 1 ? 'var(--green)' : 'var(--text-dark)' },
    { label: '胜率', value: m.win_rate + '%', color: m.win_rate > 50 ? 'var(--green)' : 'var(--red)' },
    { label: '盈亏比', value: m.profit_factor?.toString(), color: m.profit_factor > 1 ? 'var(--green)' : 'var(--red)' },
    { label: '总交易次数', value: m.total_trades?.toString() },
  ]
})

function loadTemplate(key) {
  if (templates.value[key]) form.value.code = templates.value[key].code
}

async function runBacktest() {
  if (!form.value.code.trim()) { ElMessage.warning('请输入策略代码'); return }
  running.value = true; error.value = ''; result.value = null
  try {
    const { data } = await backtestApi.run({
      code: form.value.code, symbol: form.value.symbol, interval: form.value.interval,
      limit: 500, initial_capital: form.value.capital, commission: form.value.commission,
    })
    if (data.status === 'error') { error.value = data.error }
    else { result.value = data; ElMessage.success(`回测完成: ${data.metrics.total_trades} 笔交易, 收益 ${data.metrics.total_return}%`) }
  } catch (e) { error.value = e.response?.data?.detail || e.message }
  running.value = false
}

const chartColors = { line: '#e9ecef', text: '#8392ab', green: '#4caf50', red: '#f44336', blue: '#1a73e8', gray: '#9e9e9e', area: 'rgba(76,175,80,0.1)' }

const equityChartOpt = computed(() => {
  const eq = result.value?.equity_curve
  const bench = result.value?.benchmark_curve
  const excess = result.value?.excess_curve
  if (!eq || !bench || !excess) return {}
  const ts = eq.timestamps.map(t => t.substring(0, 10))
  const base = result.value.metrics?.initial_capital || 1
  const eqNorm = eq.values.map(v => v / base)
  const bmNorm = bench.values.map(v => v / base)
  const exNorm = excess.values.map(v => v / base + 1)
  return {
    tooltip: { trigger: 'axis' },
    legend: { data: ['Strategy', 'Benchmark', 'Excess'], textStyle: { color: chartColors.text }, top: 4 },
    grid: { left: '10%', right: '4%', top: '8%', bottom: '15%' },
    xAxis: { type: 'category', data: ts, axisLine: { lineStyle: { color: chartColors.line } }, axisLabel: { color: chartColors.text, fontSize: 10 } },
    yAxis: { type: 'value', splitLine: { lineStyle: { color: '#f0f2f5' } }, axisLabel: { color: chartColors.text, fontSize: 10 } },
    series: [
      { name: 'Strategy', type: 'line', data: eqNorm, smooth: true, lineStyle: { color: chartColors.blue, width: 2 }, symbol: 'none' },
      { name: 'Benchmark', type: 'line', data: bmNorm, smooth: true, lineStyle: { color: chartColors.gray, width: 1.5, type: 'dashed' }, symbol: 'none' },
      { name: 'Excess', type: 'line', data: exNorm, smooth: true, lineStyle: { color: chartColors.green, width: 2 }, symbol: 'none' },
    ],
  }
})

const drawdownChartOpt = computed(() => {
  const dd = result.value?.drawdown_curve; if (!dd) return {}
  const ts = dd.timestamps.map(t => t.substring(5, 10))
  return {
    tooltip: { trigger: 'axis' },
    grid: { left: '10%', right: '4%', top: '8%', bottom: '15%' },
    xAxis: { type: 'category', data: ts, axisLine: { lineStyle: { color: chartColors.line } }, axisLabel: { color: chartColors.text, fontSize: 10 } },
    yAxis: { type: 'value', splitLine: { lineStyle: { color: '#f0f2f5' } }, axisLabel: { color: chartColors.text, fontSize: 10, formatter: v => v + '%' } },
    series: [{ type: 'line', data: dd.values, smooth: true, lineStyle: { color: chartColors.red, width: 2 }, areaStyle: { color: 'rgba(244,67,54,0.15)' }, symbol: 'none' }],
  }
})

const distChartOpt = computed(() => {
  const d = result.value?.returns_distribution; if (!d) return {}
  const labels = d.edges.slice(0, -1).map((e, i) => ((e + d.edges[i + 1]) / 2).toFixed(2) + '%')
  const colors = d.edges.slice(0, -1).map((e, i) => ((e + d.edges[i + 1]) / 2) >= 0 ? 'rgba(76,175,80,0.7)' : 'rgba(244,67,54,0.65)')
  return {
    tooltip: { trigger: 'axis' },
    grid: { left: '10%', right: '4%', top: '8%', bottom: '15%' },
    xAxis: { type: 'category', data: labels, axisLine: { lineStyle: { color: chartColors.line } }, axisLabel: { color: chartColors.text, fontSize: 9, rotate: 45 } },
    yAxis: { type: 'value', splitLine: { lineStyle: { color: '#f0f2f5' } }, axisLabel: { color: chartColors.text, fontSize: 10 } },
    series: [{ name: 'Strategy', type: 'bar', barWidth: '75%', data: d.counts.map((c, i) => ({ value: c, itemStyle: { color: colors[i] } })) }],
  }
})

const rollingChartOpt = computed(() => {
  const rolling = result.value?.rolling_stats
  if (!rolling) return {}
  const ts = rolling.timestamps.map(t => t.substring(0, 10))
  return {
    legend: { data: ['Rolling Sharpe', 'Rolling Volatility'], textStyle: { color: chartColors.text }, top: 4 },
    tooltip: { trigger: 'axis' },
    grid: { left: '10%', right: '8%', top: '15%', bottom: '15%' },
    xAxis: { type: 'category', data: ts, axisLine: { lineStyle: { color: chartColors.line } }, axisLabel: { color: chartColors.text, fontSize: 10 } },
    yAxis: [
      { type: 'value', name: 'Sharpe', splitLine: { lineStyle: { color: '#f0f2f5' } }, axisLabel: { color: chartColors.text, fontSize: 10 } },
      { type: 'value', name: 'Vol', position: 'right', axisLabel: { color: chartColors.text, fontSize: 10 } },
    ],
    series: [
      { name: 'Rolling Sharpe', type: 'line', yAxisIndex: 0, data: rolling.rolling_sharpe, smooth: true, lineStyle: { color: '#f9a825', width: 2 }, symbol: 'none' },
      { name: 'Rolling Volatility', type: 'line', yAxisIndex: 1, data: rolling.rolling_volatility, smooth: true, lineStyle: { color: chartColors.green, width: 2 }, symbol: 'none' },
    ],
  }
})

const turnoverChartOpt = computed(() => {
  const turn = result.value?.turnover_curve
  if (!turn) return {}
  const ts = turn.timestamps.map(t => t.substring(0, 10))
  const avg = (result.value.metrics?.turnover_rate || 0) / 100
  return {
    tooltip: { trigger: 'axis' },
    grid: { left: '10%', right: '4%', top: '10%', bottom: '15%' },
    xAxis: { type: 'category', data: ts, axisLine: { lineStyle: { color: chartColors.line } }, axisLabel: { color: chartColors.text, fontSize: 10 } },
    yAxis: { type: 'value', splitLine: { lineStyle: { color: '#f0f2f5' } }, axisLabel: { color: chartColors.text, fontSize: 10 } },
    series: [
      { type: 'bar', data: turn.values, itemStyle: { color: 'rgba(33,150,243,0.25)' }, barWidth: '70%' },
      { type: 'line', data: ts.map(() => avg), symbol: 'none', lineStyle: { color: '#d32f2f', type: 'dashed', width: 2 } },
    ],
  }
})

onMounted(async () => {
  await store.fetchContracts()
  try {
    const { data } = await backtestApi.getTemplates()
    templates.value = data
    const first = Object.keys(data)[0]
    if (first) { selectedTemplate.value = first; form.value.code = data[first].code }
  } catch (e) { console.error(e) }
})
</script>
