/**
 * 운영 현황 대시보드 — 멀티스레드 파이프라인·JVM·트래픽·모의/실거래
 */
import React, { useEffect, useState, useCallback } from 'react';
import type { Theme } from '../types';
import {
  loadDashboardSummary,
  type DashboardSummaryDto,
  type ProcessMonitorDto,
  type SystemMonitorDto,
} from '../utils/backendApi';

interface Props {
  theme: Theme;
  onGoChart?: (market: string) => void;
}

const fmtKrw = (n: number) =>
  n >= 1e8 ? `${(n / 1e8).toFixed(2)}억` : n >= 1e4 ? `${(n / 1e4).toFixed(0)}만` : n.toLocaleString('ko-KR');

const STATUS_LABEL: Record<string, string> = {
  healthy: '정상',
  degraded: '주의',
  down: '중단',
  disabled: '비활성',
};

function statusClass(s: string): string {
  if (s === 'healthy') return 'dash-proc--ok';
  if (s === 'degraded') return 'dash-proc--warn';
  if (s === 'down') return 'dash-proc--down';
  return 'dash-proc--off';
}

function formatMetricValue(v: unknown): string {
  if (typeof v === 'boolean') return v ? 'Y' : 'N';
  if (typeof v === 'number') {
    if (Number.isInteger(v)) return v.toLocaleString('ko-KR');
    return v.toLocaleString('ko-KR', { maximumFractionDigits: 2 });
  }
  return String(v ?? '—');
}

function formatAgo(ms: number): string {
  if (!ms) return '—';
  const sec = Math.floor((Date.now() - ms) / 1000);
  if (sec < 60) return `${sec}초 전`;
  if (sec < 3600) return `${Math.floor(sec / 60)}분 전`;
  return `${Math.floor(sec / 3600)}시간 전`;
}

const ProcessCard: React.FC<{ proc: ProcessMonitorDto }> = ({ proc }) => (
  <article className={`dash-proc ${statusClass(proc.status)}`}>
    <header className="dash-proc-head">
      <span className="dash-proc-layer">{proc.layer}</span>
      <span className={`dash-proc-badge ${statusClass(proc.status)}`}>
        {STATUS_LABEL[proc.status] ?? proc.status}
      </span>
    </header>
    <h3 className="dash-proc-name">{proc.name}</h3>
    <ul className="dash-proc-metrics">
      {Object.entries(proc.metrics).slice(0, 6).map(([k, v]) => (
        <li key={k}>
          <span>{k}</span>
          <strong>{formatMetricValue(v)}</strong>
        </li>
      ))}
    </ul>
  </article>
);

const DashboardPage: React.FC<Props> = ({ theme, onGoChart }) => {
  const [data, setData] = useState<DashboardSummaryDto | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const refresh = useCallback(() => {
    setLoading(true);
    loadDashboardSummary()
      .then(d => { setData(d); setError(null); })
      .catch(e => setError((e as Error).message))
      .finally(() => setLoading(false));
  }, []);

  useEffect(() => {
    refresh();
    const id = window.setInterval(refresh, 5_000);
    return () => window.clearInterval(id);
  }, [refresh]);

  const app = data?.app as Record<string, unknown> | undefined;
  const mon: SystemMonitorDto | undefined = data?.systemMonitor;

  return (
    <div className={`dashboard-page theme-${theme}`}>
      <header className="dashboard-header">
        <h1>운영 대시보드</h1>
        <div className="dashboard-header-actions">
          {mon && (
            <span className="dashboard-live">
              파이프라인 {mon.pipelineEnabled ? 'ON' : 'OFF'}
              {mon.sampledAtMs ? ` · ${formatAgo(mon.sampledAtMs)} 갱신` : ''}
            </span>
          )}
          <button type="button" className="stg-btn" onClick={refresh} disabled={loading}>
            {loading ? '갱신 중…' : '새로고침'}
          </button>
        </div>
      </header>

      {error && <p className="dashboard-error">{error}</p>}

      {data && mon && (
        <div className="dashboard-grid">
          {/* JVM · 트래픽 */}
          <section className="dashboard-card dashboard-card--wide dash-monitor-top">
            <h2>JVM · 트래픽</h2>
            <div className="dash-jvm-row">
              <div className="dash-jvm-heap">
                <div className="dash-jvm-label">
                  Heap {mon.jvm.heapUsedMb} / {mon.jvm.heapMaxMb} MB ({mon.jvm.heapPct}%)
                </div>
                <div className="dash-jvm-bar">
                  <div
                    className={`dash-jvm-fill${mon.jvm.heapPct > 85 ? ' dash-jvm-fill--warn' : ''}`}
                    style={{ width: `${Math.min(100, mon.jvm.heapPct)}%` }}
                  />
                </div>
              </div>
              <ul className="dashboard-kv dash-traffic-kv">
                <li><span>WS 메시지/s</span><strong>{mon.traffic.wsMessagesPerSec ?? 0}</strong></li>
                <li><span>틱 적재/s</span><strong>{mon.traffic.ticksEnqueuedPerSec ?? 0}</strong></li>
                <li><span>틱 처리/s</span><strong>{mon.traffic.ticksProcessedPerSec ?? 0}</strong></li>
                <li><span>주문 실행/s</span><strong>{mon.traffic.ordersExecutedPerSec ?? 0}</strong></li>
                <li><span>스레드</span><strong>{mon.jvm.threadCount}</strong></li>
                <li><span>Non-Heap</span><strong>{mon.jvm.nonHeapUsedMb} MB</strong></li>
              </ul>
            </div>
          </section>

          {/* Ta4j 메모리 */}
          <section className="dashboard-card">
            <h2>인메모리 캔들 (Ta4j)</h2>
            <ul className="dashboard-kv">
              <li><span>종목</span><strong>{mon.memory.markets}</strong></li>
              <li><span>시리즈</span><strong>{mon.memory.series}</strong></li>
              <li><span>총 봉 수</span><strong>{mon.memory.totalBars.toLocaleString('ko-KR')}</strong></li>
              <li><span>시리즈 상한</span><strong>{mon.memory.maxBarsPerSeries}</strong></li>
            </ul>
          </section>

          {/* 이벤트 큐 */}
          <section className="dashboard-card">
            <h2>이벤트 큐</h2>
            <ul className="dashboard-kv">
              <li><span>대기</span><strong>{mon.queue.pending}</strong></li>
              <li><span>용량</span><strong>{mon.queue.capacity?.toLocaleString('ko-KR') ?? '—'}</strong></li>
              <li><span>적재율</span><strong>{Math.round((mon.queue.fillRatio ?? 0) * 1000) / 10}%</strong></li>
              <li><span>드롭</span><strong className={mon.queue.dropped > 0 ? 'warn' : ''}>{mon.queue.dropped}</strong></li>
            </ul>
          </section>

          {/* 멀티스레드 프로세스 */}
          <section className="dashboard-card dashboard-card--wide">
            <h2>멀티스레드 프로세스</h2>
            <div className="dash-proc-grid">
              {mon.processes.map(p => (
                <ProcessCard key={p.id} proc={p} />
              ))}
            </div>
          </section>

          {/* 스레드 목록 */}
          <section className="dashboard-card dashboard-card--wide">
            <h2>관련 스레드</h2>
            {mon.threads.length === 0 ? (
              <p className="dashboard-muted">표시할 스레드 없음</p>
            ) : (
              <table className="dashboard-table dashboard-table--compact">
                <thead>
                  <tr><th>이름</th><th>ID</th><th>상태</th><th>데몬</th></tr>
                </thead>
                <tbody>
                  {mon.threads.map(t => (
                    <tr key={`${t.id}-${t.name}`}>
                      <td><code>{t.name}</code></td>
                      <td>{t.id}</td>
                      <td>{t.state}</td>
                      <td>{t.daemon ? 'Y' : 'N'}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            )}
          </section>

          {/* 틱 정체 종목 */}
          {mon.staleMarkets.length > 0 && (
            <section className="dashboard-card dashboard-card--wide dash-stale">
              <h2>틱 정체 종목 ({mon.staleMarkets.length})</h2>
              <table className="dashboard-table dashboard-table--compact">
                <thead>
                  <tr><th>종목</th><th>마지막 틱 경과</th></tr>
                </thead>
                <tbody>
                  {mon.staleMarkets.slice(0, 12).map(s => (
                    <tr key={s.market}>
                      <td>
                        <button type="button" className="dashboard-link" onClick={() => onGoChart?.(s.market)}>
                          {s.market.replace('KRW-', '')}
                        </button>
                      </td>
                      <td>{s.lastTickAgeSec}초</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </section>
          )}

          <section className="dashboard-card">
            <h2>매매 모드</h2>
            <ul className="dashboard-kv">
              <li><span>운영 모드</span><strong>{String(app?.tradingMode ?? '—')}</strong></li>
              <li><span>실거래 자동</span><strong>{app?.liveAutoTradeEnabled ? 'ON' : 'OFF'}</strong></li>
              <li><span>모의 자동</span><strong>{app?.paperAutoTradeEnabled ? 'ON' : 'OFF'}</strong></li>
              <li><span>전략 체크</span><strong>{app?.liveStrategyCheck ? 'ON' : 'OFF'}</strong></li>
            </ul>
          </section>

          <section className="dashboard-card">
            <h2>모니터링</h2>
            <ul className="dashboard-kv">
              <li><span>관심종목</span><strong>{data.watchlistCount}</strong></li>
              <li><span>전략 감시</span><strong>{data.monitoredMarkets}</strong></li>
              <li><span>FCM</span><strong>
                {data.fcm.pushEnabled ? (data.fcm.available ? '활성' : '설정됨·서버 미연결') : 'OFF'}
              </strong></li>
            </ul>
          </section>

          <section className="dashboard-card">
            <h2>모의투자</h2>
            <ul className="dashboard-kv">
              <li><span>현금</span><strong>{fmtKrw(data.paper.cashBalance)} KRW</strong></li>
              <li><span>총자산</span><strong>{fmtKrw(data.paper.totalAsset)} KRW</strong></li>
              <li><span>보유 종목</span><strong>{data.paper.positions?.length ?? 0}</strong></li>
            </ul>
          </section>

          <section className="dashboard-card">
            <h2>실거래</h2>
            <ul className="dashboard-kv">
              <li><span>KRW</span><strong>{fmtKrw(data.live.krwBalance)}</strong></li>
              <li><span>보유</span><strong>{data.live.positions?.length ?? 0} 종목</strong></li>
              <li><span>연동</span><strong>{data.live.configured ? 'OK' : '미설정'}</strong></li>
            </ul>
          </section>

          <section className="dashboard-card dashboard-card--wide">
            <h2>최근 시그널</h2>
            {data.recentSignals.length === 0 ? (
              <p className="dashboard-muted">최근 시그널 없음</p>
            ) : (
              <table className="dashboard-table">
                <thead>
                  <tr><th>종목</th><th>방향</th><th>가격</th><th>분봉</th><th>시각</th></tr>
                </thead>
                <tbody>
                  {data.recentSignals.map(s => (
                    <tr key={s.id}>
                      <td>
                        <button type="button" className="dashboard-link" onClick={() => onGoChart?.(s.market)}>
                          {s.market.replace('KRW-', '')}
                        </button>
                      </td>
                      <td className={s.signalType === 'BUY' ? 'buy' : 'sell'}>{s.signalType}</td>
                      <td>{s.price?.toLocaleString('ko-KR')}</td>
                      <td>{s.candleType}</td>
                      <td>{s.createdAt?.slice(0, 19) ?? '—'}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            )}
          </section>
        </div>
      )}
    </div>
  );
};

export default DashboardPage;
