/**
 * 모의투자 대시보드 — 첨부 UI (3열 + 핵심 성과 지표)
 */
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import {
  loadPaperSummary,
  loadPaperTrades,
  resetPaperAccount,
  type PaperPositionDto,
  type PaperSummaryDto,
  type PaperTradeDto,
} from '../utils/backendApi';
import { computePaperMetrics } from '../utils/paperMetrics';
import { fmtKrw } from './TradeOrderPanel';
import TradeOrderPanel from './TradeOrderPanel';
import type { Theme, TradeOrderFillRequest } from '../types';
import PaperAnalysisChart from './paper/PaperAnalysisChart';
import PaperLeftStrategyTab from './paper/PaperLeftStrategyTab';
import PaperLeftSettingsTab from './paper/PaperLeftSettingsTab';
import PaperCompactOrderbook from './paper/PaperCompactOrderbook';
import PaperSplitPanel from './paper/PaperSplitPanel';
import BuilderPageShell from './layout/BuilderPageShell';

type HistoryTab = 'open' | 'recent';
type RightTab = 'trade' | 'orderbook' | 'history';
type LeftTab = 'strategy' | 'settings';

interface Props {
  theme?: Theme;
  tickers?: Map<string, { tradePrice: number | null }>;
  onGoChart?: (market: string) => void;
  refreshKey?: number;
  defaultMarket?: string;
  paperTradingEnabled?: boolean;
  paperAutoTradeEnabled?: boolean;
  onPaperOrderFilled?: () => void;
}

function buildMarkPrices(
  summary: PaperSummaryDto | null,
  tickers?: Map<string, { tradePrice: number | null }>,
): Record<string, number> {
  const m: Record<string, number> = {};
  summary?.positions?.forEach(p => {
    const t = tickers?.get(p.symbol)?.tradePrice;
    if (t != null && t > 0) m[p.symbol] = t;
  });
  return m;
}

function positionPriceKey(
  positions: PaperPositionDto[] | undefined,
  tickers?: Map<string, { tradePrice: number | null }>,
): string {
  if (!positions?.length) return '';
  return positions.map(p => `${p.symbol}:${tickers?.get(p.symbol)?.tradePrice ?? ''}`).join('|');
}

function coinCode(symbol: string): string {
  return symbol.replace(/^KRW-/, '');
}

const PaperTradingPage: React.FC<Props> = ({
  theme = 'dark',
  tickers,
  refreshKey = 0,
  defaultMarket = 'KRW-BTC',
  paperTradingEnabled = true,
  paperAutoTradeEnabled = false,
  onPaperOrderFilled,
}) => {
  const [summary, setSummary] = useState<PaperSummaryDto | null>(null);
  const [trades, setTrades] = useState<PaperTradeDto[]>([]);
  const [initialLoading, setInitialLoading] = useState(true);
  const [selectedMarket, setSelectedMarket] = useState(defaultMarket);
  const [historyTab, setHistoryTab] = useState<HistoryTab>('recent');
  const [rightTab, setRightTab] = useState<RightTab>('trade');
  const [leftTab, setLeftTab] = useState<LeftTab>('strategy');
  const [fillBuy, setFillBuy] = useState<TradeOrderFillRequest | null>(null);
  const [fillSell, setFillSell] = useState<TradeOrderFillRequest | null>(null);
  const orderAnchorRef = useRef<HTMLDivElement>(null);
  const fillSeqRef = useRef(0);

  const tickersRef = useRef(tickers);
  tickersRef.current = tickers;
  const summaryRef = useRef(summary);
  summaryRef.current = summary;

  const loadData = useCallback(async () => {
    try {
      const base = await loadPaperSummary();
      const marks = buildMarkPrices(base, tickersRef.current);
      const full = Object.keys(marks).length > 0 ? await loadPaperSummary(marks) : base;
      setSummary(full);
      setTrades(await loadPaperTrades());
    } finally {
      setInitialLoading(false);
    }
  }, []);

  useEffect(() => { void loadData(); }, [loadData]);
  useEffect(() => { if (refreshKey > 0) void loadData(); }, [refreshKey, loadData]);

  const priceKey = positionPriceKey(summary?.positions, tickers);
  const lastPriceKeyRef = useRef('');
  useEffect(() => {
    if (!priceKey || initialLoading || priceKey === lastPriceKeyRef.current) return;
    lastPriceKeyRef.current = priceKey;
    let cancelled = false;
    (async () => {
      const marks = buildMarkPrices(summaryRef.current, tickersRef.current);
      if (!Object.keys(marks).length) return;
      try {
        const full = await loadPaperSummary(marks);
        if (!cancelled) setSummary(full);
      } catch { /* ignore */ }
    })();
    return () => { cancelled = true; };
  }, [priceKey, initialLoading]);

  const metrics = useMemo(() => computePaperMetrics(trades, summary), [trades, summary]);
  const s = summary;
  const tradePrice = tickers?.get(selectedMarket)?.tradePrice ?? null;

  const posQty = useMemo(() => {
    const p = s?.positions?.find(x => x.symbol === selectedMarket);
    return p?.quantity ?? 0;
  }, [s?.positions, selectedMarket]);

  const handleObPick = useCallback((price: number, rowType: 'ask' | 'bid') => {
    const side = rowType === 'ask' ? 'buy' : 'sell';
    fillSeqRef.current += 1;
    const req: TradeOrderFillRequest = {
      market: selectedMarket,
      price,
      side,
      seq: fillSeqRef.current,
    };
    if (side === 'buy') setFillBuy(req); else setFillSell(req);
    setRightTab('trade');
  }, [selectedMarket]);

  const handleReset = useCallback(async () => {
    if (!window.confirm('모의투자 계좌를 초기화합니다. 계속할까요?')) return;
    const res = await resetPaperAccount();
    if (res) { setSummary(res); setTrades([]); }
  }, []);

  const rightTabs = (
    <div className="bps-right-tabs">
      <button type="button" className={`bps-right-tab${rightTab === 'trade' ? ' bps-right-tab--on' : ''}`} onClick={() => setRightTab('trade')}>매매</button>
      <button type="button" className={`bps-right-tab${rightTab === 'orderbook' ? ' bps-right-tab--on' : ''}`} onClick={() => setRightTab('orderbook')}>호가</button>
      <button type="button" className={`bps-right-tab${rightTab === 'history' ? ' bps-right-tab--on' : ''}`} onClick={() => setRightTab('history')}>체결</button>
    </div>
  );

  const leftTabs = (
    <div className="bps-left-tabs">
      <button type="button" className={`bps-left-tab${leftTab === 'strategy' ? ' bps-left-tab--on' : ''}`} onClick={() => setLeftTab('strategy')}>전략</button>
      <button type="button" className={`bps-left-tab${leftTab === 'settings' ? ' bps-left-tab--on' : ''}`} onClick={() => setLeftTab('settings')}>설정</button>
    </div>
  );

  return (
    <BuilderPageShell
      theme={theme}
      title="모의투자"
      subtitle="Paper Trading"
      loading={initialLoading}
      loadingText="모의투자 대시보드 로딩…"
      leftStorageKey="ptd-left-width"
      footerStorageKey="ptd-footer-height"
      headerActions={(
        <>
          <button type="button" className="bps-btn bps-btn--ghost" onClick={() => void loadData()}>새로고침</button>
          <button type="button" className="bps-btn bps-btn--danger" onClick={() => void handleReset()}>계좌 초기화</button>
        </>
      )}
      banner={!s?.enabled ? (
        <div className="bps-banner bps-banner--warn">모의투자가 꺼져 있습니다. 설정에서 활성화하세요.</div>
      ) : undefined}
      leftTabs={leftTabs}
      left={leftTab === 'strategy' ? (
        <PaperLeftStrategyTab
          market={selectedMarket}
          summary={s}
          paperAutoTradeEnabled={paperAutoTradeEnabled}
          onMarketSelect={setSelectedMarket}
        />
      ) : (
        <PaperLeftSettingsTab
          onAccountReset={() => { setSummary(null); setTrades([]); void loadData(); }}
        />
      )}
      centerHead={(
        <span className="bps-center-head-title">{coinCode(selectedMarket)} / KRW</span>
      )}
      center={(
        <div className="ptd-card ptd-chart-card ptd-center-fill">
          <PaperAnalysisChart market={selectedMarket} theme={theme} />
        </div>
      )}
      rightTabs={rightTabs}
      right={(
        <div className="ptd-right-body" ref={orderAnchorRef}>
          {rightTab === 'trade' ? (
            <PaperSplitPanel
              className="ptd-split-panel--right"
              topTitle="매수"
              bottomTitle="매도"
              top={(
                <TradeOrderPanel
                  side="buy"
                  market={selectedMarket}
                  tradePrice={tradePrice}
                  availableKrw={s?.cashBalance ?? 0}
                  fillRequest={fillBuy}
                  searchAnchorRef={orderAnchorRef}
                  onMarketSelect={setSelectedMarket}
                  showSymbolField
                  paperTradingEnabled={paperTradingEnabled}
                  paperAutoTradeEnabled={paperAutoTradeEnabled}
                  onPaperOrderFilled={() => { onPaperOrderFilled?.(); void loadData(); }}
                />
              )}
              bottom={(
                <TradeOrderPanel
                  side="sell"
                  market={selectedMarket}
                  tradePrice={tradePrice}
                  availableCoinQty={posQty}
                  fillRequest={fillSell}
                  onMarketSelect={setSelectedMarket}
                  showSymbolField={false}
                  paperTradingEnabled={paperTradingEnabled}
                  paperAutoTradeEnabled={paperAutoTradeEnabled}
                  onPaperOrderFilled={() => { onPaperOrderFilled?.(); void loadData(); }}
                />
              )}
            />
          ) : rightTab === 'orderbook' ? (
            <PaperSplitPanel
              className="ptd-split-panel--right"
              topTitle="매도 호가"
              bottomTitle="매수 호가"
              top={(
                <PaperCompactOrderbook
                  market={selectedMarket}
                  onPick={handleObPick}
                  section="asks"
                  fillHeight
                  hideHeader
                  depth={10}
                />
              )}
              bottom={(
                <PaperCompactOrderbook
                  market={selectedMarket}
                  onPick={handleObPick}
                  section="bids"
                  fillHeight
                  hideHeader
                  depth={10}
                />
              )}
            />
          ) : (
            <PaperSplitPanel
              className="ptd-split-panel--right"
              topTitle="체결 구분"
              bottomTitle={historyTab === 'open' ? '미체결' : '최근체결'}
              top={(
                <div className="ptd-tabs ptd-tabs--in-card">
                  <button type="button" className={`ptd-tab${historyTab === 'open' ? ' active' : ''}`} onClick={() => setHistoryTab('open')}>미체결</button>
                  <button type="button" className={`ptd-tab${historyTab === 'recent' ? ' active' : ''}`} onClick={() => setHistoryTab('recent')}>최근체결</button>
                </div>
              )}
              bottom={historyTab === 'open' ? (
                <p className="ptd-muted">미체결 주문 없음 (모의투자 즉시 체결)</p>
              ) : (
                <table className="ptd-table ptd-table--compact">
                  <thead>
                    <tr><th>시간</th><th>자산</th><th>유형</th><th>가격</th><th>상태</th></tr>
                  </thead>
                  <tbody>
                    {trades.slice(0, 20).map(t => (
                      <tr key={t.id}>
                        <td className="ptd-time">{t.createdAt?.slice(11, 19) ?? '—'}</td>
                        <td>{coinCode(t.symbol)}</td>
                        <td className={t.side === 'BUY' ? 'up' : 'down'}>{t.side === 'BUY' ? '매수' : '매도'}</td>
                        <td>{fmtKrw(t.price)}</td>
                        <td><span className="ptd-status ptd-status--done">체결</span></td>
                      </tr>
                    ))}
                    {!trades.length && <tr><td colSpan={5} className="ptd-muted">체결 내역 없음</td></tr>}
                  </tbody>
                </table>
              )}
            />
          )}
        </div>
      )}
      footerLabel="성과 지표"
      footer={(
        <div className="ptd-metrics-grid">
          <MetricCard icon="📉" title="MDD" value={`${metrics.mddPct.toFixed(2)}%`} sub="최대 낙폭" tone="down" />
          <MetricCard icon="📊" title="Sharpe Ratio" value={metrics.sharpeRatio.toFixed(2)} sub="위험 대비 수익" tone="up" />
          <MetricCard icon="🏆" title="Win Rate" value={`${metrics.winRatePct.toFixed(0)}%`} sub="승률" tone="up" />
          <MetricCard icon="🛡" title="Profit Factor" value={metrics.profitFactor.toFixed(2)} sub="총이익/총손실" tone="up" />
        </div>
      )}
    />
  );
};

function MetricCard({ icon, title, value, sub, tone }: {
  icon: string; title: string; value: string; sub: string; tone: 'up' | 'down';
}) {
  return (
    <div className={`ptd-metric ptd-metric--${tone}`}>
      <span className="ptd-metric-icon">{icon}</span>
      <div>
        <div className="ptd-metric-title">{title}</div>
        <div className="ptd-metric-value">{value}</div>
        <div className="ptd-metric-sub">{sub}</div>
      </div>
    </div>
  );
}

export default PaperTradingPage;
