'use client';

import { useEffect, useMemo, useState } from 'react';
import { EquityCurveChart } from '@/components/EquityCurveChart';
import { runBacktest, type BacktestResponse, type BacktestTrade } from '@/lib/analytics-api';

type TradeRecord = {
  id: string;
  date: string;
  odds: number;
  isWin: boolean;
  stake: number;
  altitude: number;
  handicap: number;
  weather: string;
  recentWinRate: number;
  market: string;
};

const history: TradeRecord[] = [
  { id: 'T-001', date: '2026-01-05', odds: 1.95, isWin: true, stake: 100, altitude: 1700, handicap: -1, weather: '乾燥', recentWinRate: 0.56, market: '讓球' },
  { id: 'T-002', date: '2026-01-10', odds: 2.1, isWin: false, stake: 100, altitude: 1200, handicap: -0.5, weather: '潮濕', recentWinRate: 0.49, market: '讓球' },
  { id: 'T-003', date: '2026-01-12', odds: 1.82, isWin: true, stake: 100, altitude: 1600, handicap: 0, weather: '高溫', recentWinRate: 0.68, market: '大小分' },
  { id: 'T-004', date: '2026-01-19', odds: 2.25, isWin: true, stake: 100, altitude: 2100, handicap: -1.5, weather: '乾燥', recentWinRate: 0.62, market: '讓球' },
  { id: 'T-005', date: '2026-01-27', odds: 1.74, isWin: false, stake: 100, altitude: 2200, handicap: 0.5, weather: '低溫', recentWinRate: 0.44, market: '1x2' },
  { id: 'T-006', date: '2026-02-01', odds: 2.02, isWin: true, stake: 100, altitude: 1100, handicap: -0.5, weather: '中高濕', recentWinRate: 0.58, market: '讓球' },
  { id: 'T-007', date: '2026-02-09', odds: 1.91, isWin: true, stake: 100, altitude: 1800, handicap: -1, weather: '乾燥', recentWinRate: 0.61, market: '讓球' },
];

function toLocalISOString(date: string): string {
  return new Date(`${date}T15:00:00+08:00`).toISOString();
}

function fallbackRun(trades: TradeRecord[]) {
  let capital = 10000;
  const points: { ts: string; capital: number }[] = [{ ts: 'start', capital }];
  let wins = 0;

  for (const trade of trades) {
    const pnl = trade.isWin ? trade.stake * (trade.odds - 1) : -trade.stake;
    capital += pnl;
    if (trade.isWin) wins += 1;
    points.push({ ts: trade.date, capital: Number(capital.toFixed(2)) });
  }

  const hitRate = trades.length > 0 ? (wins / trades.length) * 100 : 0;
  const stakeTotal = trades.length * 100;
  const roi = stakeTotal > 0 ? ((capital - 10000) / stakeTotal) * 100 : 0;
  const maxDrawdown = points.reduce((acc, point, idx) => {
    const maxBefore = Math.max(...points.slice(0, idx + 1).map((item) => item.capital));
    const dd = ((maxBefore - point.capital) / maxBefore) * 100;
    return Math.max(acc, dd);
  }, 0);

  return {
    matched: trades.length,
    total: trades.length,
    hit_count: wins,
    win_rate: Number(hitRate.toFixed(4)),
    final_capital: Number(capital.toFixed(4)),
    net_profit: Number((capital - 10000).toFixed(4)),
    roi_percent: Number(roi.toFixed(4)),
    max_drawdown_percent: Number(maxDrawdown.toFixed(4)),
    equity_curve: points,
  } as BacktestResponse;
}

export default function BacktestingPage() {
  const [altMin, setAltMin] = useState(1400);
  const [altMax, setAltMax] = useState(2200);
  const [handicapMin, setHandicapMin] = useState(-2);
  const [handicapMax, setHandicapMax] = useState(0);
  const [weather, setWeather] = useState('全部');
  const [minRecentWinRate, setMinRecentWinRate] = useState(0.5);
  const [loading, setLoading] = useState(true);
  const [errorMessage, setErrorMessage] = useState('');
  const [result, setResult] = useState<BacktestResponse>({
    matched: 0,
    total: 0,
    hit_count: 0,
    win_rate: 0,
    final_capital: 10000,
    net_profit: 0,
    roi_percent: 0,
    max_drawdown_percent: 0,
    equity_curve: [{ ts: 'start', capital: 10000 }],
  });

  const filtered = useMemo(() => {
    return history.filter((trade) => {
      if (trade.altitude < altMin || trade.altitude > altMax) return false;
      if (trade.handicap < handicapMin || trade.handicap > handicapMax) return false;
      if (weather !== '全部' && trade.weather !== weather) return false;
      if (trade.recentWinRate < minRecentWinRate) return false;
      return true;
    });
  }, [altMin, altMax, handicapMin, handicapMax, weather, minRecentWinRate]);

  const requestPayload = useMemo(
    () => ({
      initial_capital: 10000,
      strategy: {
        weather: weather === '全部' ? null : weather,
        altitude_min_meters: altMin,
        altitude_max_meters: altMax,
        handicap_min: handicapMin,
        handicap_max: handicapMax,
        recent_win_rate_min: minRecentWinRate,
        recent_win_rate_max: null,
        market_types: null,
        start_at: null,
        end_at: null,
      },
      historical_trades: history.map<BacktestTrade>((trade) => ({
        trade_id: trade.id,
        settled_at: toLocalISOString(trade.date),
        odds: trade.odds,
        is_win: trade.isWin,
        stake: trade.stake,
        altitude_meters: trade.altitude,
        handicap: trade.handicap,
        weather: trade.weather,
        recent_form_win_rate: trade.recentWinRate,
        market_type: trade.market,
        selection: 'home',
      })),
    }),
    [altMin, altMax, handicapMin, handicapMax, weather, minRecentWinRate],
  );

  useEffect(() => {
    let active = true;
    setLoading(true);

    const execute = async () => {
      try {
        const data = await runBacktest(requestPayload);
        if (active) {
          setResult(data);
          setErrorMessage('');
        }
      } catch (error) {
        if (!active) return;
        setErrorMessage(error instanceof Error ? error.message : '回測服務無法連線，改用本機試算');
        setResult(fallbackRun(filtered));
      } finally {
        if (active) {
          setLoading(false);
        }
      }
    };

    execute();
    return () => {
      active = false;
    };
  }, [filtered, requestPayload]);

  return (
    <div className="space-y-4">
      <h2 className="dot-matrix text-2xl text-[#7d2a15]">自訂策略回測引擎</h2>

      <section className="panel-glow rounded-2xl p-4">
        <h3 className="dot-matrix text-lg text-[#7d2a15]">策略條件設定</h3>
        <div className="mt-3 grid gap-3 md:grid-cols-2">
          <label className="text-sm text-[#7a5b46]">
            海拔下限（m）
            <input
              className="mt-2 w-full rounded-lg border border-[#e0c6a8] bg-white/70 px-3 py-2"
              type="number"
              value={altMin}
              onChange={(event) => setAltMin(Number(event.target.value))}
            />
          </label>
          <label className="text-sm text-[#7a5b46]">
            海拔上限（m）
            <input
              className="mt-2 w-full rounded-lg border border-[#e0c6a8] bg-white/70 px-3 py-2"
              type="number"
              value={altMax}
              onChange={(event) => setAltMax(Number(event.target.value))}
            />
          </label>
          <label className="text-sm text-[#7a5b46]">
            讓球下限
            <input
              className="mt-2 w-full rounded-lg border border-[#e0c6a8] bg-white/70 px-3 py-2"
              type="number"
              value={handicapMin}
              onChange={(event) => setHandicapMin(Number(event.target.value))}
            />
          </label>
          <label className="text-sm text-[#7a5b46]">
            讓球上限
            <input
              className="mt-2 w-full rounded-lg border border-[#e0c6a8] bg-white/70 px-3 py-2"
              type="number"
              value={handicapMax}
              onChange={(event) => setHandicapMax(Number(event.target.value))}
            />
          </label>
          <label className="text-sm text-[#7a5b46]">
            天氣
            <select
              className="mt-2 w-full rounded-lg border border-[#e0c6a8] bg-white/70 px-3 py-2"
              value={weather}
              onChange={(event) => setWeather(event.target.value)}
            >
              <option value="全部">全部</option>
              <option value="乾燥">乾燥</option>
              <option value="潮濕">潮濕</option>
              <option value="中高濕">中高濕</option>
            </select>
          </label>
          <label className="text-sm text-[#7a5b46]">
            近期勝率下限
            <input
              className="mt-2 w-full"
              type="range"
              min={0}
              max={1}
              step={0.01}
              value={minRecentWinRate}
              onChange={(event) => setMinRecentWinRate(Number(event.target.value))}
            />
            <p className="text-xs text-[#7a5b46]">{(minRecentWinRate * 100).toFixed(0)}%</p>
          </label>
        </div>
      </section>

      <section className="grid gap-4 md:grid-cols-3">
        <article className="panel-glow rounded-2xl p-4">
          <p className="text-sm text-[#7a5b46]">樣本數</p>
          <p className="mt-2 text-2xl font-semibold text-[#7d2a15]">{result.matched}</p>
        </article>
        <article className="panel-glow rounded-2xl p-4">
          <p className="text-sm text-[#7a5b46]">勝率</p>
          <p className="mt-2 text-2xl font-semibold text-[#7d2a15]">{result.win_rate.toFixed(1)}%</p>
        </article>
        <article className="panel-glow rounded-2xl p-4">
          <p className="text-sm text-[#7a5b46]">ROI</p>
          <p className="mt-2 text-2xl font-semibold text-[#7d2a15]">{result.roi_percent.toFixed(2)}%</p>
        </article>
      </section>

      <section className="panel-glow rounded-2xl p-4">
        <p className="dot-matrix text-sm text-[#7d2a15]">
          命中：{result.hit_count} / {result.total}
          {' '}
          | 最終資金：{result.final_capital.toFixed(2)}
          | 淨利：{result.net_profit.toFixed(2)}
        </p>
        {loading ? <p className="mt-1 text-xs text-[#a16b4f]">回測引擎計算中…</p> : null}
        {errorMessage ? <p className="mt-1 text-xs text-[#8c2f2f]">{errorMessage}</p> : null}
      </section>

      <EquityCurveChart
        title="資金成長曲線（Equity Curve）"
        points={result.equity_curve}
        maxDrawdown={result.max_drawdown_percent}
      />

      <section className="panel-glow rounded-2xl p-4">
        <h3 className="dot-matrix text-lg text-[#7d2a15]">交易明細（依條件）</h3>
        <ul className="mt-3 space-y-2 text-sm text-[#7a5b46]">
          {filtered.map((trade) => (
            <li key={trade.id} className="rounded-lg bg-white/70 p-3">
              {trade.id}｜{trade.date}｜{trade.market}｜讓球 {trade.handicap}｜海拔 {trade.altitude}m｜
              {trade.isWin ? '勝' : '敗'}｜賠率 {trade.odds}
            </li>
          ))}
          {filtered.length === 0 ? <li className="rounded-lg bg-white/70 p-3">此條件下目前無筆交易</li> : null}
        </ul>
      </section>
    </div>
  );
}
