// 통계 페이지 — 계정별 성과 요약 + 글별 순위
//
// 데이터는 /api/stats 가 이미 중복 제거·집계까지 끝내서 준다.
// 여기서는 보여주기(정렬·필터·포맷)만 한다. 계산을 화면에 또 두면
// API 와 숫자가 갈라져서 어느 쪽이 맞는지 알 수 없게 된다.

function fmtNum(n) {
  if (n === null || n === undefined) return '—';
  if (n >= 1000000) return (n / 1000000).toFixed(1).replace(/\.0$/, '') + 'M';
  if (n >= 10000) return (n / 1000).toFixed(1).replace(/\.0$/, '') + 'k';
  return n.toLocaleString('ko-KR');
}

const TRACK_COLOR = {
  ko: 'oklch(0.62 0.15 25)',
  'zh-TW': 'oklch(0.62 0.14 60)',
  ja: 'oklch(0.62 0.13 300)',
  en: 'oklch(0.62 0.13 240)',
  es: 'oklch(0.62 0.14 145)',
};
function trackColor(locale, handle) {
  if (TRACK_COLOR[locale]) return TRACK_COLOR[locale];
  const key = String(locale || handle || '').toLowerCase();
  if (key.includes('ko')) return TRACK_COLOR.ko;
  if (key.includes('tw') || key.includes('zh')) return TRACK_COLOR['zh-TW'];
  if (key.includes('ja')) return TRACK_COLOR.ja;
  if (key.includes('es')) return TRACK_COLOR.es;
  if (key.includes('en')) return TRACK_COLOR.en;
  return 'var(--fg-muted)';
}

// 표 컬럼 정의 — key 는 API 필드명 그대로. 정렬이 곧 그 필드의 숫자 정렬이 된다.
const COLUMNS = [
  { key: 'views', label: '조회수' },
  { key: 'likes', label: '좋아요' },
  { key: 'replies', label: '댓글*' },
  { key: 'reposts', label: '리포스트' },
  { key: 'quotes', label: '인용' },
  { key: 'shares', label: '공유' },
  { key: 'engagementRate', label: '참여율', suffix: '%' },
];

function Delta({ pct }) {
  if (pct === null || pct === undefined) return <span style={{ color: 'var(--fg-faint)', fontSize: 11 }}>표본 부족</span>;
  const up = pct >= 0;
  return (
    <span style={{ fontSize: 11.5, fontWeight: 600, color: up ? 'var(--status-published-fg)' : 'var(--status-failed-fg)' }}>
      {up ? '▲' : '▼'} {Math.abs(pct)}%
    </span>
  );
}

function StatsPage() {
  const [days, setDays] = React.useState('14');
  const [data, setData] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState('');
  const [sort, setSort] = React.useState({ key: 'views', dir: 'desc' });
  const [account, setAccount] = React.useState('all');
  const [why, setWhy] = React.useState(false); // 계산 방식 설명 접기/펴기

  async function load(d) {
    setLoading(true);
    setError('');
    try {
      const res = await fetch(`/api/stats?days=${d}`, { cache: 'no-store' });
      const json = await res.json();
      if (!json.ok) throw new Error(json.error || '불러오기 실패');
      setData(json);
    } catch (e) {
      setError(e.message || String(e));
      setData(null);
    } finally {
      setLoading(false);
    }
  }

  React.useEffect(() => { load(days); }, [days]);

  const accounts = (data && data.accounts) || [];
  const allPosts = (data && data.posts) || [];

  const posts = React.useMemo(() => {
    const filtered = account === 'all' ? allPosts : allPosts.filter((p) => p.accountHandle === account);
    const dir = sort.dir === 'desc' ? -1 : 1;
    return [...filtered].sort((a, b) => {
      const av = a[sort.key], bv = b[sort.key];
      // shares 는 미수집 글이 null 이다. null 은 항상 아래로 밀어 정렬을 오염시키지 않는다.
      if (av === null && bv === null) return 0;
      if (av === null) return 1;
      if (bv === null) return -1;
      return (av - bv) * dir;
    });
  }, [allPosts, account, sort]);

  function toggleSort(key) {
    setSort((s) => (s.key === key ? { key, dir: s.dir === 'desc' ? 'asc' : 'desc' } : { key, dir: 'desc' }));
  }

  const totals = React.useMemo(() => {
    const t = { views: 0, likes: 0, replies: 0, reposts: 0, quotes: 0, shares: 0, posts: 0, sharesTracked: false };
    for (const a of accounts) {
      t.views += a.views; t.likes += a.likes; t.replies += a.replies;
      t.reposts += a.reposts; t.quotes += a.quotes; t.posts += a.posts;
      if (a.shares !== null) { t.shares += a.shares; t.sharesTracked = true; }
    }
    return t;
  }, [accounts]);

  return (
    <>
      <div className="page-header">
        <div>
          <h1 className="page-title">통계</h1>
          <div className="page-subtitle">
            스레드 계정별 조회수·반응을 한 화면에서. 같은 글의 중복 수집은 걷어내고 계정당 한 줄로 접었습니다.
          </div>
        </div>
        <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
          <div className="view-toggle">
            {[['7', '7일'], ['14', '14일'], ['30', '30일'], ['all', '전체']].map(([v, label]) => (
              <button key={v} className={`filter-tab ${days === v ? 'active' : ''}`} onClick={() => setDays(v)}>{label}</button>
            ))}
          </div>
          <button className="btn" onClick={() => load(days)} disabled={loading}>
            <Icon name="refresh" size={13} />{loading ? '불러오는 중…' : '새로고침'}
          </button>
        </div>
      </div>

      {error && (
        <div className="card" style={{ borderColor: 'var(--status-failed-dot)', marginBottom: 16 }}>
          <div className="card-body" style={{ color: 'var(--status-failed-fg)' }}>
            불러오지 못했습니다 — {error}
          </div>
        </div>
      )}

      {loading && !data && <div className="empty">불러오는 중…</div>}

      {data && (
        <>
          {/* ── 전체 합계 ───────────────────────────────── */}
          <div className="kpi-grid">
            <div className="kpi">
              <div className="kpi-label"><Icon name="eye" size={13} />총 조회수</div>
              <div className="kpi-value">{fmtNum(totals.views)}</div>
              <div className="kpi-hint">{totals.posts}개 글 · {accounts.length}개 계정</div>
            </div>
            <div className="kpi">
              <div className="kpi-label"><Icon name="heart" size={13} />좋아요</div>
              <div className="kpi-value">{fmtNum(totals.likes)}</div>
              <div className="kpi-hint">댓글 {fmtNum(totals.replies)}건 (시리즈 파트 포함)</div>
            </div>
            <div className="kpi">
              <div className="kpi-label"><Icon name="refresh" size={13} />리포스트 · 인용</div>
              <div className="kpi-value">{fmtNum(totals.reposts + totals.quotes)}</div>
              <div className="kpi-hint">리포스트 {fmtNum(totals.reposts)} · 인용 {fmtNum(totals.quotes)}</div>
            </div>
            <div className="kpi">
              <div className="kpi-label"><Icon name="send" size={13} />공유</div>
              <div className="kpi-value">{totals.sharesTracked ? fmtNum(totals.shares) : '—'}</div>
              <div className="kpi-hint">
                {totals.sharesTracked ? '수집 중' : '아직 수집 전 — 다음 수집부터 쌓입니다'}
              </div>
            </div>
          </div>

          {/* ── 계정별 요약 ─────────────────────────────── */}
          <div className="card" style={{ marginTop: 16 }}>
            <div className="card-header">
              <div>
                <div className="card-title">계정별 요약</div>
                <div className="card-sub">
                  조회수 중앙값 기준 정렬 · 참여율에 댓글은 넣지 않았습니다
                  {' '}
                  <button className="btn ghost sm" style={{ padding: '2px 8px', fontSize: 11.5 }}
                          onClick={() => setWhy((v) => !v)}>
                    {why ? '설명 접기' : '왜죠?'}
                  </button>
                </div>
                {why && (
                  <div style={{ marginTop: 10, padding: '10px 12px', borderRadius: 8,
                                background: 'var(--bg-canvas)', border: '1px solid var(--border-subtle)',
                                fontSize: 12.5, lineHeight: 1.7, color: 'var(--fg-muted)', maxWidth: '86ch' }}>
                    <b>중앙값을 쓰는 이유</b> — 한 글이 터지면 평균이 통째로 끌려가서 계정의 평소 실력을 못 보여줍니다.<br />
                    <b>댓글을 뺀 이유</b> — 우리 글이 2~3 파트 시리즈라 2·3번째 파트가 스레드에서 "댓글"로 잡힙니다.
                    넣으면 조회수 낮은 계정의 참여율이 부풀려집니다 (EN2가 11회 조회에 25% 로 1위처럼 보였습니다).<br />
                    참여율 = {(data && data.engagementFormula) || '좋아요 + 리포스트 + 인용 + 공유'}
                  </div>
                )}
              </div>
            </div>
            <div className="card-body" style={{ padding: 0, overflowX: 'auto' }}>
              <table className="table">
                <thead>
                  <tr>
                    <th>계정</th>
                    <th style={{ textAlign: 'right' }}>글</th>
                    <th style={{ textAlign: 'right' }}>조회수 중앙값</th>
                    <th style={{ textAlign: 'right' }}>최고</th>
                    <th style={{ textAlign: 'right' }}>총 조회수</th>
                    <th style={{ textAlign: 'right' }}>좋아요</th>
                    <th style={{ textAlign: 'right' }} title="우리 시리즈 2·3파트도 댓글로 잡힙니다">댓글*</th>
                    <th style={{ textAlign: 'right' }}>리포스트</th>
                    <th style={{ textAlign: 'right' }}>인용</th>
                    <th style={{ textAlign: 'right' }}>공유</th>
                    <th style={{ textAlign: 'right' }}>참여율</th>
                    <th style={{ textAlign: 'right' }}>추세</th>
                  </tr>
                </thead>
                <tbody>
                  {accounts.map((a) => (
                    <tr key={a.handle} style={{ cursor: 'pointer' }}
                        onClick={() => setAccount(account === a.handle ? 'all' : a.handle)}>
                      <td>
                        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                          <span style={{ width: 6, height: 24, borderRadius: 3, background: trackColor(a.locale, a.handle), flexShrink: 0 }} />
                          <div style={{ minWidth: 0 }}>
                            <div style={{ fontWeight: 600, fontSize: 13 }}>{a.handle}</div>
                            <div style={{ fontSize: 11, color: 'var(--fg-subtle)' }}>{a.locale || '—'}</div>
                          </div>
                        </div>
                      </td>
                      <td style={{ textAlign: 'right' }}>{a.posts}</td>
                      <td style={{ textAlign: 'right', fontWeight: 700, fontSize: 14 }}>{fmtNum(a.medianViews)}</td>
                      <td style={{ textAlign: 'right', color: 'var(--fg-muted)' }}>{fmtNum(a.bestViews)}</td>
                      <td style={{ textAlign: 'right' }}>{fmtNum(a.views)}</td>
                      <td style={{ textAlign: 'right' }}>{fmtNum(a.likes)}</td>
                      <td style={{ textAlign: 'right' }}>{fmtNum(a.replies)}</td>
                      <td style={{ textAlign: 'right' }}>{fmtNum(a.reposts)}</td>
                      <td style={{ textAlign: 'right' }}>{fmtNum(a.quotes)}</td>
                      <td style={{ textAlign: 'right' }}>{a.shares === null ? '—' : fmtNum(a.shares)}</td>
                      <td style={{ textAlign: 'right' }}>{a.engagementRate}%</td>
                      <td style={{ textAlign: 'right' }}><Delta pct={a.trendPct} /></td>
                    </tr>
                  ))}
                </tbody>
              </table>
              {accounts.length === 0 && <div className="empty">이 기간에 수집된 성과가 없습니다.</div>}
            </div>
          </div>

          {/* ── 글별 순위 ───────────────────────────────── */}
          <div className="card" style={{ marginTop: 16 }}>
            <div className="card-header">
              <div>
                <div className="card-title">글별 순위</div>
                <div className="card-sub">
                  머리글을 눌러 정렬. 계정 행을 누르면 그 계정만 걸러집니다.
                </div>
              </div>
              {account !== 'all' && (
                <button className="btn ghost" onClick={() => setAccount('all')}>
                  <Icon name="x" size={12} />{account} 필터 해제
                </button>
              )}
            </div>
            <div className="card-body" style={{ padding: 0, overflowX: 'auto' }}>
              <table className="table">
                <thead>
                  <tr>
                    <th style={{ width: 36 }}>#</th>
                    <th>글</th>
                    <th>계정</th>
                    <th>발행</th>
                    {COLUMNS.map((c) => (
                      <th key={c.key} style={{ textAlign: 'right', cursor: 'pointer', whiteSpace: 'nowrap' }}
                          onClick={() => toggleSort(c.key)}>
                        {c.label}{sort.key === c.key ? (sort.dir === 'desc' ? ' ▼' : ' ▲') : ''}
                      </th>
                    ))}
                  </tr>
                </thead>
                <tbody>
                  {posts.slice(0, 200).map((p, i) => (
                    <tr key={p.externalPostId}>
                      <td style={{ color: 'var(--fg-faint)', fontSize: 11 }}>{i + 1}</td>
                      <td style={{ maxWidth: 380 }}>
                        <a href={p.url} target="_blank" rel="noreferrer"
                           style={{ color: 'var(--fg)', textDecoration: 'none', display: 'block' }}>
                          <div style={{ fontSize: 12.5, lineHeight: 1.4, overflow: 'hidden', display: '-webkit-box',
                                        WebkitLineClamp: 2, WebkitBoxOrient: 'vertical' }}>
                            {p.hook || p.title || '(본문 없음)'}
                          </div>
                          {p.topic && <div style={{ fontSize: 10.5, color: 'var(--fg-subtle)', marginTop: 2 }}>{p.topic}</div>}
                        </a>
                      </td>
                      <td style={{ whiteSpace: 'nowrap' }}>
                        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 11.5 }}>
                          <span style={{ width: 6, height: 6, borderRadius: 3, background: trackColor(p.locale, p.accountHandle) }} />
                          {p.accountHandle}
                        </span>
                      </td>
                      <td style={{ whiteSpace: 'nowrap', fontSize: 11.5, color: 'var(--fg-muted)' }}>{fmtTime(p.publishedAt)}</td>
                      <td style={{ textAlign: 'right', fontWeight: 700 }}>{fmtNum(p.views)}</td>
                      <td style={{ textAlign: 'right' }}>{fmtNum(p.likes)}</td>
                      <td style={{ textAlign: 'right' }}>{fmtNum(p.replies)}</td>
                      <td style={{ textAlign: 'right' }}>{fmtNum(p.reposts)}</td>
                      <td style={{ textAlign: 'right' }}>{fmtNum(p.quotes)}</td>
                      <td style={{ textAlign: 'right', color: p.shares === null ? 'var(--fg-faint)' : undefined }}>
                        {p.shares === null ? '—' : fmtNum(p.shares)}
                      </td>
                      <td style={{ textAlign: 'right' }}>{p.engagementRate}%</td>
                    </tr>
                  ))}
                </tbody>
              </table>
              {posts.length === 0 && <div className="empty">표시할 글이 없습니다.</div>}
              {posts.length > 200 && (
                <div style={{ padding: '10px 14px', fontSize: 11.5, color: 'var(--fg-subtle)' }}>
                  상위 200개만 표시 (전체 {posts.length}개)
                </div>
              )}
            </div>
          </div>

          <div style={{ marginTop: 12, fontSize: 11.5, color: 'var(--fg-subtle)' }}>
            마지막 갱신 {fmtTime(data.generatedAt)}
            {!data.sharesSupported && ' · 공유 수는 다음 수집분부터 들어옵니다'}
          </div>
        </>
      )}
    </>
  );
}

window.StatsPage = StatsPage;
