/* global React, ReactDOM */
const { useState, useMemo, useEffect, useRef } = React;
const D = window.APP_DATA;

// ========================== Helpers ==========================
const fmt = {
  num: (n) => n.toLocaleString('ko-KR'),
  signed: (n) => (n >= 0 ? '+' : '') + n.toLocaleString('ko-KR'),
  pct: (n) => (n >= 0 ? '+' : '') + n.toFixed(2) + '%',
};

// ========================== Sidebar ==========================
function Sidebar({ tab, setTab }) {
  const items = [
    { key: 'toppick',  label: "오늘의 Top Pick", badge: "1", icon: "★" },
    { key: 'screener', label: "다트 스크리너",   badge: "17", icon: "▦" },
    { key: 'reports',  label: "애널 리포트",      badge: "8",  icon: "≡" },
  ];
  return (
    <aside className="sidebar">
      <div className="brand">
        <div className="brand-mark"><span className="dot"></span>DAILY PICK</div>
        <div className="brand-sub">Equity Intelligence</div>
      </div>

      <div className="nav-group">
        <div className="nav-group-title">Today</div>
        {items.map(it => (
          <div key={it.key}
               className={"nav-item " + (tab === it.key ? "active" : "")}
               onClick={() => setTab(it.key)}>
            <span className="ico">{it.icon}</span>
            <span>{it.label}</span>
            <span className="badge">{it.badge}</span>
          </div>
        ))}
      </div>

      <div className="nav-group">
        <div className="nav-group-title">Markets</div>
        <div className="nav-item"><span className="ico">◐</span><span>지수 / 환율</span></div>
        <div className="nav-item"><span className="ico">◑</span><span>섹터 히트맵</span></div>
        <div className="nav-item"><span className="ico">◓</span><span>외국인 / 기관</span></div>
      </div>

      <div className="nav-group">
        <div className="nav-group-title">Watchlist</div>
        <div className="nav-item"><span className="ico">＋</span><span>관심 종목 추가</span></div>
      </div>

      <div className="sidebar-footer">
        <div className="row"><span><span className="live-dot"></span>DATA LIVE</span><span>04:32:14</span></div>
        <div className="row"><span>NEXT OPEN</span><span>2D 14H</span></div>
        <div className="row"><span>BUILD</span><span>v2.4.1</span></div>
      </div>
    </aside>
  );
}

// ========================== Header / Ticker ==========================
function Header() {
  const t = [...D.ticker, ...D.ticker]; // for seamless scroll
  return (
    <header className="header">
      <div className="header-meta">
        <div>
          <div className="date">2026년 4월 26일 일요일</div>
          <div className="session">{D.meta.sessionLabel}</div>
        </div>
      </div>

      <div className="ticker-wrap">
        <div className="ticker">
          {t.map((x, i) => (
            <span key={i} className={"tick " + x.dir}>
              <span className="name">{x.name}</span>
              <span className="px">{x.px}</span>
              <span className="chg">{x.pct}</span>
            </span>
          ))}
        </div>
      </div>

      <div className="header-tools">
        <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--ink-inv-3)', letterSpacing: '0.1em' }}>KOSPI</span>
        <span style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: '#fff' }}>{fmt.num(D.meta.kospi.value)}</span>
        <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: '#ff6b6b' }}>{fmt.pct(D.meta.kospi.pct)}</span>
        <button className="icon-btn" title="검색">⌕</button>
        <button className="icon-btn" title="설정">⚙</button>
      </div>
    </header>
  );
}

// ========================== Tabs ==========================
function Tabs({ tab, setTab }) {
  const tabs = [
    { key: 'toppick',  label: "오늘의 Top Pick", count: 1 },
    { key: 'screener', label: "다트 스크리너 결과", count: D.screenerSummary.passed },
    { key: 'reports',  label: "애널리스트 리포트",   count: D.reports.length },
  ];
  return (
    <div className="tabs">
      {tabs.map(t => (
        <button key={t.key}
                className={"tab " + (tab === t.key ? "active" : "")}
                onClick={() => setTab(t.key)}>
          {t.label}<span className="count">{t.count}</span>
        </button>
      ))}
      <div className="tabs-right">
        <span className="pill">자동 발행 · 매일 18:00</span>
        <span className="pill">PDF</span>
        <span className="pill">공유</span>
      </div>
    </div>
  );
}

// ========================== Top Pick view ==========================
function TopPickView() {
  const t = D.topPick;
  const upsideToTarget = ((t.target.consensus - t.price) / t.price * 100);

  return (
    <div className="toppick">
      <div className="section-head">
        <div>
          <div className="eyebrow">Equity Intelligence · Daily Brief</div>
          <h1 className="section-title">오늘의 Top Pick</h1>
        </div>
        <div className="section-meta">2026.04.26 · 17:30 KST · v2.4.1</div>
      </div>

      {/* HERO */}
      <div className="hero">
        <div className="hero-left">
          <div className="hero-eyebrow">
            <span className="badge-gold">★ TOP PICK · CONVICTION BUY</span>
            <span className="date-stamp">2026.04.24 종가 기준</span>
          </div>
          <div className="stock-name">{t.name}</div>
          <div className="stock-meta-row">
            <span className="ticker-code">{t.code}</span>
            <span className="sep">·</span>
            <span>{t.market}</span>
            <span className="sep">·</span>
            <span>{t.sector}</span>
          </div>

          <div className="price-row">
            <div className="px up">{fmt.num(t.price)}</div>
            <div className="chg-block">
              <div className="chg up">▲ {fmt.num(t.chg)}</div>
              <div className="chg-pct up">+{t.pct.toFixed(2)}%</div>
            </div>
          </div>

          <div className="ratings-row">
            <span className="tag dark">매수 의견 {t.rating.buy}</span>
            <span className="tag">중립 {t.rating.hold}</span>
            <span className="tag">매도 {t.rating.sell}</span>
            <span className="tag gold">컨센 BUY · 목표가 상향 4건</span>
          </div>

          <div className="thesis">
            <div className="thesis-label">투자 논리 (Investment Thesis)</div>
            <p className="thesis-text" dangerouslySetInnerHTML={{ __html: t.thesis }} />
          </div>
        </div>

        <div className="hero-right">
          <div className="target-block">
            <div className="target-head">
              <h4>증권사 컨센서스 목표주가</h4>
              <span className="consensus-tag">19개사 / 30일 갱신</span>
            </div>
            <div className="target-numbers">
              <div className="tnum">
                <div className="tnum-label">High</div>
                <div className="tnum-value up">{fmt.num(t.target.high)}</div>
                <div className="tnum-sub">미래에셋</div>
              </div>
              <div className="tnum">
                <div className="tnum-label">Consensus</div>
                <div className="tnum-value">{fmt.num(t.target.consensus)}</div>
                <div className="tnum-sub up">▲ {(((t.target.consensus / t.target.prevConsensus) - 1) * 100).toFixed(1)}% (30D)</div>
              </div>
              <div className="tnum">
                <div className="tnum-label">Low</div>
                <div className="tnum-value">{fmt.num(t.target.low)}</div>
                <div className="tnum-sub">NH투자</div>
              </div>
            </div>

            <div className="distance-bar">
              <h5>
                <span>현재가 → 목표가 거리</span>
                <span className="upside">+{upsideToTarget.toFixed(1)}% Upside</span>
              </h5>
              <div className="bar-track">
                <div className="bar-fill" style={{ width: '56%' }}></div>
                <div className="bar-marker now" style={{ left: '56%' }}></div>
              </div>
              <div className="bar-labels">
                <span>0</span>
                <span><strong>{fmt.num(t.price)}</strong> 현재</span>
                <span><strong>{fmt.num(t.target.consensus)}</strong> 목표</span>
                <span>{fmt.num(t.target.high)}</span>
              </div>
            </div>
          </div>
        </div>
      </div>

      {/* QUICK STATS */}
      <div className="quick-stats">
        <div className="qs"><div className="qs-label">시가총액</div><div className="qs-value">{t.cap}</div><div className="qs-sub">코스피 32위</div></div>
        <div className="qs"><div className="qs-label">PER (12M Fwd)</div><div className="qs-value">{t.per}x</div><div className="qs-sub">업종 평균 31.2x</div></div>
        <div className="qs"><div className="qs-label">PBR</div><div className="qs-value">{t.pbr}x</div><div className="qs-sub">5Y 평균 4.4x</div></div>
        <div className="qs"><div className="qs-label">외국인 지분</div><div className="qs-value">{t.foreign}%</div><div className="qs-sub up">▲ 1.84%p (1M)</div></div>
        <div className="qs"><div className="qs-label">거래량 (직전 거래일)</div><div className="qs-value">{t.volume}</div><div className="qs-sub up">평균 대비 +{((t.volRatio - 1) * 100).toFixed(0)}%</div></div>
        <div className="qs"><div className="qs-label">52주 위치</div><div className="qs-value">94%</div><div className="qs-sub">신고가 근접</div></div>
      </div>

      {/* MAIN GRID */}
      <div className="toppick-grid">
        <div className="panel chart-panel">
          <div className="panel-head">
            <h3>주가 추이 · 네이버 증권</h3>
            <div className="chart-controls">
              <a className="ctrl-btn" href={`https://m.stock.naver.com/domestic/stock/${t.code}/total`} target="_blank" rel="noreferrer">모바일</a>
              <a className="ctrl-btn" href={`https://finance.naver.com/item/main.naver?code=${t.code}`} target="_blank" rel="noreferrer">PC</a>
              <a className="ctrl-btn" href={`https://finance.naver.com/item/fchart.naver?code=${t.code}`} target="_blank" rel="noreferrer">차트 새창</a>
            </div>
          </div>
          <div className="chart-area">
            <iframe
              src={`https://finance.naver.com/item/fchart.naver?code=${t.code}`}
              style={{ width: '100%', height: 360, border: 'none', background: '#fff' }}
              title={`${t.name} 차트`}
              loading="lazy"
            />
          </div>
          <div className="chart-legend">
            <span className="lg"><span className="lg-swatch" style={{ background: 'var(--up)' }}></span>네이버 증권 차트 (일/주/월/분봉 전환 가능)</span>
            <a className="lg" href={`https://finance.naver.com/item/main.naver?code=${t.code}`} target="_blank" rel="noreferrer" style={{ marginLeft: 'auto', color: 'var(--ink-3)', textDecoration: 'underline' }}>네이버 종목 페이지 →</a>
          </div>
          <div className="chart-summary">
            {(() => {
              const cs = t.chartSummary || {};
              const cls = v => v == null ? '' : (v >= 0 ? 'up' : 'down');
              const fmtPct = v => v == null ? '—' : `${v >= 0 ? '+' : ''}${v}%`;
              return (
                <>
                  <div className="qs"><div className="qs-label">6M 수익률</div><div className={`qs-value ${cls(cs.return6m)}`}>{fmtPct(cs.return6m)}</div></div>
                  <div className="qs"><div className="qs-label">3M 수익률</div><div className={`qs-value ${cls(cs.return3m)}`}>{fmtPct(cs.return3m)}</div></div>
                  <div className="qs"><div className="qs-label">변동성 (60D)</div><div className="qs-value">{cs.vol60d != null ? `${cs.vol60d}%` : '—'}</div></div>
                  <div className="qs"><div className="qs-label">베타 (vs KOSPI)</div><div className="qs-value">{cs.beta != null ? cs.beta : '—'}</div></div>
                </>
              );
            })()}
          </div>
        </div>

        <div className="right-stack">
          <div className="panel">
            <div className="panel-head">
              <h3>증권사 목표가 변동 (30일)</h3>
              <span className="meta">6개사 / 평균 +18.2%</span>
            </div>
            <div className="broker-list">
              {t.brokerReports.map((b, i) => (
                <div key={i} className="broker-row">
                  <div className="broker-logo">{b.logo}</div>
                  <div className="broker-info">
                    <div className="name">{b.broker} <span style={{ color: 'var(--ink-3)', fontWeight: 400, fontSize: 11 }}>· {b.analyst.split('·')[0].trim()}</span></div>
                    <div className="meta">{b.date} · {b.rating} · "{b.title}"</div>
                  </div>
                  <div className="broker-target">
                    <div className="new">{fmt.num(b.target)}</div>
                    <div className="delta up">▲ +{b.change.toFixed(1)}% ({fmt.num(b.prev)}→)</div>
                  </div>
                </div>
              ))}
            </div>
          </div>

          <div className="panel">
            <div className="panel-head">
              <h3>핵심 촉매 (Catalysts)</h3>
              <span className="meta">우선순위 정렬</span>
            </div>
            <div className="kv-list">
              {t.catalysts.map((c, i) => (
                <div key={i} className="kv-item">
                  <div className="marker">+ {String(i + 1).padStart(2, '0')}</div>
                  <div className="body"><strong>{c.title}</strong><span>{c.body}</span></div>
                </div>
              ))}
            </div>
          </div>

          <div className="panel">
            <div className="panel-head">
              <h3>리스크 요인 (Risks)</h3>
              <span className="meta">하방 시나리오</span>
            </div>
            <div className="kv-list">
              {t.risks.map((c, i) => (
                <div key={i} className="kv-item risk">
                  <div className="marker">− {String(i + 1).padStart(2, '0')}</div>
                  <div className="body"><strong>{c.title}</strong><span>{c.body}</span></div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>

      {/* BOTTOM */}
      <div className="bottom-grid">
        <div className="panel">
          <div className="panel-head">
            <h3>외국인 · 기관 누적 순매수</h3>
            <span className="meta">최근 27 거래일</span>
          </div>
          <div className="flow-bars"><FlowBars data={t.chart.foreignFlow} /></div>
        </div>

        <div className="panel">
          <div className="panel-head">
            <h3>실적 추이 및 전망</h3>
            <span className="meta">단위: 억원, 원</span>
          </div>
          <table className="fin-table">
            <thead>
              <tr>
                <th>기간</th>
                <th>매출액</th>
                <th>영업이익</th>
                <th>OPM</th>
                <th>EPS</th>
                <th>PER</th>
              </tr>
            </thead>
            <tbody>
              {t.financials.map((f, i) => (
                <tr key={i} className={f.hi ? 'hi' : ''}>
                  <td>{f.period}</td>
                  <td>{f.rev}</td>
                  <td>{f.op}</td>
                  <td>{f.opMargin}%</td>
                  <td>{f.eps}</td>
                  <td>{f.per}x</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>

      <div className="bottom-grid" style={{ gridTemplateColumns: '1fr', marginTop: 16 }}>
        <div className="panel">
          <div className="panel-head">
            <h3>관련 뉴스 · 공시 (직전 3 거래일)</h3>
            <span className="meta">전체 24건 중 6건</span>
          </div>
          <div className="news-list">
            {t.news.map((n, i) => (
              <div key={i} className="news-item">
                <span className="time">{n.time}</span>
                <div className="body"><strong>{n.title}</strong><div className="src">{n.src}</div></div>
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

// ========================== Charts (SVG) ==========================
function PriceChart({ data }) {
  const W = 1200, H = 320, PAD_L = 50, PAD_R = 16, PAD_T = 16, PAD_B = 32;
  const innerW = W - PAD_L - PAD_R;
  const innerH = H - PAD_T - PAD_B;

  // OHLC 데이터 우선 사용, 없으면 price만으로 라인 fallback
  const hasOHLC = Array.isArray(data.ohlc) && data.ohlc.length > 0;
  const allVals = hasOHLC
    ? [...data.ohlc.flatMap(c => [c.o, c.h, c.l, c.c]), ...(data.ma20 || []).filter(v => v != null), data.target].filter(v => v != null && !isNaN(v))
    : [...data.price, ...data.ma20, data.target].filter(v => v != null && !isNaN(v));
  const maxV = Math.max(...allVals) * 1.05;
  const minV = Math.min(...allVals) * 0.92;
  const n = hasOHLC ? data.ohlc.length : data.price.length;
  const x = (i) => PAD_L + (i / Math.max(1, n - 1)) * innerW;
  const y = (v) => PAD_T + (1 - (v - minV) / (maxV - minV)) * innerH;
  const candleW = Math.max(0.8, innerW / n * 0.7);

  const linePath = (arr) => arr
    .map((v, i) => (v == null || isNaN(v) ? null : (i === 0 ? 'M' : 'L') + x(i) + ',' + y(v)))
    .filter(Boolean).join(' ');

  // y ticks
  const ticks = [];
  const step = (maxV - minV) / 4;
  for (let i = 0; i <= 4; i++) ticks.push(minV + step * i);

  return (
    <svg viewBox={`0 0 ${W} ${H}`}>
      {/* Grid */}
      {ticks.map((v, i) => (
        <g key={i}>
          <line x1={PAD_L} x2={W - PAD_R} y1={y(v)} y2={y(v)} stroke="#ece7da" strokeDasharray="2 3" />
          <text x={PAD_L - 6} y={y(v) + 3} textAnchor="end" fontSize="10" fill="#8a8d96" fontFamily="JetBrains Mono, monospace">
            {(v).toFixed(0)}
          </text>
        </g>
      ))}

      {/* Target line */}
      {data.target > 0 && (
        <>
          <line x1={PAD_L} x2={W - PAD_R} y1={y(data.target)} y2={y(data.target)} stroke="#8a6f2a" strokeDasharray="4 4" strokeWidth="1.2" />
          <text x={W - PAD_R - 4} y={y(data.target) - 5} textAnchor="end" fontSize="10" fill="#8a6f2a" fontFamily="JetBrains Mono, monospace" fontWeight="700">
            TARGET {(data.target).toFixed(0)}
          </text>
        </>
      )}

      {/* Candlesticks (한국식: 양봉 빨강, 음봉 파랑) */}
      {hasOHLC && data.ohlc.map((c, i) => {
        const cx = x(i);
        const isUp = c.c >= c.o;
        const color = isUp ? '#d62828' : '#1565c0';
        const bodyTop = y(Math.max(c.o, c.c));
        const bodyBot = y(Math.min(c.o, c.c));
        const bodyH = Math.max(1, bodyBot - bodyTop);
        return (
          <g key={i}>
            {/* Wick (high-low) */}
            <line x1={cx} x2={cx} y1={y(c.h)} y2={y(c.l)} stroke={color} strokeWidth="1" />
            {/* Body (open-close) */}
            <rect x={cx - candleW / 2} y={bodyTop} width={candleW} height={bodyH}
                  fill={isUp ? color : '#fff'} stroke={color} strokeWidth="1" />
          </g>
        );
      })}

      {/* OHLC 없을 때 라인 차트 fallback */}
      {!hasOHLC && (
        <>
          <path d={linePath(data.price)} fill="none" stroke="#d62828" strokeWidth="1.8" />
          <circle cx={x(data.price.length - 1)} cy={y(data.price[data.price.length - 1])} r="4" fill="#d62828" stroke="#fff" strokeWidth="2" />
        </>
      )}

      {/* MA20 */}
      {data.ma20 && data.ma20.some(v => v != null) && (
        <path d={linePath(data.ma20)} fill="none" stroke="#8a8d96" strokeWidth="1.4" strokeDasharray="3 2" />
      )}

      {/* X axis labels (자동 간격 — 약 12~15개 표시) */}
      {(() => {
        const step = Math.max(1, Math.ceil(data.labels.length / 12));
        return data.labels.map((lbl, i) => (
          (i % step === 0 || i === data.labels.length - 1) ? (
            <text key={i} x={x(i)} y={H - 10} textAnchor="middle" fontSize="9" fill="#8a8d96" fontFamily="JetBrains Mono, monospace">
              {lbl}
            </text>
          ) : null
        ));
      })()}
    </svg>
  );
}

function FlowBars({ data }) {
  const W = 560, H = 140, PAD = 20;
  const innerW = W - PAD * 2;
  const innerH = H - PAD * 2;
  const max = Math.max(...data.map(Math.abs));
  const bw = innerW / data.length - 2;
  const zero = PAD + innerH / 2;
  return (
    <svg viewBox={`0 0 ${W} ${H}`}>
      <line x1={PAD} x2={W - PAD} y1={zero} y2={zero} stroke="#c9c2b1" strokeWidth="0.5" />
      {data.map((v, i) => {
        const h = (Math.abs(v) / max) * (innerH / 2 - 4);
        return (
          <rect key={i}
                x={PAD + i * (bw + 2)}
                y={v >= 0 ? zero - h : zero}
                width={bw}
                height={h}
                fill={v >= 0 ? '#d62828' : '#0d4f9e'}
                opacity="0.85" />
        );
      })}
      <text x={PAD} y={PAD - 4} fontSize="10" fill="#8a8d96" fontFamily="JetBrains Mono, monospace">+ 순매수</text>
      <text x={W - PAD} y={H - 4} textAnchor="end" fontSize="10" fill="#8a8d96" fontFamily="JetBrains Mono, monospace">− 순매도</text>
    </svg>
  );
}

// ========================== Screener view ==========================
const SIGNAL_KOR = {
  '★': '저격', 'T': '턴어라운드', 'W': '주봉정배열', 'X': '주봉조정',
  'Q': '신고가임박', 'R': '조정매집', '2': 'Phase2', 'P': '핵심전환',
  'E': '에코프로', 'L': '역배열', 'S': '단기박스', 'B': '장기박스', 'D': '깊은베이스',
};

const PRESETS = [
  { key: 'buy',   label: '🎯 매수 적기',  codes: ['★', 'T', 'R', 'Q', '2'],
    desc: '저격 + 턴어라운드 + 조정 매집 + 신고가 임박 + Phase 2' },
  { key: 'trend', label: '📈 추세 진행',  codes: ['W', 'X', 'P'],
    desc: '주봉 정배열 + 주봉 조정 중 + 핵심 전환점' },
  { key: 'all',   label: '🔍 전체',       codes: null,
    desc: '필터 없이 17개 모두 표시' },
];

function ScreenerView() {
  const [presetKey, setPresetKey] = useState('buy');
  const active = PRESETS.find(p => p.key === presetKey);

  const filteredRows = !active.codes
    ? D.screenerRows
    : D.screenerRows.filter(r => (r.signals || []).some(s => active.codes.includes(s)));

  return (
    <div className="screener">
      <div className="section-head">
        <div>
          <div className="eyebrow">DART Screener · Multi-Factor</div>
          <h1 className="section-title">다트 스크리너 결과</h1>
        </div>
        <div className="section-meta">
          {fmt.num(D.screenerSummary.universe)} 종목 스캔 · {filteredRows.length}/{D.screenerRows.length} 표시
        </div>
      </div>

      <div className="filter-bar">
        {PRESETS.map(p => (
          <button key={p.key}
                  className={"chip " + (presetKey === p.key ? "on" : "")}
                  onClick={() => setPresetKey(p.key)}
                  title={p.desc}>
            {p.label}
          </button>
        ))}
        <span style={{ marginLeft: 12, fontSize: 11, color: 'var(--ink-3)', fontFamily: 'var(--font-mono)' }}>
          {active.desc}
        </span>
      </div>

      <div className="screener-summary">
        <div className="qs"><div className="qs-label">스캔 유니버스</div><div className="qs-value">{fmt.num(D.screenerSummary.universe)}</div><div className="qs-sub">KOSPI + KOSDAQ</div></div>
        <div className="qs"><div className="qs-label">통과 종목</div><div className="qs-value up">{D.screenerSummary.passed}</div><div className="qs-sub">전일 대비 +3</div></div>
        <div className="qs"><div className="qs-label">평균 Upside</div><div className="qs-value up">+{D.screenerSummary.avgUpside}%</div><div className="qs-sub">컨센 기준</div></div>
        <div className="qs"><div className="qs-label">외국인 합산 매수</div><div className="qs-value up">{D.screenerSummary.foreignBuy}</div><div className="qs-sub">5거래일 누적</div></div>
      </div>

      <div className="screener-table-wrap">
        <table className="scr-table">
          <thead>
            <tr>
              <th className="c">#</th>
              <th className="l">종목</th>
              <th>현재가</th>
              <th>등락률</th>
              <th>거래량</th>
              <th>외국인 5D</th>
              <th>목표가 변동</th>
              <th>Upside</th>
              <th className="c">시그널</th>
              <th>스코어</th>
            </tr>
          </thead>
          <tbody>
            {filteredRows.map(r => (
              <tr key={r.code} className={r.featured ? 'featured' : ''}>
                <td className="c"><span className="rank">{String(r.rank).padStart(2, '0')}</span></td>
                <td className="l">
                  <div className="stock-cell">
                    <span className="nm">{r.name}{r.featured && <span style={{ color: 'var(--gold)', marginLeft: 6 }}>★</span>}</span>
                    <span className="cd">{r.code}</span>
                    <span style={{ fontSize: 10, color: 'var(--ink-4)', fontFamily: 'var(--font-mono)', marginLeft: 4 }}>· {r.sector}</span>
                  </div>
                </td>
                <td>{r.px}</td>
                <td className="up">{r.chg}</td>
                <td className="up">{r.vol}</td>
                <td className="up">{r.fbuy}</td>
                <td className="up">{r.tgtChg}</td>
                <td className="up" style={{ fontWeight: 700 }}>{r.upside}</td>
                <td className="c">
                  <span className="signal-badges" style={{ display: 'flex', gap: 4, flexWrap: 'wrap', justifyContent: 'center' }}>
                    {/* 매칭된 신호만 한글 단축어로 표시 */}
                    {(r.signals || []).map(s => SIGNAL_KOR[s] ? (
                      <span key={s} className="sb on" style={{ fontSize: 10, padding: '2px 6px' }}>
                        {SIGNAL_KOR[s]}
                      </span>
                    ) : null)}
                  </span>
                </td>
                <td>
                  <div className="score-bar">
                    <div className="score-track"><div className="score-fill" style={{ width: r.score + '%' }}></div></div>
                    <span className="score-num">{r.score}</span>
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <div style={{ marginTop: 12, fontFamily: 'var(--font-mono)', fontSize: 10.5, color: 'var(--ink-3)', letterSpacing: '0.06em', padding: '0 4px' }}>
        시그널: V=거래량급증 · F=외국인순매수 · T=목표가상향 · E=어닝서프라이즈 · M=20일선상회
      </div>
    </div>
  );
}

// ========================== Reports view ==========================
function ReportsView() {
  const [active, setActive] = useState(D.reports[0].id);
  const r = D.reports.find(x => x.id === active);

  return (
    <div className="reports">
      <div className="reports-left">
        <div className="panel-head" style={{ borderBottom: '1px solid var(--border-hair)' }}>
          <h3>오늘의 리포트</h3>
          <span className="meta">{D.reports.length}건 · 04.22~04.24</span>
        </div>
        {D.reports.map(rp => (
          <div key={rp.id}
               className={"report-item " + (rp.id === active ? "active" : "")}
               onClick={() => setActive(rp.id)}>
            <div className="ri-head">
              <span className="ri-broker">{rp.broker}</span>
              <span className="ri-time">{rp.time}</span>
            </div>
            <div className="ri-title">{rp.title}</div>
            <div className="ri-meta">
              <span className="nm">{rp.stock}</span>
              <span className="tag up" style={{ padding: '1px 5px', fontSize: 9.5 }}>{rp.rating}</span>
              <span className="nm">목표 {fmt.num(rp.target)}</span>
            </div>
          </div>
        ))}
      </div>

      <div className="reports-right">
        <div className="report-detail">
          <div className="rd-head">
            <div>
              <div className="broker-line">{r.broker} · {r.analyst || ''}</div>
              <h2 className="rd-title" style={{ marginTop: 8 }}>{r.title}</h2>
              <div className="rd-stock-line">대상 종목 <strong>{r.stock}</strong> · 발행 {r.time} {r.pages && <>· {r.pages}p</>}</div>
            </div>
            <div className="pub">REPORT #{String(r.id).padStart(4, '0')}</div>
          </div>

          {r.callouts && (
            <div className="rd-callouts">
              {r.callouts.map((c, i) => (
                <div key={i} className="rd-callout">
                  <div className="lbl">{c.lbl}</div>
                  <div className="val">{c.val}</div>
                  <div className="sub">{c.sub}</div>
                </div>
              ))}
            </div>
          )}

          {!r.callouts && (
            <div className="rd-callouts">
              <div className="rd-callout"><div className="lbl">투자의견</div><div className="val">{r.rating}</div><div className="sub">유지</div></div>
              <div className="rd-callout"><div className="lbl">목표주가</div><div className="val">{fmt.num(r.target)}</div><div className="sub">↑ {fmt.num(r.targetPrev)} 대비</div></div>
              <div className="rd-callout"><div className="lbl">대상 종목</div><div className="val" style={{ fontSize: 14 }}>{r.stock.split('(')[0]}</div><div className="sub">{r.stock.match(/\(([^)]+)\)/)?.[1]}</div></div>
              <div className="rd-callout"><div className="lbl">발행</div><div className="val" style={{ fontSize: 14 }}>{r.time}</div><div className="sub">{r.broker}</div></div>
            </div>
          )}

          {r.sections ? (
            r.sections.map((s, i) => (
              <div key={i} className="rd-section">
                <h4>{s.h}</h4>
                {s.p && s.p.map((para, j) => <p key={j}>{para}</p>)}
                {s.bullets && (
                  <ul className="bullets">
                    {s.bullets.map((b, j) => <li key={j} dangerouslySetInnerHTML={{ __html: b }} />)}
                  </ul>
                )}
              </div>
            ))
          ) : (
            <div className="rd-section">
              <h4>요약</h4>
              <p>리포트 본문 요약은 좌측 목록에서 다른 리포트를 선택하시면 미래에셋증권 표제 리포트의 전체 본문을 확인하실 수 있습니다. 본 리포트는 {r.broker} {r.analyst}이 발행한 {r.target.toLocaleString()}원 목표가 리포트로, {r.targetPrev && `직전 ${r.targetPrev.toLocaleString()}원 대비 ${(((r.target/r.targetPrev)-1)*100).toFixed(1)}% 상향되었습니다.`}</p>
              <p style={{ color: 'var(--ink-3)', fontStyle: 'italic' }}>전체 본문은 PDF 원문에서 확인 가능합니다. (24p)</p>
            </div>
          )}

          <div className="disclosures">
            ※ 본 리포트는 작성일 기준 공개된 정보를 바탕으로 작성되었으며, 정확성과 완전성을 보장하지 않습니다. 투자 결정은 투자자 본인의 판단과 책임 하에 이루어져야 하며, 본 자료는 투자 권유나 매매 추천을 위한 자료가 아닙니다. 작성자 및 소속 회사는 본 자료에 기초한 투자 결과에 대해 어떠한 책임도 지지 않습니다.
          </div>
        </div>
      </div>
    </div>
  );
}

// ========================== Root ==========================
function App() {
  const [tab, setTab] = useState('toppick');

  return (
    <div className="app">
      <Sidebar tab={tab} setTab={setTab} />
      <Header />
      <main className="main">
        <Tabs tab={tab} setTab={setTab} />
        <div className="content">
          <div className={"view " + (tab === 'toppick'  ? 'active' : '')}><TopPickView /></div>
          <div className={"view " + (tab === 'screener' ? 'active' : '')}><ScreenerView /></div>
          <div className={"view " + (tab === 'reports'  ? 'active' : '')}><ReportsView /></div>
        </div>
      </main>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
