import { useState, useMemo, useEffect, type FormEvent } from 'react';
import {
  Alert,
  Badge,
  Button,
  Card,
  Col,
  Container,
  Form,
  Row,
  Spinner,
} from 'react-bootstrap';
import { useNavigate, useSearchParams } from 'react-router-dom';
import {
  useCreatePaperRun,
  useExchanges,
  useExchangeInstruments,
  useInstrumentDataRange,
  useSubscriptions,
  useIngestConfigs,
  useCandleCoverage,
  useBackfillCandles,
  useStrategies,
} from '../api/hooks';
import AppBreadcrumb from '../components/AppBreadcrumb';
import type { Strategy } from '../types/api';

function strategyLabel(s: Strategy): string {
  if (s.name) return s.name + (s.version > 1 ? ` v${s.version}` : '');
  return s.hash.slice(0, 16);
}

// ---------------------------------------------------------------------------
// Multi-timeframe helpers
// ---------------------------------------------------------------------------

function collectTimeframesFromExpr(expr: unknown, out: Set<string>): void {
  if (typeof expr !== 'object' || expr === null) return;
  const e = expr as Record<string, unknown>;
  if (typeof e.timeframe === 'string') out.add(e.timeframe);
  collectTimeframesFromExpr(e.left, out);
  collectTimeframesFromExpr(e.right, out);
  collectTimeframesFromExpr(e.input, out);
  collectTimeframesFromExpr(e.operand, out);
}

function collectTimeframesFromCondition(cond: unknown, out: Set<string>): void {
  if (typeof cond !== 'object' || cond === null) return;
  const c = cond as Record<string, unknown>;
  // Legacy shorthand conditions (ema_crossover, ema_trend, rsi, bollinger, price_level)
  if (typeof c.timeframe === 'string') out.add(c.timeframe);
  // all_of / any_of
  if (Array.isArray(c.conditions)) {
    (c.conditions as unknown[]).forEach((sub) => collectTimeframesFromCondition(sub, out));
  }
  // not / event_count / bars_since inner condition
  if (c.condition !== undefined) collectTimeframesFromCondition(c.condition, out);
  // compare / cross_over / cross_under: walk left/right expressions
  collectTimeframesFromExpr(c.left, out);
  collectTimeframesFromExpr(c.right, out);
}

/** Returns sorted list of additional timeframes referenced in the strategy's rules,
 *  excluding the primary candle interval. */
function collectAdditionalTimeframes(strategy: Strategy, primaryInterval: string): string[] {
  const cfg = strategy.config as Record<string, unknown>;
  const rules = Array.isArray(cfg.rules) ? (cfg.rules as unknown[]) : [];
  const set = new Set<string>();
  for (const rule of rules) {
    collectTimeframesFromCondition((rule as Record<string, unknown>).when, set);
  }
  set.delete(primaryInterval);
  return [...set].sort();
}

export default function AddPaperRunPage() {
  const navigate = useNavigate();
  const [searchParams] = useSearchParams();
  const createMutation = useCreatePaperRun();

  // Instrument selection
  const [exchange, setExchange] = useState('');
  const [pair, setPair] = useState('');

  const exchanges = useExchanges();
  const subscriptions = useSubscriptions();
  const ingestConfigs = useIngestConfigs();

  const { availableExchanges, availablePairsByExchange } = useMemo(() => {
    const exSet = new Set<string>();
    const pairMap = new Map<string, Set<string>>();

    const addEntry = (exchangeName: string, base: string, quote: string) => {
      const ex = exchangeName.toLowerCase();
      exSet.add(ex);
      if (!pairMap.has(ex)) pairMap.set(ex, new Set());
      pairMap.get(ex)!.add(`${base.toUpperCase()}-${quote.toUpperCase()}`);
    };

    for (const sub of subscriptions.data ?? []) {
      addEntry(sub.exchange, sub.base_asset, sub.quote_asset);
    }
    for (const cfg of ingestConfigs.data ?? []) {
      addEntry(cfg.exchange, cfg.base_asset, cfg.quote_asset);
    }

    return { availableExchanges: exSet, availablePairsByExchange: pairMap };
  }, [subscriptions.data, ingestConfigs.data]);

  const dataLoaded = !subscriptions.isLoading && !ingestConfigs.isLoading;

  const filteredExchanges = useMemo(() => {
    if (!exchanges.data || !dataLoaded) return exchanges.data ?? [];
    return exchanges.data.filter((ex) => availableExchanges.has(ex.name.toLowerCase()));
  }, [exchanges.data, availableExchanges, dataLoaded]);

  const selectedExchange = useMemo(
    () => exchanges.data?.find((ex) => ex.name === exchange) ?? null,
    [exchange, exchanges.data],
  );
  const supportsLookup = selectedExchange?.supports_instrument_lookup ?? false;

  const localPairs = useMemo(() => {
    const pairs = availablePairsByExchange.get(exchange.toLowerCase());
    if (!pairs) return [];
    return [...pairs].sort().map((p) => {
      const [base, quote] = p.split('-');
      return { base, quote };
    });
  }, [exchange, availablePairsByExchange]);

  const useLocalPairs = localPairs.length > 0;
  const instruments = useExchangeInstruments(
    supportsLookup && !useLocalPairs ? exchange : null,
  );
  const sortedInstruments = useMemo(() => {
    if (useLocalPairs) return localPairs;
    if (!instruments.data) return [];
    return [...instruments.data].sort((a, b) =>
      `${a.base}-${a.quote}`.localeCompare(`${b.base}-${b.quote}`),
    );
  }, [useLocalPairs, localPairs, instruments.data]);

  const [parsedBase, parsedQuote] = useMemo(() => {
    const parts = pair.split('-');
    if (parts.length === 2 && parts[0] && parts[1]) return [parts[0], parts[1]];
    return ['', ''];
  }, [pair]);

  // Execution parameters
  const [latencyMs, setLatencyMs] = useState(100);
  const [feesPercent, setFeesPercent] = useState(0.1);
  const [quoteBalance, setQuoteBalance] = useState('10000');
  const [baseBalance, setBaseBalance] = useState('0');

  // Run parameters
  function toLocalDatetimeString(d: Date): string {
    const pad = (n: number) => String(n).padStart(2, '0');
    return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
  }
  function defaultStartsAt(): string {
    const d = new Date();
    d.setSeconds(0, 0);
    return toLocalDatetimeString(d);
  }
  function defaultFinishesAt(): string {
    const d = new Date(Date.now() + 60_000);
    d.setSeconds(0, 0);
    return toLocalDatetimeString(d);
  }
  const [mode, setMode] = useState<'live' | 'backtest'>('live');
  const [startsAt, setStartsAt] = useState(defaultStartsAt);
  const [finishesAt, setFinishesAt] = useState(defaultFinishesAt);

  // Timespan selector (number + unit)
  type TimespanUnit = 'minutes' | 'hours' | 'days' | 'weeks' | 'months';
  const UNIT_MS: Record<TimespanUnit, number> = {
    minutes: 60_000,
    hours:   60 * 60_000,
    days:    24 * 60 * 60_000,
    weeks:   7 * 24 * 60 * 60_000,
    months:  30 * 24 * 60 * 60_000,
  };
  const [timespanValue, setTimespanValue] = useState(1);
  const [timespanUnit, setTimespanUnit] = useState<TimespanUnit>('months');
  const selectedPreset = timespanValue > 0 ? timespanValue * UNIT_MS[timespanUnit] : null;
  const [customDates, setCustomDates] = useState(false);
  // null = tick-based replay; '1m', '5m', etc. = candle-based
  const [candleInterval, setCandleInterval] = useState<string | null>(null);

  const nameExchange = parsedBase && parsedQuote ? parsedBase + parsedQuote : null;
  const dataRange = useInstrumentDataRange(
    mode === 'backtest' && !candleInterval && exchange ? exchange : null,
    mode === 'backtest' && !candleInterval ? nameExchange : null,
  );

  // candle symbol is e.g. "BTCUSDC" (no dash, uppercase)
  const candleSymbol = nameExchange;
  const candleCoverage = useCandleCoverage(
    mode === 'backtest' && candleInterval && exchange ? exchange : null,
    mode === 'backtest' && candleInterval ? candleSymbol : null,
  );
  const backfillMutation = useBackfillCandles();

  const selectedCoverage = candleCoverage.data?.find((c) => c.interval === candleInterval);

  useEffect(() => {
    if (customDates) return;

    if (mode === 'live') {
      const end = new Date();
      end.setSeconds(0, 0);
      const durationMs = selectedPreset ?? 60 * 60_000;
      const start = new Date(end.getTime());
      const finish = new Date(end.getTime() + durationMs);
      finish.setSeconds(0, 0);
      setStartsAt(toLocalDatetimeString(start));
      setFinishesAt(toLocalDatetimeString(finish));
      return;
    }

    // Backtest: anchor end to last available data point, subtract preset duration for start.
    let anchorEnd: Date | null = null;
    if (candleInterval && selectedCoverage) {
      anchorEnd = new Date(selectedCoverage.last_close);
    } else if (!candleInterval && dataRange.data) {
      anchorEnd = new Date(dataRange.data.end);
    }

    if (anchorEnd) {
      anchorEnd.setSeconds(0, 0);
      const durationMs = selectedPreset ?? 30 * 24 * 60 * 60_000;
      const anchorStart = new Date(anchorEnd.getTime() - durationMs);
      anchorStart.setSeconds(0, 0);
      setStartsAt(toLocalDatetimeString(anchorStart));
      setFinishesAt(toLocalDatetimeString(anchorEnd));
    }
  }, [dataRange.data, selectedCoverage, mode, candleInterval, selectedPreset, customDates, timespanValue, timespanUnit]);

  const [riskFreeReturn, setRiskFreeReturn] = useState(0.05);

  // Strategy — loaded from DB
  const strategies = useStrategies();
  const ruleBasedStrategies = useMemo(
    () =>
      (strategies.data ?? []).filter(
        (s) => (s.config as Record<string, unknown>)?.type === 'rule_based',
      ),
    [strategies.data],
  );

  const preselectedId = searchParams.get('strategy_id') ?? '';
  const [selectedStrategyId, setSelectedStrategyId] = useState(preselectedId);

  // When strategies load and a preselected id was provided, ensure it's selected
  useEffect(() => {
    if (preselectedId) {
      setSelectedStrategyId(preselectedId);
      setMode('backtest');
    }
  }, [preselectedId]);

  const selectedStrategy = useMemo(
    () => ruleBasedStrategies.find((s) => s.id === selectedStrategyId) ?? null,
    [ruleBasedStrategies, selectedStrategyId],
  );

  // Sync candle interval from the selected strategy
  useEffect(() => {
    if (!selectedStrategy) return;
    const cfg = selectedStrategy.config as Record<string, unknown>;
    const interval = typeof cfg.candle_interval === 'string' ? cfg.candle_interval : null;
    setCandleInterval(interval);
  }, [selectedStrategy]);

  /** Additional timeframes the selected strategy references beyond the primary interval. */
  const additionalTimeframes = useMemo(() => {
    if (!selectedStrategy || !candleInterval) return [];
    return collectAdditionalTimeframes(selectedStrategy, candleInterval);
  }, [selectedStrategy, candleInterval]);

  function handleExchangeChange(name: string) {
    setExchange(name);
    setPair('');
  }

  function handleSubmit(e: FormEvent) {
    e.preventDefault();
    if (!exchange || !parsedBase || !parsedQuote) return;

    const base = parsedBase;
    const quote = parsedQuote;
    const nameEx = base + quote;
    const now = new Date().toISOString();

    const strategy = selectedStrategy
      ? selectedStrategy.config
      : { type: 'default' };

    const config = {
      instrument: {
        exchange,
        name_exchange: nameEx,
        underlying: { base: base.toLowerCase(), quote: quote.toLowerCase() },
        quote: 'underlying_quote',
        kind: 'spot',
      },
      execution: {
        mocked_exchange: exchange,
        latency_ms: latencyMs,
        fees_percent: feesPercent / 100,
        initial_state: {
          exchange,
          balances: [
            {
              asset: quote.toLowerCase(),
              balance: { total: Number(quoteBalance), free: Number(quoteBalance) },
              time_exchange: now,
            },
            {
              asset: base.toLowerCase(),
              balance: { total: Number(baseBalance), free: Number(baseBalance) },
              time_exchange: now,
            },
          ],
          instrument: { instrument_name: nameEx, orders: [] },
        },
      },
      strategy,
    };

    createMutation.mutate(
      {
        mode,
        config,
        starts_at: new Date(startsAt).toISOString(),
        finishes_at: new Date(finishesAt).toISOString(),
        risk_free_return: riskFreeReturn,
        candle_interval: mode === 'backtest' ? candleInterval : null,
      },
      {
        onSuccess: (run) => navigate(`/paper-runs/${run.id}`),
      },
    );
  }

  const pairValid = !!parsedBase && !!parsedQuote;
  const formValid = !!exchange && pairValid;

  return (
    <Container>
      <AppBreadcrumb />
      <Card>
        <Card.Header>Create Paper Run</Card.Header>
        <Card.Body>
          <Form onSubmit={handleSubmit}>
            <Row>
              <Col lg={4}>
                <h6>Instrument</h6>
                <Form.Group className="mb-3">
                  <Form.Label>Exchange</Form.Label>
                  <Form.Select
                    value={exchange}
                    onChange={(e) => handleExchangeChange(e.target.value)}
                    disabled={!dataLoaded}
                  >
                    <option value="">
                      {dataLoaded ? 'Select an exchange...' : 'Loading...'}
                    </option>
                    {filteredExchanges.map((ex) => (
                      <option key={ex.name} value={ex.name}>
                        {ex.name}
                      </option>
                    ))}
                  </Form.Select>
                  {dataLoaded && filteredExchanges.length === 0 && (
                    <Form.Text className="text-warning">
                      No exchanges with available data. Add a subscription or ingest config first.
                    </Form.Text>
                  )}
                </Form.Group>

                <Form.Group className="mb-3">
                  <Form.Label>
                    Pair (BASE-QUOTE)
                    {!useLocalPairs && supportsLookup && instruments.isLoading && (
                      <Spinner size="sm" animation="border" className="ms-2" />
                    )}
                  </Form.Label>
                  {useLocalPairs || supportsLookup ? (
                    <>
                      <Form.Control
                        value={pair}
                        onChange={(e) => setPair(e.target.value)}
                        placeholder="Type to search instruments..."
                        list="paper-run-instrument-pairs"
                        disabled={!exchange}
                      />
                      <datalist id="paper-run-instrument-pairs">
                        {sortedInstruments.map((inst) => {
                          const value = `${inst.base}-${inst.quote}`;
                          return <option key={value} value={value} />;
                        })}
                      </datalist>
                    </>
                  ) : (
                    <Form.Control
                      value={pair}
                      onChange={(e) => setPair(e.target.value)}
                      placeholder="e.g. BTC-USDT"
                      disabled={!exchange}
                    />
                  )}
                  {pair && !pairValid && (
                    <Form.Text className="text-danger">
                      Enter pair as BASE-QUOTE (e.g. BTC-USDC)
                    </Form.Text>
                  )}
                </Form.Group>

                <h6>Execution</h6>
                <Form.Group className="mb-3">
                  <Form.Label>Latency (ms)</Form.Label>
                  <Form.Control
                    type="number"
                    min={0}
                    value={latencyMs}
                    onChange={(e) => setLatencyMs(Number(e.target.value))}
                  />
                </Form.Group>
                <Form.Group className="mb-3">
                  <Form.Label>Fees (%, e.g. 0.1 = 0.1%)</Form.Label>
                  <Form.Control
                    type="number"
                    step={0.01}
                    min={0}
                    value={feesPercent}
                    onChange={(e) => setFeesPercent(Number(e.target.value))}
                  />
                </Form.Group>

                <h6>Starting Balances</h6>
                <Form.Group className="mb-3">
                  <Form.Label>
                    {parsedQuote ? `${parsedQuote} balance` : 'Quote balance'}
                  </Form.Label>
                  <Form.Control
                    type="number"
                    min={0}
                    step="any"
                    value={quoteBalance}
                    onChange={(e) => setQuoteBalance(e.target.value)}
                  />
                </Form.Group>
                <Form.Group className="mb-3">
                  <Form.Label>
                    {parsedBase ? `${parsedBase} balance` : 'Base balance'}
                  </Form.Label>
                  <Form.Control
                    type="number"
                    min={0}
                    step="any"
                    value={baseBalance}
                    onChange={(e) => setBaseBalance(e.target.value)}
                  />
                </Form.Group>
              </Col>

              <Col lg={4}>
                <h6>Run Parameters</h6>
                <Form.Group className="mb-3">
                  <Form.Label>Mode</Form.Label>
                  <Form.Select
                    value={mode}
                    onChange={(e) => {
                      setMode(e.target.value as 'live' | 'backtest');
                      if (e.target.value === 'live') setCandleInterval(null);
                    }}
                  >
                    <option value="live">Live</option>
                    <option value="backtest">Backtest</option>
                  </Form.Select>
                  {mode === 'backtest' && (
                    <Form.Text className="text-muted">
                      Replays historical data — runs immediately, no wall-clock wait.
                    </Form.Text>
                  )}
                </Form.Group>

                {mode === 'backtest' && (
                  <Form.Group className="mb-3">
                    <Form.Label>Data Mode</Form.Label>
                    <Form.Select
                      value={candleInterval ?? ''}
                      onChange={(e) => setCandleInterval(e.target.value || null)}
                    >
                      <option value="">Tick-by-tick (trade replay)</option>
                      <option value="1m">1m candles (~500x faster)</option>
                      <option value="5m">5m candles</option>
                      <option value="15m">15m candles</option>
                      <option value="1h">1h candles</option>
                      <option value="4h">4h candles</option>
                      <option value="1d">1d candles</option>
                    </Form.Select>
                    {candleInterval && nameExchange && exchange && (
                      <div className="mt-2">
                        {candleCoverage.isLoading && (
                          <Form.Text className="text-muted">Checking candle coverage…</Form.Text>
                        )}
                        {selectedCoverage && (
                          <Form.Text className="text-muted">
                            Available: {new Date(selectedCoverage.first_open).toLocaleString()} –{' '}
                            {new Date(selectedCoverage.last_close).toLocaleString()}{' '}
                            ({selectedCoverage.count.toLocaleString()} candles)
                          </Form.Text>
                        )}
                        {!candleCoverage.isLoading && candleCoverage.data && !selectedCoverage && (
                          <div>
                            <Form.Text className="text-warning d-block">
                              No {candleInterval} candle data found. Backfill from Binance:
                            </Form.Text>
                            <Button
                              size="sm"
                              variant="outline-primary"
                              className="mt-1"
                              disabled={backfillMutation.isPending || !startsAt || !finishesAt}
                              onClick={() =>
                                backfillMutation.mutate({
                                  exchange,
                                  symbol: nameExchange,
                                  interval: candleInterval,
                                  from: new Date(startsAt).toISOString(),
                                  to: new Date(finishesAt).toISOString(),
                                })
                              }
                            >
                              {backfillMutation.isPending ? (
                                <><Spinner size="sm" animation="border" className="me-1" />Backfilling…</>
                              ) : (
                                `Backfill ${candleInterval} candles`
                              )}
                            </Button>
                            {backfillMutation.isError && (
                              <Form.Text className="text-danger d-block">
                                {(backfillMutation.error as Error).message}
                              </Form.Text>
                            )}
                            {backfillMutation.isSuccess && (
                              <Form.Text className="text-success d-block">
                                Inserted {backfillMutation.data.inserted} candles.
                              </Form.Text>
                            )}
                          </div>
                        )}

                        {/* Additional timeframes referenced by the selected strategy */}
                        {additionalTimeframes.length > 0 && (
                          <div className="mt-2 border-top pt-2">
                            <Form.Text className="d-block mb-1" style={{ fontWeight: 600 }}>
                              Additional timeframes required:
                            </Form.Text>
                            {additionalTimeframes.map((tf) => {
                              const tfCov = candleCoverage.data?.find((c) => c.interval === tf);
                              return (
                                <div key={tf} className="mb-2">
                                  {candleCoverage.isLoading ? (
                                    <Form.Text className="text-muted">
                                      Checking {tf} coverage…
                                    </Form.Text>
                                  ) : tfCov ? (
                                    <Form.Text className="text-muted">
                                      {tf}: {new Date(tfCov.first_open).toLocaleString()} –{' '}
                                      {new Date(tfCov.last_close).toLocaleString()}{' '}
                                      ({tfCov.count.toLocaleString()} candles)
                                    </Form.Text>
                                  ) : (
                                    <div>
                                      <Form.Text className="text-warning d-block">
                                        No {tf} candle data. Backfill from Binance:
                                      </Form.Text>
                                      <Button
                                        size="sm"
                                        variant="outline-primary"
                                        className="mt-1"
                                        disabled={
                                          backfillMutation.isPending || !startsAt || !finishesAt
                                        }
                                        onClick={() =>
                                          backfillMutation.mutate({
                                            exchange,
                                            symbol: nameExchange!,
                                            interval: tf,
                                            from: new Date(startsAt).toISOString(),
                                            to: new Date(finishesAt).toISOString(),
                                          })
                                        }
                                      >
                                        {backfillMutation.isPending ? (
                                          <>
                                            <Spinner
                                              size="sm"
                                              animation="border"
                                              className="me-1"
                                            />
                                            Backfilling…
                                          </>
                                        ) : (
                                          `Backfill ${tf} candles`
                                        )}
                                      </Button>
                                    </div>
                                  )}
                                </div>
                              );
                            })}
                          </div>
                        )}
                      </div>
                    )}
                  </Form.Group>
                )}

                <Form.Group className="mb-3">
                  <div className="d-flex justify-content-between align-items-center mb-1">
                    <Form.Label className="mb-0">
                      {mode === 'backtest' ? 'Backtest Window' : 'Duration'}
                    </Form.Label>
                    <Form.Check
                      type="switch"
                      id="custom-dates-toggle"
                      label={<small className="text-muted">Custom dates</small>}
                      checked={customDates}
                      onChange={(e) => setCustomDates(e.target.checked)}
                    />
                  </div>
                  {!customDates ? (
                    <>
                      <div className="d-flex gap-2">
                        <Form.Control
                          type="number"
                          min={1}
                          value={timespanValue}
                          onChange={(e) => setTimespanValue(Math.max(1, Number(e.target.value)))}
                          style={{ width: '5rem' }}
                        />
                        <Form.Select
                          value={timespanUnit}
                          onChange={(e) => setTimespanUnit(e.target.value as TimespanUnit)}
                        >
                          <option value="minutes">minutes</option>
                          <option value="hours">hours</option>
                          <option value="days">days</option>
                          <option value="weeks">weeks</option>
                          <option value="months">months</option>
                        </Form.Select>
                      </div>
                      {mode === 'backtest' && (
                        <Form.Text className="text-muted">
                          {(candleInterval ? candleCoverage.isLoading : dataRange.isLoading)
                            ? 'Checking available data…'
                            : startsAt && finishesAt
                            ? `${new Date(startsAt).toLocaleString()} – ${new Date(finishesAt).toLocaleString()}`
                            : nameExchange
                            ? 'Select an instrument to resolve dates'
                            : ''}
                        </Form.Text>
                      )}
                    </>
                  ) : (
                    <>
                      <Form.Control
                        type="datetime-local"
                        value={startsAt}
                        onChange={(e) => setStartsAt(e.target.value)}
                        className="mb-2"
                      />
                      <Form.Control
                        type="datetime-local"
                        value={finishesAt}
                        onChange={(e) => setFinishesAt(e.target.value)}
                      />
                      {mode === 'backtest' && !candleInterval && nameExchange && (
                        <Form.Text className="text-muted">
                          {dataRange.isLoading && 'Checking available data…'}
                          {dataRange.data && (
                            <>
                              Available:{' '}
                              {new Date(dataRange.data.start).toLocaleString()} –{' '}
                              {new Date(dataRange.data.end).toLocaleString()}
                            </>
                          )}
                          {!dataRange.isLoading && dataRange.data === null && (
                            'No trade data available for this instrument'
                          )}
                        </Form.Text>
                      )}
                    </>
                  )}
                </Form.Group>
                <Form.Group className="mb-3">
                  <Form.Label>Risk-free return</Form.Label>
                  <Form.Control
                    type="number"
                    step={0.01}
                    value={riskFreeReturn}
                    onChange={(e) => setRiskFreeReturn(Number(e.target.value))}
                  />
                </Form.Group>
              </Col>

              <Col lg={4}>
                <h6>Strategy</h6>
                <Form.Group className="mb-3">
                  <Form.Label>Select strategy</Form.Label>
                  {strategies.isLoading ? (
                    <div><Spinner size="sm" animation="border" className="me-2" />Loading strategies…</div>
                  ) : (
                    <Form.Select
                      value={selectedStrategyId}
                      onChange={(e) => setSelectedStrategyId(e.target.value)}
                    >
                      <option value="">— None (no-op) —</option>
                      {ruleBasedStrategies.map((s) => (
                        <option key={s.id} value={s.id}>
                          {strategyLabel(s)}
                        </option>
                      ))}
                    </Form.Select>
                  )}
                  {!strategies.isLoading && ruleBasedStrategies.length === 0 && (
                    <Form.Text className="text-muted">
                      No rule-based strategies found. <a href="/strategies/new">Create one</a> first.
                    </Form.Text>
                  )}
                </Form.Group>

                {selectedStrategy && (
                  <Card className="mb-3" bg="light" border="secondary">
                    <Card.Body className="py-2 px-3" style={{ fontSize: '0.85em' }}>
                      <div className="d-flex align-items-center gap-2 mb-1">
                        <strong>{selectedStrategy.name ?? selectedStrategy.hash.slice(0, 16)}</strong>
                        {selectedStrategy.version > 1 && (
                          <Badge bg="secondary">v{selectedStrategy.version}</Badge>
                        )}
                      </div>
                      {(() => {
                        const cfg = selectedStrategy.config as Record<string, unknown>;
                        const interval = cfg.candle_interval as string | undefined;
                        const rules = Array.isArray(cfg.rules) ? cfg.rules.length : 0;
                        return (
                          <div className="text-muted">
                            {rules} rule{rules !== 1 ? 's' : ''}
                            {interval && <span className="ms-2">· {interval} candles</span>}
                          </div>
                        );
                      })()}
                      {selectedStrategy.description && (
                        <div className="text-muted mt-1" style={{ whiteSpace: 'pre-wrap' }}>
                          {selectedStrategy.description.trim()}
                        </div>
                      )}
                    </Card.Body>
                  </Card>
                )}
              </Col>
            </Row>

            <div className="mt-3 d-flex gap-2">
              <Button type="submit" disabled={createMutation.isPending || !formValid}>
                {createMutation.isPending ? (
                  <Spinner size="sm" animation="border" />
                ) : (
                  'Create Run'
                )}
              </Button>
              <Button
                variant="outline-secondary"
                onClick={() => navigate('/paper-runs')}
                disabled={createMutation.isPending}
              >
                Cancel
              </Button>
            </div>

            {createMutation.isError && (
              <Alert variant="danger" className="mt-3">
                {(createMutation.error as Error).message}
              </Alert>
            )}
          </Form>
        </Card.Body>
      </Card>
    </Container>
  );
}
