/* global React, TICKERS, STRATEGIES, ORDERS_SEED, AUDIT_SEED, genEquity,
   krw, krwSigned, pct, fmtPx, sigQty, LineChart, Sparkline, StratBar */
const { useState, useEffect, useMemo } = React;

// =============== KPI STRIP ===============
function KpiStrip({ s }) {
  const items = [
    {
      k: "오늘 손익",
      v: krwSigned(Math.round(s.todayPnl)),
      sub: s.liveView ? '실현 (장중 mark 제외)' : pct(s.todayPnlPct),
      tone: s.todayPnl >= 0 ? 'up' : 'down',
    },
    {
      k: s.liveView ? "총 평가손익" : "누적 손익",
      v: krwSigned(Math.round(s.cumPnl)),
      sub: pct(s.cumPnlPct),
      tone: s.cumPnl >= 0 ? 'up' : 'down',
    },
    {
      k: s.liveView ? "총 보유자산" : "총 자본",
      v: krw(Math.round(s.totalEquity)),
      sub: s.liveView
        ? `원화 ${krw(Math.round(s.krwBalance))} + 평가 ${krw(Math.round(s.totalValueKrw))}`
        : `원화 + ${s.slotsUsed}종목`,
      tone: 'accent',
    },
    {
      k: "포지션",
      v: `${s.slotsUsed}/${s.slotsMax}`,
      sub: `슬롯 ${Math.round((s.slotsUsed / s.slotsMax) * 100)}% 사용`,
      tone: '',
    },
    {
      k: "일일 손실 소진",
      v: `${Math.round(s.lossUsedPct)}%`,
      sub: `한도 ${krw(s.dailyLossLimit)}`,
      tone: s.lossUsedPct > 60 ? 'down' : '',
    },
    {
      k: "승률 · 30일",
      v: `${(s.winRate30d || 0).toFixed(1)}%`,
      sub: `샤프 ${(s.sharpe30d || 0).toFixed(2)}`,
      tone: (s.winRate30d || 0) >= 50 ? 'up' : '',
    },
  ];
  const sparkValues = s.equity.map(e => e.v);
  return (
    <div className="kpi-strip">
      {items.map((k, i) => (
        <div className="kpi" key={i}>
          <div className="k">{k.k}</div>
          <div className={`v ${k.tone}`}>{k.v}</div>
          <div className="sub">{k.sub}</div>
          {i === 1 && (
            <div className="spark">
              <Sparkline values={sparkValues} color="var(--accent)" width={70} height={28} />
            </div>
          )}
        </div>
      ))}
    </div>
  );
}

// =============== EQUITY CELL ===============
function EquityCell({ s }) {
  const [range, setRange] = useState('30D');
  const baseline = (s.risk && s.risk.paper_initial_krw) || (s.totalEquity - s.cumPnl) || 0;
  const points = useMemo(() => {
    const days = range === '7D' ? 7 : range === '14D' ? 14 : range === '30D' ? 30 : 90;
    const slice = range === 'ALL' ? s.equity : s.equity.slice(-days);
    return slice.map((e, i) => ({ x: i, y: e.v, label: e.d }));
  }, [s.equity, range]);

  const latest = points[points.length - 1]?.y || 0;
  const first = points[0]?.y || 0;
  const change = latest - first;
  const changePct = first > 0 ? (change / first) * 100 : 0;
  const modeLabel = (s.mode === 'live' ? '실거래' : '페이퍼') + ' · 원화';

  return (
    <div className="cell">
      <div className="cell-head">
        <h3>자본 곡선</h3>
        <span className="meta">{modeLabel}</span>
        <div className="actions">
          <div className="tabs">
            {[['7D','7일'], ['14D','14일'], ['30D','30일'], ['ALL','전체']].map(([r, lbl]) => (
              <button key={r} className={range === r ? 'on' : ''} onClick={() => setRange(r)}>{lbl}</button>
            ))}
          </div>
        </div>
      </div>
      <div className="cell-body">
        <div className="chart-wrap">
          <div className="chart-legend">
            <span><i style={{ background: 'var(--accent)' }} />자본</span>
            <span><i style={{ background: 'var(--text-faint)', borderTop: '1px dashed var(--text-faint)' }} />기준선 {krw(Math.round(baseline))}</span>
          </div>
          <div className="chart-readout">
            <div className="big">{krw(Math.round(latest))}</div>
            <div style={{ color: change >= 0 ? 'var(--up)' : 'var(--down)' }}>
              {krwSigned(Math.round(change))} ({pct(changePct)})
            </div>
          </div>
          {points.length > 0 && (
            <LineChart
              series={[
                { key: 'eq', color: 'oklch(0.78 0.13 220)', fill: true, points },
                { key: 'base', color: '#4a525e', points: points.map(p => ({ x: p.x, y: baseline, label: p.label })) },
              ]}
              formatY={(y) => (y / 1_000_000).toFixed(1) + 'M'}
            />
          )}
        </div>
      </div>
    </div>
  );
}

// =============== POSITIONS CELL ===============
function PositionsCell({ s }) {
  return (
    <div className="cell">
      <div className="cell-head">
        <h3>보유 포지션</h3>
        <span className="meta">{s.slotsUsed}/{s.slotsMax} 슬롯 · 실시간 평가</span>
        <div className="actions">
          <button className="btn ghost sm">내보내기</button>
        </div>
      </div>
      <div className="cell-body">
        <table className="t">
          <thead>
            <tr>
              <th>종목</th>
              <th>전략</th>
              <th>수량</th>
              <th>진입가</th>
              <th>현재가</th>
              <th>손익</th>
              <th>수익률</th>
              <th>평가액</th>
              <th>손절가</th>
            </tr>
          </thead>
          <tbody>
            {s.tickers.map(t => {
              const isOpen = t.qty > 0;
              const upnl = isOpen ? (t.price - t.entry) * t.qty : 0;
              const upnlPct = isOpen ? ((t.price - t.entry) / t.entry) * 100 : 0;
              const stop = t.entry * 0.98;
              return (
                <tr key={t.sym}>
                  <td className="strong">{t.sym}</td>
                  <td className="tag">{STRATEGIES.find(st => st.id === t.strat)?.code || '—'}</td>
                  <td>{isOpen ? sigQty(t.qty) : <span className="muted">—</span>}</td>
                  <td>{isOpen ? fmtPx(t.entry) : <span className="muted">—</span>}</td>
                  <td className={t.price_stale ? 'muted' : 'strong'}
                      title={t.price_stale ? '가격 피드 stale — 진입가로 대체 표시' : ''}>
                    {fmtPx(Math.round(t.price))}{t.price_stale ? ' ·' : ''}
                  </td>
                  <td className={isOpen && !t.price_stale ? (upnl >= 0 ? 'up' : 'down') : 'muted'}>
                    {isOpen && !t.price_stale ? krwSigned(Math.round(upnl)) : '—'}
                  </td>
                  <td className={isOpen && !t.price_stale ? (upnl >= 0 ? 'up' : 'down') : 'muted'}>
                    {isOpen && !t.price_stale ? pct(upnlPct) : '—'}
                  </td>
                  <td>{isOpen ? krw(Math.round(t.qty * t.price)) : <span className="muted">—</span>}</td>
                  <td className={isOpen ? 'down' : 'muted'}>{isOpen ? fmtPx(Math.round(stop)) : '—'}</td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
}

// =============== STRATEGY PERFORMANCE CELL ===============
function StrategyPerfCell({ s }) {
  const maxAbs = Math.max(...STRATEGIES.map(x => Math.abs(x.pnl30d)));
  return (
    <div className="cell">
      <div className="cell-head">
        <h3>전략 성과 · 30일</h3>
        <span className="meta">walk-forward</span>
        <div className="actions">
          <span className="chip on">{STRATEGIES.find(x => x.id === s.activeStrat)?.code} 활성</span>
        </div>
      </div>
      <div className="cell-body">
        <table className="t">
          <thead>
            <tr>
              <th>코드</th>
              <th>전략</th>
              <th>손익 30일</th>
              <th>샤프</th>
              <th>승률</th>
              <th>매매</th>
              <th>분포</th>
            </tr>
          </thead>
          <tbody>
            {STRATEGIES.slice().sort((a, b) => b.pnl30d - a.pnl30d).map(st => (
              <tr key={st.id} style={{ background: st.id === s.activeStrat ? 'oklch(0.78 0.13 220 / 0.06)' : 'transparent' }}>
                <td className="tag">{st.code}</td>
                <td className="strong">{st.name}</td>
                <td className={st.pnl30d >= 0 ? 'up' : 'down'}>{pct(st.pnl30d, 1)}</td>
                <td>{st.sharpe.toFixed(2)}</td>
                <td>{st.winRate}%</td>
                <td className="muted">{st.trades}</td>
                <td style={{ width: 120 }}>
                  <StratBar value={st.pnl30d} max={maxAbs} color={st.pnl30d >= 0 ? 'var(--up)' : 'var(--down)'} />
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

// =============== ORDER STREAM CELL ===============
function OrderStreamCell({ s }) {
  const [filter, setFilter] = useState('ALL');
  const filtered = useMemo(() => {
    if (filter === 'ALL') return s.orders;
    return s.orders.filter(o => o.side === filter);
  }, [s.orders, filter]);
  return (
    <div className="cell">
      <div className="cell-head">
        <h3>주문 스트림</h3>
        <span className="meta">최근 24시간 · 체결 {s.orders.length}건</span>
        <div className="actions">
          <div className="tabs">
            {[['ALL','전체'], ['BUY','매수'], ['SELL','매도']].map(([f, lbl]) => (
              <button key={f} className={filter === f ? 'on' : ''} onClick={() => setFilter(f)}>{lbl}</button>
            ))}
          </div>
        </div>
      </div>
      <div className="cell-body">
        <table className="t">
          <thead>
            <tr>
              <th>시간</th>
              <th>방향</th>
              <th>종목</th>
              <th>전략</th>
              <th>가격</th>
              <th>수량</th>
              <th>금액</th>
              <th>상태</th>
            </tr>
          </thead>
          <tbody>
            {filtered.map((o, i) => (
              <tr key={i}>
                <td className="muted">{o.ts}</td>
                <td className={o.side === 'BUY' ? 'up' : 'down'} style={{ fontWeight: 600 }}>{o.side === 'BUY' ? '매수' : '매도'}</td>
                <td className="strong">{o.sym}</td>
                <td className="tag">{o.strat}</td>
                <td>{fmtPx(o.px)}</td>
                <td>{sigQty(o.qty)}</td>
                <td>{krw(o.krw)}</td>
                <td><span className="tag up">{o.status}</span></td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

// =============== DASHBOARD ===============
function Dashboard({ s }) {
  return (
    <>
      <KpiStrip s={s} />
      <div className="grid">
        <EquityCell s={s} />
        <PositionsCell s={s} />
        <StrategyPerfCell s={s} />
        <OrderStreamCell s={s} />
      </div>
    </>
  );
}

Object.assign(window, { Dashboard });
