<script setup lang="ts">
import { computed, ref } from 'vue';
import { postEventBacktest } from '@/api/client';
import type { EventBacktestResponse, EventBacktestSpec } from '@/api/types';
import ConditionChips from '@/components/ConditionChips.vue';

const EXAMPLES = [
  '在连续三天 J 小于 10 的时候第二天开盘购买，之后未来三天的涨幅有多少',
  'RSI 低于 30 的第二天开盘买入，持有 5 天收盘卖出',
  '收盘价跌破布林带下轨的次日开盘买入，持有 10 天',
];

const text = ref(EXAMPLES[0]);
const tsCode = ref('');
const startDate = ref('');
const endDate = ref('');

const loading = ref(false);
const note = ref('');
const error = ref('');
const result = ref<EventBacktestResponse | null>(null);

// 调参重跑的本地 spec（首次由后端 LLM 解析返回，后续直接传给后端跳过解析）
const spec = ref<EventBacktestSpec | null>(null);
const holdingDays = ref(3);
const entryTiming = ref<'next_open' | 'next_close'>('next_open');
const exitTiming = ref<'close' | 'open'>('close');

const stats = computed(() => result.value?.stats ?? null);
const bestTrades = computed(() => {
  const t = result.value?.trades ?? [];
  return t.length > 100 ? t.slice(0, 100) : t;
});
const worstTrades = computed(() => {
  const t = result.value?.trades ?? [];
  return t.length > 100 ? t.slice(-100) : [];
});
const fmtPct = (v: number) => `${v > 0 ? '+' : ''}${v.toFixed(2)}%`;
const fmtDate = (s: string) => s.slice(0, 10);

async function run(specDirect?: EventBacktestSpec | null) {
  if (loading.value) return;
  const t = text.value.trim();
  if (!specDirect && t.length < 2) {
    error.value = '请先输入回测需求描述';
    return;
  }
  loading.value = true;
  error.value = '';
  note.value = specDirect
    ? '正在按调整后的参数重新回测（全市场扫描可能需要几分钟）…'
    : '正在解析回测参数并扫描全市场（可能需要几分钟）…';
  try {
    const res = await postEventBacktest({
      text: t,
      spec: specDirect ?? undefined,
      ts_code: tsCode.value.trim() || null,
      start: startDate.value || null,
      end: endDate.value || null,
    });
    result.value = res;
    spec.value = res.spec;
    holdingDays.value = res.spec.holding_days;
    entryTiming.value = res.spec.entry_timing;
    exitTiming.value = res.spec.exit_timing;
  } catch (e) {
    error.value = e instanceof Error ? e.message : String(e);
    result.value = null;
  } finally {
    loading.value = false;
    note.value = '';
  }
}

async function rerunAdjusted() {
  if (!spec.value) return;
  await run({
    ...spec.value,
    holding_days: holdingDays.value,
    entry_timing: entryTiming.value,
    exit_timing: exitTiming.value,
  });
}
</script>

<template>
  <div>
    <!-- 输入区 -->
    <div class="rounded-xl border border-[#26272E] bg-[#101014] p-4">
      <div class="flex items-center justify-between">
        <div class="text-sm font-medium text-[#A8AFB8]">事件回测：描述一个「信号 → 次日买入 → 持有 N 日」的事件，统计历史上全市场（或单只股票）的收益分布</div>
      </div>
      <textarea
        v-model="text"
        rows="2"
        class="mt-3 w-full resize-none rounded-lg border border-[#26272E] bg-[#16181D] px-3 py-2 text-sm text-[#E8EAED] outline-none placeholder:text-[#7A818C] focus:border-blue-500"
        placeholder="例：在连续三天 J 小于 10 的时候第二天开盘购买，之后未来三天的涨幅有多少"
        @keydown.ctrl.enter="run()"
      />
      <div class="mt-2 flex flex-wrap items-center gap-2">
        <span class="text-[13px] text-[#9BA3AE]">试试：</span>
        <button
          v-for="ex in EXAMPLES"
          :key="ex"
          class="rounded-full border border-[#26272E] px-2.5 py-1 text-[13px] text-[#A8AFB8] hover:border-blue-500 hover:text-blue-300"
          @click="text = ex"
        >
          {{ ex.length > 26 ? ex.slice(0, 26) + '…' : ex }}
        </button>
      </div>

      <div class="mt-3 flex flex-wrap items-end gap-3">
        <label class="text-[13px] text-[#A8AFB8]">
          股票范围
          <div class="mt-1 flex overflow-hidden rounded-lg border border-[#26272E] text-[13px]">
            <button
              class="px-3 py-1.5"
              :class="tsCode ? 'bg-[#101014] text-[#A8AFB8]' : 'bg-blue-600 text-white'"
              @click="tsCode = ''"
            >全市场</button>
            <button
              class="px-3 py-1.5"
              :class="tsCode ? 'bg-blue-600 text-white' : 'bg-[#101014] text-[#A8AFB8]'"
              @click="tsCode ||= '000001.SZ'"
            >单只股票</button>
          </div>
        </label>
        <label v-if="tsCode" class="text-[13px] text-[#A8AFB8]">
          股票代码
          <input
            v-model="tsCode"
            class="mt-1 block w-40 rounded-lg border border-[#26272E] bg-[#16181D] px-3 py-1.5 text-sm text-[#E8EAED] outline-none placeholder:text-[#7A818C] focus:border-blue-500"
            placeholder="000001.SZ"
          />
        </label>
        <label class="text-[13px] text-[#A8AFB8]">
          开始日期
          <input
            v-model="startDate"
            type="date"
            class="mt-1 block rounded-lg border border-[#26272E] bg-[#16181D] px-3 py-1.5 text-sm text-[#E8EAED] outline-none placeholder:text-[#7A818C] focus:border-blue-500"
          />
        </label>
        <label class="text-[13px] text-[#A8AFB8]">
          结束日期
          <input
            v-model="endDate"
            type="date"
            class="mt-1 block rounded-lg border border-[#26272E] bg-[#16181D] px-3 py-1.5 text-sm text-[#E8EAED] outline-none placeholder:text-[#7A818C] focus:border-blue-500"
          />
        </label>
        <span class="text-xs text-[#9BA3AE]">留空默认最近一年</span>
        <button
          class="ml-auto rounded-lg bg-blue-600 px-5 py-2 text-sm font-medium text-white hover:bg-blue-700 disabled:opacity-50"
          :disabled="loading"
          @click="run()"
        >
          {{ loading ? '回测中…' : '开始回测' }}
        </button>
      </div>
    </div>

    <!-- 错误 -->
    <div v-if="error" class="mt-4 flex items-start gap-2 rounded-xl border border-red-500/40 bg-red-500/15 px-4 py-3 text-sm text-red-300">
      <svg class="mt-0.5 h-4 w-4 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.3 3.9L1.8 18a2 2 0 001.7 3h17a2 2 0 001.7-3L13.7 3.9a2 2 0 00-3.4 0z" /><path d="M12 9v4M12 17h.01" /></svg>
      {{ error }}
    </div>

    <!-- 加载中 -->
    <div v-if="loading && note" class="py-16 text-center text-sm text-[#9BA3AE]">
      <svg class="mx-auto mb-3 h-6 w-6 animate-spin text-blue-500" viewBox="0 0 24 24" fill="none"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" /><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z" /></svg>
      {{ note }}
    </div>

    <!-- 结果 -->
    <template v-else-if="result && stats">
      <div class="mt-4 rounded-xl border border-[#26272E] bg-[#101014] px-4 py-3">
        <div class="mb-2 text-[13px] text-[#9BA3AE]">
          信号条件（{{ result.universe === 'all' ? '全市场' : result.universe }}，{{ fmtDate(result.start) }} ~ {{ fmtDate(result.end) }}）
        </div>
        <ConditionChips :conditions="result.spec.entry" />
      </div>

      <!-- 统计卡片 -->
      <div class="mt-4 grid grid-cols-2 gap-3 md:grid-cols-3 lg:grid-cols-6">
        <div class="rounded-xl border border-[#26272E] bg-[#101014] px-4 py-3">
          <div class="text-xs text-[#9BA3AE]">样本数</div>
          <div class="mt-1 text-xl font-semibold text-[#E8EAED]">{{ stats.samples.toLocaleString() }}</div>
          <div class="text-xs text-[#9BA3AE]">{{ stats.stocks.toLocaleString() }} 只股票</div>
        </div>
        <div class="rounded-xl border border-[#26272E] bg-[#101014] px-4 py-3">
          <div class="text-xs text-[#9BA3AE]">平均涨幅</div>
          <div class="mt-1 text-xl font-semibold" :class="stats.mean_pct >= 0 ? 'text-up' : 'text-down'">{{ fmtPct(stats.mean_pct) }}</div>
          <div class="text-xs text-[#9BA3AE]">中位数 {{ fmtPct(stats.median_pct) }}</div>
        </div>
        <div class="rounded-xl border border-[#26272E] bg-[#101014] px-4 py-3">
          <div class="text-xs text-[#9BA3AE]">胜率（涨）</div>
          <div class="mt-1 text-xl font-semibold text-[#E8EAED]">{{ stats.win_rate.toFixed(2) }}%</div>
          <div class="text-xs text-[#9BA3AE]">波动 σ {{ stats.std_pct.toFixed(2) }}</div>
        </div>
        <div class="rounded-xl border border-[#26272E] bg-[#101014] px-4 py-3">
          <div class="text-xs text-[#9BA3AE]">P10 / P25</div>
          <div class="mt-1 text-[15px] font-semibold text-down">{{ fmtPct(stats.p10_pct) }} / {{ fmtPct(stats.p25_pct) }}</div>
          <div class="text-xs text-[#9BA3AE]">最差 {{ fmtPct(stats.min_pct) }}</div>
        </div>
        <div class="rounded-xl border border-[#26272E] bg-[#101014] px-4 py-3">
          <div class="text-xs text-[#9BA3AE]">P75 / P90</div>
          <div class="mt-1 text-[15px] font-semibold text-up">{{ fmtPct(stats.p75_pct) }} / {{ fmtPct(stats.p90_pct) }}</div>
          <div class="text-xs text-[#9BA3AE]">最好 {{ fmtPct(stats.max_pct) }}</div>
        </div>
        <div class="rounded-xl border border-[#26272E] bg-[#101014] px-4 py-3">
          <div class="text-xs text-[#9BA3AE]">收益口径</div>
          <div class="mt-1 text-sm leading-5 text-[#E8EAED]">持有 {{ result.spec.holding_days }} 个交易日<br>{{ result.spec.entry_timing === 'next_open' ? '次日开盘' : '次日收盘' }}买入 → 按{{ result.spec.exit_timing === 'close' ? '收盘' : '开盘' }}卖出</div>
        </div>
      </div>

      <!-- 调参重跑 -->
      <div class="mt-4 flex flex-wrap items-end gap-3 rounded-xl border border-[#26272E] bg-[#101014] px-4 py-3">
        <div class="text-[13px] font-medium text-[#A8AFB8]">调整参数重跑（不动信号条件）：</div>
        <label class="text-[13px] text-[#A8AFB8]">
          持有天数
          <input
            v-model.number="holdingDays"
            type="number" min="1" max="250"
            class="mt-1 block w-20 rounded-lg border border-[#26272E] bg-[#16181D] px-2 py-1.5 text-sm text-[#E8EAED] outline-none focus:border-blue-500"
          />
        </label>
        <label class="text-[13px] text-[#A8AFB8]">
          买入时机
          <select v-model="entryTiming" class="mt-1 block rounded-lg border border-[#26272E] bg-[#16181D] px-2 py-1.5 text-sm text-[#E8EAED] outline-none focus:border-blue-500">
            <option value="next_open">次日开盘</option>
            <option value="next_close">次日收盘</option>
          </select>
        </label>
        <label class="text-[13px] text-[#A8AFB8]">
          卖出价
          <select v-model="exitTiming" class="mt-1 block rounded-lg border border-[#26272E] bg-[#16181D] px-2 py-1.5 text-sm text-[#E8EAED] outline-none focus:border-blue-500">
            <option value="close">收盘</option>
            <option value="open">开盘</option>
          </select>
        </label>
        <button
          class="rounded-lg border border-blue-500 px-4 py-1.5 text-sm font-medium text-blue-300 hover:bg-blue-500/15 disabled:opacity-50"
          :disabled="loading || !spec"
          @click="rerunAdjusted()"
        >按新参数重跑</button>
      </div>

      <!-- 分年统计 -->
      <div v-if="stats.by_year.length" class="mt-4 rounded-xl border border-[#26272E] bg-[#101014] p-4">
        <div class="mb-2 text-sm font-medium text-[#A8AFB8]">分年统计</div>
        <table class="w-full text-sm">
          <thead>
            <tr class="border-b border-[#1E2026] text-left text-[13px] text-[#9BA3AE]">
              <th class="py-1.5 font-normal">年份</th>
              <th class="py-1.5 font-normal">样本数</th>
              <th class="py-1.5 font-normal">平均涨幅</th>
              <th class="py-1.5 font-normal">中位数</th>
              <th class="py-1.5 font-normal">胜率</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="y in stats.by_year" :key="y.year" class="border-b border-[#1E2026]">
              <td class="py-1.5">{{ y.year }}</td>
              <td class="py-1.5">{{ y.samples.toLocaleString() }}</td>
              <td class="py-1.5 font-medium" :class="y.mean_pct >= 0 ? 'text-up' : 'text-down'">{{ fmtPct(y.mean_pct) }}</td>
              <td class="py-1.5" :class="y.median_pct >= 0 ? 'text-up' : 'text-down'">{{ fmtPct(y.median_pct) }}</td>
              <td class="py-1.5">{{ y.win_rate.toFixed(2) }}%</td>
            </tr>
          </tbody>
        </table>
      </div>

      <!-- 样本明细 -->
      <div class="mt-4 grid gap-4 lg:grid-cols-2">
        <div class="rounded-xl border border-[#26272E] bg-[#101014] p-4">
          <div class="mb-2 text-sm font-medium text-[#A8AFB8]">表现最好的样本（前 {{ bestTrades.length }}）</div>
          <div class="max-h-96 overflow-y-auto">
            <table class="w-full text-[13px]">
              <thead class="sticky top-0 bg-[#101014]">
                <tr class="border-b border-[#1E2026] text-left text-xs text-[#9BA3AE]">
                  <th class="py-1.5 font-normal">代码</th>
                  <th class="py-1.5 font-normal">买入日</th>
                  <th class="py-1.5 font-normal">买入价</th>
                  <th class="py-1.5 font-normal">卖出价</th>
                  <th class="py-1.5 font-normal">收益</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="(t, i) in bestTrades" :key="i" class="border-b border-[#1E2026]">
                  <td class="py-1.5">{{ t.ts_code }} <span class="text-[#9BA3AE]">{{ t.name }}</span></td>
                  <td class="py-1.5 text-[#A8AFB8]">{{ fmtDate(t.entry_date) }}</td>
                  <td class="py-1.5">{{ t.entry_price }}</td>
                  <td class="py-1.5">{{ t.exit_price }}</td>
                  <td class="py-1.5 font-medium text-up">{{ fmtPct(t.ret_pct) }}</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
        <div v-if="worstTrades.length" class="rounded-xl border border-[#26272E] bg-[#101014] p-4">
          <div class="mb-2 text-sm font-medium text-[#A8AFB8]">表现最差的样本（后 {{ worstTrades.length }}）</div>
          <div class="max-h-96 overflow-y-auto">
            <table class="w-full text-[13px]">
              <thead class="sticky top-0 bg-[#101014]">
                <tr class="border-b border-[#1E2026] text-left text-xs text-[#9BA3AE]">
                  <th class="py-1.5 font-normal">代码</th>
                  <th class="py-1.5 font-normal">买入日</th>
                  <th class="py-1.5 font-normal">买入价</th>
                  <th class="py-1.5 font-normal">卖出价</th>
                  <th class="py-1.5 font-normal">收益</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="(t, i) in worstTrades" :key="i" class="border-b border-[#1E2026]">
                  <td class="py-1.5">{{ t.ts_code }} <span class="text-[#9BA3AE]">{{ t.name }}</span></td>
                  <td class="py-1.5 text-[#A8AFB8]">{{ fmtDate(t.entry_date) }}</td>
                  <td class="py-1.5">{{ t.entry_price }}</td>
                  <td class="py-1.5">{{ t.exit_price }}</td>
                  <td class="py-1.5 font-medium text-down">{{ fmtPct(t.ret_pct) }}</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>
      <div class="mt-2 text-xs text-[#9BA3AE]">
        共 {{ result.total.toLocaleString() }} 个样本；收益率已按复权因子校正（消除除权除息失真）。明细仅展示最好/最差各 100 条。
      </div>
    </template>

    <div v-else-if="!error && !loading" class="py-16 text-center text-sm text-[#9BA3AE]">
      用一句话描述你的想法，例如「连续三天 J 小于 10 时次日开盘买入，未来三天涨多少」
    </div>
  </div>
</template>
