import { useState, useRef, useEffect } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import {
  LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip,
  ResponsiveContainer, ReferenceLine,
} from 'recharts';
import {
  TrendingUp, Play, Square, Plus, Trash2, Eraser,
  BarChart2, List, Target, Activity, Clock,
} from 'lucide-react';
import {
  tgtcApi,
  type TgtcSession,
  type TgtcStrategyInfo,
  type TgtcBacktestResult,
} from '../api/client';
import { Loading, ErrorState } from '../components/common/Loading';

// ── Styles ────────────────────────────────────────────────────────────────────

const card: React.CSSProperties = {
  background: 'var(--bg1)',
  border: '1px solid var(--border)',
  borderRadius: 12,
  overflow: 'hidden',
};

const inputStyle: React.CSSProperties = {
  width: '100%',
  padding: '8px 11px',
  fontSize: 14,
  fontFamily: 'var(--font-mono)',
  background: 'var(--bg2)',
  border: '1px solid var(--border-md)',
  borderRadius: 7,
  color: 'var(--text1)',
  outline: 'none',
};

const btn = (variant: 'primary' | 'danger' | 'ghost' | 'outline' = 'outline'): React.CSSProperties => ({
  display: 'inline-flex', alignItems: 'center', gap: 6,
  padding: '7px 14px', fontSize: 13, fontWeight: 500,
  borderRadius: 7, border: '1px solid', cursor: 'pointer',
  transition: 'all 0.12s', whiteSpace: 'nowrap' as const,
  background: variant === 'primary' ? 'var(--cyan)' : variant === 'danger' ? 'var(--red)' : 'transparent',
  color: variant === 'primary' ? '#fff' : variant === 'danger' ? '#fff' : variant === 'ghost' ? 'var(--text3)' : 'var(--text2)',
  borderColor: variant === 'primary' ? 'var(--cyan)' : variant === 'danger' ? 'var(--red)' : 'var(--border-md)',
});

function fmtPct(n: number | null | undefined) {
  if (n == null) return '—';
  return `${n >= 0 ? '+' : ''}${n.toFixed(2)}%`;
}
function fmtDollars(n: number | null | undefined) {
  if (n == null) return '—';
  return `${n >= 0 ? '+' : '−'}$${Math.abs(n).toFixed(2)}`;
}
function fmtScore(n: number | null | undefined) {
  if (n == null) return '—';
  return (n * 100).toFixed(0);
}

// ── Scheduler Panel ───────────────────────────────────────────────────────────

function SchedulerPanel({ selectedSessions }: { selectedSessions: string[] }) {
  const qc = useQueryClient();
  const [showLog, setShowLog] = useState(false);
  const logRef = useRef<HTMLPreElement>(null);

  const { data } = useQuery({
    queryKey: ['tgtc-auto-status'],
    queryFn: tgtcApi.autoStatus,
    refetchInterval: 5000,
  });

  const startMut = useMutation({
    mutationFn: () => tgtcApi.autoStart(selectedSessions, true),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['tgtc-auto-status'] }),
    onError: (e: Error) => alert(`스케줄러 시작 실패: ${e.message}`),
  });

  const stopMut = useMutation({
    mutationFn: tgtcApi.autoStop,
    onSuccess: () => qc.invalidateQueries({ queryKey: ['tgtc-auto-status'] }),
    onError: (e: Error) => alert(`스케줄러 중지 실패: ${e.message}`),
  });

  const clearLogMut = useMutation({
    mutationFn: tgtcApi.clearLog,
    onSuccess: () => qc.invalidateQueries({ queryKey: ['tgtc-auto-status'] }),
  });

  const running = data?.running ?? false;
  const logLines = data?.log_lines ?? [];

  return (
    <div style={{ ...card, marginBottom: 20 }}>
      <div style={{ padding: '14px 18px', borderBottom: '1px solid var(--border)', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <Clock size={15} style={{ color: 'var(--cyan)' }} />
          <span style={{ fontWeight: 600, fontSize: 15 }}>TGTC Scheduler</span>
          <span style={{
            display: 'inline-flex', alignItems: 'center', gap: 5,
            padding: '3px 9px', borderRadius: 99, fontSize: 11, fontWeight: 600,
            background: running ? 'rgba(0,255,136,0.12)' : 'var(--bg2)',
            color: running ? 'var(--green)' : 'var(--text3)',
            border: `1px solid ${running ? 'var(--green)' : 'var(--border)'}`,
          }}>
            <span style={{ width: 6, height: 6, borderRadius: '50%', background: running ? 'var(--green)' : 'var(--text3)', animation: running ? 'pulse-line 2s infinite' : undefined }} />
            {running ? 'LIVE (DRY-RUN)' : 'IDLE'}
          </span>
        </div>
        <div style={{ display: 'flex', gap: 8 }}>
          {!running && (
            <button style={btn('primary')} onClick={() => startMut.mutate()} disabled={startMut.isPending}>
              <Play size={13} /> Start Dry-Run
            </button>
          )}
          {running && (
            <button style={btn('danger')} onClick={() => stopMut.mutate()} disabled={stopMut.isPending}>
              <Square size={13} /> Stop
            </button>
          )}
          <button style={btn('ghost')} onClick={() => setShowLog(v => !v)}>
            {showLog ? 'Hide Log' : 'Show Log'}
          </button>
          <button style={btn('ghost')} onClick={() => clearLogMut.mutate()}>
            <Eraser size={13} />
          </button>
        </div>
      </div>

      {showLog && (
        <div style={{ padding: 12, background: 'var(--bg2)' }}>
          <pre
            ref={logRef}
            style={{
              margin: 0, fontSize: 11, fontFamily: 'var(--font-mono)',
              color: 'var(--text2)', lineHeight: 1.55,
              maxHeight: 260, overflowY: 'auto', whiteSpace: 'pre-wrap',
            }}
          >
            {logLines.length ? logLines.join('\n') : '(로그 없음)'}
          </pre>
        </div>
      )}
    </div>
  );
}

// ── Create Session Modal ───────────────────────────────────────────────────────

function CreateSessionModal({ onClose, onCreated }: { onClose: () => void; onCreated: () => void }) {
  const [name, setName] = useState('');
  const [capital, setCapital] = useState('10000');
  const [selectedConfig, setSelectedConfig] = useState('');

  const { data: strategiesData } = useQuery({
    queryKey: ['tgtc-strategies'],
    queryFn: tgtcApi.strategies,
  });

  const strategies: TgtcStrategyInfo[] = strategiesData?.strategies ?? [];

  const createMut = useMutation({
    mutationFn: () => tgtcApi.createSession(name, selectedConfig, parseFloat(capital)),
    onSuccess: () => { onCreated(); onClose(); },
    onError: (e: Error) => alert(`세션 생성 실패: ${e.message}`),
  });

  return (
    <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.6)', zIndex: 100, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
      <div style={{ ...card, width: 520, maxWidth: '95vw', padding: 24 }}>
        <div style={{ fontSize: 17, fontWeight: 700, marginBottom: 18, display: 'flex', alignItems: 'center', gap: 8 }}>
          <TrendingUp size={16} style={{ color: 'var(--cyan)' }} /> 새 TGTC 세션
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <div>
            <div style={{ fontSize: 12, color: 'var(--text3)', marginBottom: 5, fontFamily: 'var(--font-mono)', textTransform: 'uppercase', letterSpacing: '0.05em' }}>세션 이름</div>
            <input style={inputStyle} value={name} onChange={e => setName(e.target.value)} placeholder="예: tgtc-live-01" />
          </div>

          <div>
            <div style={{ fontSize: 12, color: 'var(--text3)', marginBottom: 5, fontFamily: 'var(--font-mono)', textTransform: 'uppercase', letterSpacing: '0.05em' }}>초기 자본 ($)</div>
            <input style={inputStyle} type="number" value={capital} onChange={e => setCapital(e.target.value)} />
          </div>

          <div>
            <div style={{ fontSize: 12, color: 'var(--text3)', marginBottom: 8, fontFamily: 'var(--font-mono)', textTransform: 'uppercase', letterSpacing: '0.05em' }}>전략 설정</div>
            {strategies.map(s => (
              <div
                key={s.config_path}
                onClick={() => setSelectedConfig(s.config_path)}
                style={{
                  padding: '10px 14px', borderRadius: 8, marginBottom: 6, cursor: 'pointer',
                  border: `1px solid ${selectedConfig === s.config_path ? 'var(--cyan)' : 'var(--border)'}`,
                  background: selectedConfig === s.config_path ? 'rgba(0,119,182,0.08)' : 'var(--bg2)',
                  transition: 'all 0.1s',
                }}
              >
                <div style={{ fontSize: 13, fontWeight: 600, color: selectedConfig === s.config_path ? 'var(--cyan)' : 'var(--text1)' }}>{s.name}</div>
                <div style={{ fontSize: 11, color: 'var(--text3)', marginTop: 2 }}>{s.config_path}</div>
                {s.live_readiness && (
                  <div style={{ fontSize: 11, color: 'var(--orange)', marginTop: 3 }}>
                    [{s.live_readiness}] {s.status}
                  </div>
                )}
              </div>
            ))}
            {strategies.length === 0 && (
              <div style={{ fontSize: 13, color: 'var(--text3)' }}>configs/intraday/strategies/tgtc_*.yaml 파일 없음</div>
            )}
          </div>

          <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8, marginTop: 4 }}>
            <button style={btn('ghost')} onClick={onClose}>취소</button>
            <button
              style={btn('primary')}
              onClick={() => createMut.mutate()}
              disabled={!name || !selectedConfig || createMut.isPending}
            >
              생성
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Session Card ──────────────────────────────────────────────────────────────

function SessionCard({
  session,
  isSelected,
  onClick,
  onDelete,
}: {
  session: TgtcSession;
  isSelected: boolean;
  onClick: () => void;
  onDelete: () => void;
}) {
  const pnl = session.current_equity - session.initial_equity;
  const positive = pnl >= 0;

  return (
    <div
      onClick={onClick}
      style={{
        ...card,
        cursor: 'pointer',
        padding: '16px 18px',
        borderColor: isSelected ? 'var(--cyan)' : 'var(--border)',
        transition: 'border-color 0.12s',
        position: 'relative',
      }}
    >
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
        <div>
          <div style={{ fontSize: 14, fontWeight: 600, fontFamily: 'var(--font-mono)' }}>{session.session_name}</div>
          <div style={{ fontSize: 11, color: 'var(--text3)', marginTop: 2 }}>{session.phase}</div>
        </div>
        <button
          style={{ ...btn('ghost'), padding: '4px 8px', color: 'var(--text3)' }}
          onClick={e => { e.stopPropagation(); onDelete(); }}
        >
          <Trash2 size={13} />
        </button>
      </div>

      <div style={{ display: 'flex', gap: 20, marginTop: 12 }}>
        <div>
          <div style={{ fontSize: 11, color: 'var(--text3)' }}>현재 자본</div>
          <div style={{ fontSize: 16, fontWeight: 700, fontFamily: 'var(--font-mono)' }}>
            ${session.current_equity.toLocaleString(undefined, { minimumFractionDigits: 2 })}
          </div>
        </div>
        <div>
          <div style={{ fontSize: 11, color: 'var(--text3)' }}>수익률</div>
          <div style={{ fontSize: 15, fontWeight: 700, color: positive ? 'var(--green)' : 'var(--red)', fontFamily: 'var(--font-mono)' }}>
            {fmtPct(session.total_return_pct)}
          </div>
        </div>
      </div>

      {session.ran_today && (
        <div style={{ marginTop: 8, fontSize: 11, color: 'var(--cyan)' }}>● 오늘 실행됨</div>
      )}
    </div>
  );
}

// ── Quick Backtest Panel ──────────────────────────────────────────────────────

function QuickBacktestPanel() {
  const [btDate, setBtDate] = useState('');
  const [btEndDate, setBtEndDate] = useState('');
  const [btConfig, setBtConfig] = useState('');
  const [btLoading, setBtLoading] = useState(false);
  const [btResult, setBtResult] = useState<TgtcBacktestResult | null>(null);
  const [btError, setBtError] = useState<string | null>(null);
  const [collapsed, setCollapsed] = useState(false);

  const { data: strategiesData } = useQuery({
    queryKey: ['tgtc-strategies'],
    queryFn: tgtcApi.strategies,
  });
  const strategies: TgtcStrategyInfo[] = strategiesData?.strategies ?? [];

  useEffect(() => {
    if (strategies.length > 0 && !btConfig) setBtConfig(strategies[0].config_path);
  }, [strategies, btConfig]);

  const isMultiday = btEndDate && btEndDate > btDate;
  const maxPollAttempts = isMultiday ? 200 : 60;

  const handleRun = async () => {
    if (!btDate) { alert('시작 날짜를 입력하세요'); return; }
    if (!btConfig) { alert('전략 config를 선택하세요'); return; }
    setBtLoading(true); setBtError(null); setBtResult(null);
    try {
      const endDate = btEndDate && btEndDate > btDate ? btEndDate : undefined;
      const { task_id } = await tgtcApi.submitBacktest(btDate, btConfig, undefined, endDate);
      let attempt = 0;
      const poll = async () => {
        const task = await tgtcApi.backtestTask(task_id);
        if (task.status === 'completed' && task.result) {
          setBtResult(task.result); setBtLoading(false);
        } else if (task.status === 'failed') {
          setBtError(task.error || '백테스트 실패'); setBtLoading(false);
        } else if (attempt < maxPollAttempts) {
          attempt++; setTimeout(poll, 3000);
        } else {
          setBtError('타임아웃'); setBtLoading(false);
        }
      };
      setTimeout(poll, 2000);
    } catch (e: unknown) {
      setBtError(e instanceof Error ? e.message : String(e)); setBtLoading(false);
    }
  };

  const thS: React.CSSProperties = { padding: '7px 10px', textAlign: 'left' as const, fontSize: 11, fontFamily: 'var(--font-mono)', textTransform: 'uppercase' as const, color: 'var(--text3)', background: 'var(--bg2)', borderBottom: '1px solid var(--border)' };
  const tdS: React.CSSProperties = { padding: '7px 10px', fontSize: 12, fontFamily: 'var(--font-mono)', borderBottom: '1px solid var(--border)' };

  const panelLabel = isMultiday ? '기간 백테스트' : '단일 날짜 백테스트';

  return (
    <div style={{ ...card, marginBottom: 20 }}>
      <div
        style={{ padding: '13px 18px', borderBottom: collapsed ? 'none' : '1px solid var(--border)', display: 'flex', alignItems: 'center', justifyContent: 'space-between', cursor: 'pointer' }}
        onClick={() => setCollapsed(v => !v)}
      >
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <BarChart2 size={15} style={{ color: 'var(--cyan)' }} />
          <span style={{ fontWeight: 600, fontSize: 15 }}>{panelLabel}</span>
          <span style={{ fontSize: 11, color: 'var(--text3)', fontFamily: 'var(--font-mono)' }}>
            5분봉 → Yahoo Top Gainer 합성 재구성 → VWAP pullback reclaim 시뮬레이션
          </span>
        </div>
        <span style={{ fontSize: 12, color: 'var(--text3)' }}>{collapsed ? '▼' : '▲'}</span>
      </div>

      {!collapsed && (
        <div style={{ padding: '16px 18px' }}>
          <div style={{ display: 'flex', gap: 10, alignItems: 'flex-end', marginBottom: 16, flexWrap: 'wrap' as const }}>
            <div style={{ flex: '0 0 180px' }}>
              <div style={{ fontSize: 11, color: 'var(--text3)', marginBottom: 4 }}>시작 날짜</div>
              <input style={inputStyle} type="date" value={btDate} onChange={e => setBtDate(e.target.value)} />
            </div>
            <div style={{ flex: '0 0 180px' }}>
              <div style={{ fontSize: 11, color: 'var(--text3)', marginBottom: 4 }}>종료 날짜 <span style={{ color: 'var(--text3)', fontStyle: 'italic' }}>(선택 — 기간 백테스트)</span></div>
              <input style={inputStyle} type="date" value={btEndDate} onChange={e => setBtEndDate(e.target.value)} />
            </div>
            <div style={{ flex: 1, minWidth: 240 }}>
              <div style={{ fontSize: 11, color: 'var(--text3)', marginBottom: 4 }}>전략 Config</div>
              <select style={inputStyle} value={btConfig} onChange={e => setBtConfig(e.target.value)}>
                <option value="">— 선택 —</option>
                {strategies.map(s => (
                  <option key={s.config_path} value={s.config_path}>{s.name}</option>
                ))}
              </select>
            </div>
            <button style={btn('primary')} onClick={handleRun} disabled={btLoading || !btDate || !btConfig}>
              <Play size={13} /> {btLoading ? '실행 중...' : (isMultiday ? '기간 백테스트 실행' : '백테스트 실행')}
            </button>
          </div>

          {btError && (
            <div style={{ padding: 10, borderRadius: 8, background: 'rgba(255,60,60,0.1)', border: '1px solid var(--red)', color: 'var(--red)', fontSize: 13, marginBottom: 12 }}>
              {btError}
            </div>
          )}
          {btLoading && (
            <div style={{ color: 'var(--text3)', fontSize: 13 }}>
              시뮬레이션 실행 중{isMultiday ? ' (기간 백테스트는 수분 소요)' : ''}...
            </div>
          )}

          {btResult && (
            <div>
              {/* Summary metrics */}
              <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', marginBottom: 14 }}>
                {(btResult.type === 'multiday' ? [
                  { label: '기간', val: `${btResult.start_date} ~ ${btResult.end_date}` },
                  { label: '거래일', val: `${btResult.n_days}일` },
                  { label: '총 거래', val: String(btResult.n_trades) },
                  { label: '총 P&L', val: fmtDollars(btResult.total_pnl), color: btResult.total_pnl >= 0 ? 'var(--green)' : 'var(--red)' },
                  { label: '누적 수익률', val: fmtPct(btResult.total_return_pct), color: btResult.total_return_pct >= 0 ? 'var(--green)' : 'var(--red)' },
                  { label: '승률', val: `${btResult.win_rate.toFixed(0)}%` },
                ] : [
                  { label: '날짜', val: btResult.date ?? '—' },
                  { label: '후보', val: String(btResult.n_candidates ?? 0) },
                  { label: '거래', val: String(btResult.n_trades) },
                  { label: '총 P&L', val: fmtDollars(btResult.total_pnl), color: btResult.total_pnl >= 0 ? 'var(--green)' : 'var(--red)' },
                  { label: '수익률', val: fmtPct(btResult.total_return_pct), color: btResult.total_return_pct >= 0 ? 'var(--green)' : 'var(--red)' },
                  { label: '승률', val: `${btResult.win_rate.toFixed(0)}%` },
                ]).map(m => (
                  <div key={m.label} style={{ ...card, padding: '9px 14px', minWidth: 90 }}>
                    <div style={{ fontSize: 10, color: 'var(--text3)' }}>{m.label}</div>
                    <div style={{ fontSize: 15, fontWeight: 700, fontFamily: 'var(--font-mono)', color: m.color || 'var(--text1)' }}>{m.val}</div>
                  </div>
                ))}
              </div>

              {/* Equity curve */}
              {btResult.type === 'multiday' && btResult.equity_curve && btResult.equity_curve.length > 1 && (
                <div style={{ marginBottom: 14 }}>
                  <div style={{ fontSize: 12, color: 'var(--text3)', marginBottom: 6 }}>누적 자본 곡선</div>
                  <ResponsiveContainer width="100%" height={180}>
                    <LineChart data={btResult.equity_curve}>
                      <CartesianGrid strokeDasharray="3 3" stroke="var(--border)" />
                      <XAxis dataKey="date" tick={{ fontSize: 10, fill: 'var(--text3)' }} />
                      <YAxis tick={{ fontSize: 10, fill: 'var(--text3)' }} domain={['auto', 'auto']} />
                      <Tooltip contentStyle={{ background: 'var(--bg1)', border: '1px solid var(--border)', fontSize: 12 }} />
                      <ReferenceLine y={btResult.initial_equity} stroke="var(--text3)" strokeDasharray="4 4" />
                      <Line type="monotone" dataKey="equity" stroke="var(--cyan)" dot={false} strokeWidth={2} />
                    </LineChart>
                  </ResponsiveContainer>
                </div>
              )}
              {btResult.type !== 'multiday' && btResult.equity_curve && btResult.equity_curve.length > 0 && (
                <div style={{ marginBottom: 14 }}>
                  <div style={{ fontSize: 12, color: 'var(--text3)', marginBottom: 6 }}>장중 가상 자본 곡선</div>
                  <ResponsiveContainer width="100%" height={150}>
                    <LineChart data={btResult.equity_curve}>
                      <CartesianGrid strokeDasharray="3 3" stroke="var(--border)" />
                      <XAxis dataKey="ts_et" tick={{ fontSize: 10, fill: 'var(--text3)' }} />
                      <YAxis tick={{ fontSize: 10, fill: 'var(--text3)' }} domain={['auto', 'auto']} />
                      <Tooltip contentStyle={{ background: 'var(--bg1)', border: '1px solid var(--border)', fontSize: 12 }} />
                      <ReferenceLine y={btResult.initial_equity} stroke="var(--text3)" strokeDasharray="4 4" />
                      <Line type="monotone" dataKey="equity" stroke="var(--cyan)" dot={false} strokeWidth={2} />
                    </LineChart>
                  </ResponsiveContainer>
                </div>
              )}

              {/* Per-day table for multi-day */}
              {btResult.type === 'multiday' && btResult.per_day && btResult.per_day.length > 0 && (
                <div style={{ marginBottom: 14 }}>
                  <div style={{ fontSize: 12, color: 'var(--text3)', marginBottom: 6 }}>일별 결과</div>
                  <table style={{ width: '100%', borderCollapse: 'collapse' }}>
                    <thead>
                      <tr>{['날짜', '후보', '거래', 'P&L', '수익률', '승률', '누적 자본'].map(h => <th key={h} style={thS}>{h}</th>)}</tr>
                    </thead>
                    <tbody>
                      {btResult.per_day.map((d, i) => (
                        <tr key={d.date} style={{ background: i % 2 === 0 ? 'transparent' : 'var(--bg2)' }}>
                          <td style={{ ...tdS, color: 'var(--text3)' }}>{d.date}</td>
                          <td style={tdS}>{d.n_candidates}</td>
                          <td style={tdS}>{d.n_trades}</td>
                          <td style={{ ...tdS, color: d.pnl >= 0 ? 'var(--green)' : 'var(--red)', fontWeight: 600 }}>{fmtDollars(d.pnl)}</td>
                          <td style={{ ...tdS, color: d.return_pct >= 0 ? 'var(--green)' : 'var(--red)' }}>{fmtPct(d.return_pct)}</td>
                          <td style={tdS}>{d.win_rate.toFixed(0)}%</td>
                          <td style={{ ...tdS, fontFamily: 'var(--font-mono)' }}>${d.equity.toLocaleString(undefined, { minimumFractionDigits: 2 })}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              )}

              {/* Trade list */}
              {btResult.trades.length > 0 ? (
                <div>
                  <div style={{ fontSize: 12, color: 'var(--text3)', marginBottom: 6 }}>트레이드 내역 ({btResult.trades.length}건)</div>
                  <table style={{ width: '100%', borderCollapse: 'collapse' }}>
                    <thead>
                      <tr>
                        {(btResult.type === 'multiday'
                          ? ['날짜', '종목', '진입가', '청산가', '주수', 'P&L', 'R', '청산이유']
                          : ['종목', '진입가', '청산가', '주수', 'P&L', 'R', '청산이유']
                        ).map(h => <th key={h} style={thS}>{h}</th>)}
                      </tr>
                    </thead>
                    <tbody>
                      {btResult.trades.map((t, i) => (
                        <tr key={i}>
                          {btResult.type === 'multiday' && <td style={{ ...tdS, color: 'var(--text3)' }}>{t.date ?? '—'}</td>}
                          <td style={{ ...tdS, fontWeight: 600 }}>{t.symbol}</td>
                          <td style={tdS}>${t.entry_price.toFixed(2)}</td>
                          <td style={tdS}>${t.exit_price.toFixed(2)}</td>
                          <td style={tdS}>{t.shares}</td>
                          <td style={{ ...tdS, color: t.pnl >= 0 ? 'var(--green)' : 'var(--red)', fontWeight: 600 }}>{fmtDollars(t.pnl)}</td>
                          <td style={{ ...tdS, color: t.r_multiple >= 0 ? 'var(--green)' : 'var(--red)' }}>
                            {t.r_multiple >= 0 ? '+' : ''}{t.r_multiple.toFixed(2)}R
                          </td>
                          <td style={{ ...tdS, color: 'var(--text3)', fontSize: 11 }}>{t.exit_reason}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              ) : (
                <div style={{ color: 'var(--text3)', fontSize: 13 }}>
                  {btResult.type === 'multiday'
                    ? `${btResult.n_days}일 중 진입 시그널 없음`
                    : btResult.n_candidates === 0
                      ? '이 날 TGTC 후보 없음 (데이터 없거나 필터 기준 미달)'
                      : `후보 ${btResult.n_candidates}개 있었으나 진입 시그널 없음`}
                </div>
              )}
            </div>
          )}
        </div>
      )}
    </div>
  );
}

// ── Session Detail Tabs ────────────────────────────────────────────────────────

type TabKey = 'snapshots' | 'candidates' | 'positions' | 'trades' | 'equity';

function SessionDetail({ session }: { session: TgtcSession }) {
  const [tab, setTab] = useState<TabKey>('candidates');

  const tabs: { key: TabKey; label: string; icon: React.ReactNode }[] = [
    { key: 'snapshots', label: 'Snapshots', icon: <Activity size={13} /> },
    { key: 'candidates', label: 'Candidates', icon: <Target size={13} /> },
    { key: 'positions', label: 'Positions', icon: <TrendingUp size={13} /> },
    { key: 'trades', label: 'Trades', icon: <List size={13} /> },
    { key: 'equity', label: 'Equity', icon: <BarChart2 size={13} /> },
  ];

  const { data: snapshotData } = useQuery({
    queryKey: ['tgtc-snapshots', session.session_id],
    queryFn: () => tgtcApi.snapshots(session.session_id),
    refetchInterval: tab === 'snapshots' ? 30000 : false,
    enabled: tab === 'snapshots',
  });

  const { data: candidatesData } = useQuery({
    queryKey: ['tgtc-candidates', session.session_id],
    queryFn: () => tgtcApi.candidates(session.session_id),
    refetchInterval: 60000,
  });

  const { data: positionsData } = useQuery({
    queryKey: ['tgtc-positions', session.session_id],
    queryFn: () => tgtcApi.positions(session.session_id),
    refetchInterval: 30000,
  });

  const { data: tradesData } = useQuery({
    queryKey: ['tgtc-trades', session.session_id],
    queryFn: () => tgtcApi.trades(session.session_id),
    refetchInterval: 60000,
  });

  const { data: equityData } = useQuery({
    queryKey: ['tgtc-equity', session.session_id],
    queryFn: () => tgtcApi.equity(session.session_id),
    refetchInterval: tab === 'equity' ? 60000 : false,
    enabled: tab === 'equity',
  });



  const thStyle: React.CSSProperties = {
    padding: '8px 12px', textAlign: 'left' as const,
    fontSize: 11, fontFamily: 'var(--font-mono)',
    letterSpacing: '0.06em', textTransform: 'uppercase' as const,
    color: 'var(--text3)', background: 'var(--bg2)',
    borderBottom: '1px solid var(--border)',
  };
  const tdStyle: React.CSSProperties = {
    padding: '8px 12px', fontSize: 12, fontFamily: 'var(--font-mono)',
    borderBottom: '1px solid var(--border)',
  };

  return (
    <div style={{ ...card, marginTop: 16 }}>
      {/* Tab bar */}
      <div style={{ display: 'flex', gap: 0, borderBottom: '1px solid var(--border)' }}>
        {tabs.map(t => (
          <button
            key={t.key}
            onClick={() => setTab(t.key)}
            style={{
              display: 'inline-flex', alignItems: 'center', gap: 6,
              padding: '11px 16px', fontSize: 13, fontWeight: 500,
              background: 'transparent', border: 'none', cursor: 'pointer',
              borderBottom: tab === t.key ? '2px solid var(--cyan)' : '2px solid transparent',
              color: tab === t.key ? 'var(--cyan)' : 'var(--text2)',
              transition: 'all 0.1s',
            }}
          >
            {t.icon} {t.label}
          </button>
        ))}
      </div>

      <div style={{ padding: 16 }}>

        {/* Snapshots tab */}
        {tab === 'snapshots' && (
          <>
            <div style={{ fontSize: 12, color: 'var(--text3)', marginBottom: 10 }}>
              Yahoo day_gainers 최신 스냅샷 (장 시작 후 09:29:30~10:00 수집, 30초 폴링)
            </div>
            {!snapshotData || snapshotData.count === 0 ? (
              <div style={{ color: 'var(--text3)', fontSize: 13 }}>
                스냅샷 없음 — 장중 Auto Start 후 수집됨
              </div>
            ) : (
              <table style={{ width: '100%', borderCollapse: 'collapse' }}>
                <thead>
                  <tr>
                    {['순위', '종목', '등락률', '가격', '거래량', '수집시각'].map(h => (
                      <th key={h} style={thStyle}>{h}</th>
                    ))}
                  </tr>
                </thead>
                <tbody>
                  {snapshotData.snapshots.slice(0, 50).map((s, i) => (
                    <tr key={i} style={{ background: i % 2 === 0 ? 'transparent' : 'var(--bg2)' }}>
                      <td style={tdStyle}>{s.rank}</td>
                      <td style={{ ...tdStyle, fontWeight: 600, color: 'var(--cyan)' }}>{s.symbol}</td>
                      <td style={{ ...tdStyle, color: (s.pct_change ?? 0) >= 0 ? 'var(--green)' : 'var(--red)' }}>
                        {s.pct_change != null ? `${(s.pct_change * 100).toFixed(1)}%` : '—'}
                      </td>
                      <td style={tdStyle}>{s.price != null ? `$${s.price.toFixed(2)}` : '—'}</td>
                      <td style={tdStyle}>{s.volume != null ? s.volume.toLocaleString(undefined, { maximumFractionDigits: 0 }) : '—'}</td>
                      <td style={{ ...tdStyle, color: 'var(--text3)' }}>{s.captured_at?.slice(11, 19)}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            )}
          </>
        )}

        {/* Candidates tab */}
        {tab === 'candidates' && (
          <>
            <div style={{ fontSize: 12, color: 'var(--text3)', marginBottom: 10 }}>
              10:00 ET 후보 (rank_persistence + VWAP + 점수 기반 선별)
            </div>
            {!candidatesData || candidatesData.candidates.length === 0 ? (
              <div style={{ color: 'var(--text3)', fontSize: 13 }}>후보 없음</div>
            ) : (
              <table style={{ width: '100%', borderCollapse: 'collapse' }}>
                <thead>
                  <tr>
                    {['종목', 'Score', 'Persist', 'Velocity', 'Struct', 'VolQ', 'RS', '%Change@10', 'VWAP', '상태'].map(h => (
                      <th key={h} style={thStyle}>{h}</th>
                    ))}
                  </tr>
                </thead>
                <tbody>
                  {candidatesData.candidates.map((c, i) => (
                    <tr key={c.symbol} style={{ background: i % 2 === 0 ? 'transparent' : 'var(--bg2)' }}>
                      <td style={{ ...tdStyle, fontWeight: 700, color: 'var(--cyan)' }}>{c.symbol}</td>
                      <td style={{ ...tdStyle, color: 'var(--yellow)' }}>{fmtScore(c.score)}</td>
                      <td style={tdStyle}>{fmtScore(c.rank_persistence)}</td>
                      <td style={tdStyle}>{c.rank_velocity != null ? (c.rank_velocity >= 0 ? '+' : '') + (c.rank_velocity * 100).toFixed(0) : '—'}</td>
                      <td style={tdStyle}>{fmtScore(c.price_structure)}</td>
                      <td style={tdStyle}>{fmtScore(c.volume_quality)}</td>
                      <td style={tdStyle}>{fmtScore(c.relative_strength)}</td>
                      <td style={{ ...tdStyle, color: (c.pct_change_at_10 ?? 0) >= 0 ? 'var(--green)' : 'var(--red)' }}>
                        {c.pct_change_at_10 != null ? `${(c.pct_change_at_10 * 100).toFixed(1)}%` : '—'}
                      </td>
                      <td style={{ ...tdStyle, color: c.above_vwap ? 'var(--green)' : 'var(--red)' }}>
                        {c.above_vwap ? '↑VWAP' : '↓VWAP'}
                      </td>
                      <td style={{ ...tdStyle, color: 'var(--text3)', fontSize: 11 }}>{c.status}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            )}
          </>
        )}

        {/* Positions tab */}
        {tab === 'positions' && (
          <>
            <div style={{ fontSize: 12, color: 'var(--text3)', marginBottom: 10 }}>
              가상 포지션 (Dry-Run — 실주문 없음)
            </div>
            {!positionsData || positionsData.positions.length === 0 ? (
              <div style={{ color: 'var(--text3)', fontSize: 13 }}>포지션 없음</div>
            ) : (
              <table style={{ width: '100%', borderCollapse: 'collapse' }}>
                <thead>
                  <tr>
                    {['날짜', '종목', '진입가', '현재 스탑', '주수', 'P&L', '상태', '청산 이유'].map(h => (
                      <th key={h} style={thStyle}>{h}</th>
                    ))}
                  </tr>
                </thead>
                <tbody>
                  {positionsData.positions.map((p, i) => (
                    <tr key={i} style={{ background: i % 2 === 0 ? 'transparent' : 'var(--bg2)' }}>
                      <td style={{ ...tdStyle, color: 'var(--text3)' }}>{p.date}</td>
                      <td style={{ ...tdStyle, fontWeight: 700, color: 'var(--cyan)' }}>{p.symbol}</td>
                      <td style={tdStyle}>${p.entry_price.toFixed(2)}</td>
                      <td style={tdStyle}>${p.current_stop.toFixed(2)}</td>
                      <td style={tdStyle}>{p.shares}</td>
                      <td style={{ ...tdStyle, color: (p.pnl ?? 0) >= 0 ? 'var(--green)' : 'var(--red)' }}>
                        {fmtDollars(p.pnl)}
                      </td>
                      <td style={{ ...tdStyle, color: p.status === 'open' ? 'var(--cyan)' : 'var(--text3)', fontSize: 11 }}>
                        {p.status}
                      </td>
                      <td style={{ ...tdStyle, color: 'var(--text3)', fontSize: 11 }}>{p.exit_reason ?? '—'}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            )}
          </>
        )}

        {/* Trades tab */}
        {tab === 'trades' && (
          <>
            {!tradesData || tradesData.trades.length === 0 ? (
              <div style={{ color: 'var(--text3)', fontSize: 13 }}>거래 없음</div>
            ) : (
              <table style={{ width: '100%', borderCollapse: 'collapse' }}>
                <thead>
                  <tr>
                    {['날짜', '종목', '진입가', '청산가', '주수', 'P&L', 'R', '이유'].map(h => (
                      <th key={h} style={thStyle}>{h}</th>
                    ))}
                  </tr>
                </thead>
                <tbody>
                  {tradesData.trades.map((t, i) => (
                    <tr key={t.trade_id} style={{ background: i % 2 === 0 ? 'transparent' : 'var(--bg2)' }}>
                      <td style={{ ...tdStyle, color: 'var(--text3)' }}>{t.date}</td>
                      <td style={{ ...tdStyle, fontWeight: 700, color: 'var(--cyan)' }}>{t.symbol}</td>
                      <td style={tdStyle}>${t.entry_price.toFixed(2)}</td>
                      <td style={tdStyle}>${t.exit_price.toFixed(2)}</td>
                      <td style={tdStyle}>{t.shares}</td>
                      <td style={{ ...tdStyle, color: t.pnl >= 0 ? 'var(--green)' : 'var(--red)', fontWeight: 700 }}>
                        {fmtDollars(t.pnl)}
                      </td>
                      <td style={{ ...tdStyle, color: t.r_multiple >= 0 ? 'var(--green)' : 'var(--red)' }}>
                        {t.r_multiple >= 0 ? '+' : ''}{t.r_multiple.toFixed(2)}R
                      </td>
                      <td style={{ ...tdStyle, color: 'var(--text3)', fontSize: 11 }}>{t.exit_reason}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            )}
          </>
        )}

        {/* Equity tab */}
        {tab === 'equity' && (
          <>
            {!equityData ? (
              <Loading />
            ) : (
              <>
                <div style={{ display: 'flex', gap: 24, marginBottom: 16 }}>
                  <div>
                    <div style={{ fontSize: 11, color: 'var(--text3)' }}>초기 자본</div>
                    <div style={{ fontWeight: 700, fontFamily: 'var(--font-mono)' }}>
                      ${equityData.initial_equity.toLocaleString()}
                    </div>
                  </div>
                  <div>
                    <div style={{ fontSize: 11, color: 'var(--text3)' }}>현재 자본</div>
                    <div style={{ fontWeight: 700, fontFamily: 'var(--font-mono)', color: 'var(--cyan)' }}>
                      ${equityData.current_equity.toLocaleString(undefined, { minimumFractionDigits: 2 })}
                    </div>
                  </div>
                </div>
                {Array.isArray(equityData.daily_snapshots) && equityData.daily_snapshots.length > 0 && (
                  <ResponsiveContainer width="100%" height={200}>
                    <LineChart data={equityData.daily_snapshots as Array<{ date: string; equity: number }>}>
                      <CartesianGrid strokeDasharray="3 3" stroke="var(--border)" />
                      <XAxis dataKey="date" tick={{ fontSize: 10, fill: 'var(--text3)' }} />
                      <YAxis tick={{ fontSize: 10, fill: 'var(--text3)' }} />
                      <Tooltip contentStyle={{ background: 'var(--bg1)', border: '1px solid var(--border)', fontSize: 12 }} />
                      <ReferenceLine y={equityData.initial_equity} stroke="var(--text3)" strokeDasharray="4 4" />
                      <Line type="monotone" dataKey="equity" stroke="var(--cyan)" dot={false} strokeWidth={2} />
                    </LineChart>
                  </ResponsiveContainer>
                )}
              </>
            )}
          </>
        )}

      </div>
    </div>
  );
}

// ── Main Page ─────────────────────────────────────────────────────────────────

export function TgtcTradingPage() {
  const qc = useQueryClient();
  const [showCreate, setShowCreate] = useState(false);
  const [selectedId, setSelectedId] = useState<string | null>(null);

  const { data, isLoading, error } = useQuery({
    queryKey: ['tgtc-sessions'],
    queryFn: tgtcApi.sessions,
    refetchInterval: 30000,
  });

  const deleteMut = useMutation({
    mutationFn: (id: string) => tgtcApi.deleteSession(id),
    onSuccess: (_, id) => {
      if (selectedId === id) setSelectedId(null);
      qc.invalidateQueries({ queryKey: ['tgtc-sessions'] });
    },
    onError: (e: Error) => alert(`삭제 실패: ${e.message}`),
  });

  const sessions: TgtcSession[] = data?.sessions ?? [];
  const selectedSession = sessions.find(s => s.session_id === selectedId) ?? null;

  if (isLoading) return <Loading />;
  if (error) return <ErrorState error={error as Error} />;

  return (
    <div style={{ padding: '24px 28px', maxWidth: 1300, margin: '0 auto' }}>
      {/* Header */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 20 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <TrendingUp size={20} style={{ color: 'var(--cyan)' }} />
          <h1 style={{ fontSize: 22, fontWeight: 700, margin: 0 }}>TGTC Trading</h1>
          <span style={{ fontSize: 12, color: 'var(--text3)', fontFamily: 'var(--font-mono)', background: 'var(--bg2)', padding: '3px 8px', borderRadius: 5 }}>
            Top Gainer Tape Continuation · Dry-Run V1
          </span>
        </div>
        <button style={btn('primary')} onClick={() => setShowCreate(true)}>
          <Plus size={14} /> 새 세션
        </button>
      </div>

      {/* Scheduler */}
      <SchedulerPanel selectedSessions={selectedId ? [selectedId] : []} />

      {/* Quick Backtest */}
      <QuickBacktestPanel />

      {/* Sessions grid */}
      {sessions.length === 0 ? (
        <div style={{ ...card, padding: 40, textAlign: 'center' as const, color: 'var(--text3)' }}>
          <TrendingUp size={40} style={{ opacity: 0.2, display: 'block', margin: '0 auto 12px' }} />
          <div style={{ fontSize: 15, fontWeight: 600 }}>세션 없음</div>
          <div style={{ fontSize: 13, marginTop: 6 }}>
            "새 세션" 버튼으로 TGTC 트레이딩 세션을 만드세요
          </div>
        </div>
      ) : (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: 12 }}>
          {sessions.map(s => (
            <SessionCard
              key={s.session_id}
              session={s}
              isSelected={selectedId === s.session_id}
              onClick={() => setSelectedId(id => id === s.session_id ? null : s.session_id)}
              onDelete={() => {
                if (confirm(`"${s.session_name}" 세션을 삭제하시겠습니까?`)) {
                  deleteMut.mutate(s.session_id);
                }
              }}
            />
          ))}
        </div>
      )}

      {/* Session detail */}
      {selectedSession && <SessionDetail session={selectedSession} />}

      {/* Create modal */}
      {showCreate && (
        <CreateSessionModal
          onClose={() => setShowCreate(false)}
          onCreated={() => qc.invalidateQueries({ queryKey: ['tgtc-sessions'] })}
        />
      )}
    </div>
  );
}
