/* ============================================================
   ga4-analytics.jsx — 관리자 분석 (Sellery 구성 · Bannerly 디자인)
   ============================================================ */
function Ga4AnalyticsView() {
  const [days, setDays] = useState(28);
  const [state, setState] = useState('loading'); // loading | ok | empty
  const [report, setReport] = useState(null);
  const [helpOpen, setHelpOpen] = useState(false);

  const reload = React.useCallback(async (d) => {
    setState('loading');
    const n = d == null ? days : d;
    if (!window.__ga4) {setReport({ ok: false, reason: 'error', message: '분석 모듈이 로드되지 않았습니다' });setState('ok');return;}
    const r = await window.__ga4.fetchReport(n);
    setReport(r);
    setState('ok');
  }, [days]);

  useEffect(() => {reload();}, [days]);

  const cell = { height: 40, padding: '0 12px', borderRadius: 8, border: '1px solid var(--border)', font: 'inherit', fontSize: 13, background: '#fff', boxSizing: 'border-box', color: 'var(--text-1)' };
  const CHEV = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238a8a96' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>";
  const selectCell = Object.assign({}, cell, { appearance: 'none', WebkitAppearance: 'none', MozAppearance: 'none', backgroundImage: 'url("' + CHEV + '")', backgroundRepeat: 'no-repeat', backgroundPosition: 'right 12px center', paddingRight: 34, cursor: 'pointer', minWidth: 140 });
  const th = { textAlign: 'left', padding: '11px 16px', fontSize: 12.5, fontWeight: 700, color: 'var(--text-subtle)', whiteSpace: 'nowrap' };
  const td = { padding: '9px 16px', fontSize: 13, verticalAlign: 'middle', borderTop: '1px solid var(--border)', color: 'var(--text-1)' };
  const panel = { background: '#fff', border: '1px solid var(--border)', borderRadius: 12, padding: 20, marginBottom: 16 };
  const ACCENT = '#4E4CDB';

  const fmtPct = (rate) => {
    if (!Number.isFinite(rate)) return '—';
    return (rate * 100).toFixed(1) + '%';
  };
  const fmtDur = (seconds) => {
    if (!Number.isFinite(seconds) || seconds <= 0) return '—';
    if (seconds < 60) return Math.round(seconds) + '초';
    const m = Math.floor(seconds / 60);
    const s = Math.round(seconds % 60);
    return s > 0 ? m + '분 ' + s + '초' : m + '분';
  };
  const nfmt = (n) => Number(n || 0).toLocaleString();
  const fmtConv = (views, done) => {
    if (!views) return '—';
    return ((Number(done || 0) / views) * 100).toFixed(1) + '%';
  };

  const pid = report && report.propertyId;
  const realtimeHref = pid
    ? 'https://analytics.google.com/analytics/web/#/p' + pid + '/realtime/overview'
    : 'https://analytics.google.com/analytics/web/#/realtime/overview';

  const Tile = ({ label, value, sub, accent }) => (
    <div style={{ background: accent ? '#eef2ff' : '#fff', border: '1px solid var(--border)', borderRadius: 12, padding: '16px 18px', minWidth: 0 }}>
      <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--text-subtle)', marginBottom: 8 }}>{label}</div>
      <div style={{ fontSize: 22, fontWeight: 750, letterSpacing: '-0.03em', color: accent ? ACCENT : 'var(--text-1)' }}>{value}</div>
      {sub ? <div style={{ fontSize: 12, color: 'var(--text-subtle)', marginTop: 6, lineHeight: 1.4 }}>{sub}</div> : null}
    </div>
  );

  const maxDay = report && report.ok ? Math.max(1, ...report.daily.map((d) => d.activeUsers)) : 1;
  const dailyTotal = report && report.ok ? report.daily.reduce((s, d) => s + d.activeUsers, 0) : 0;
  const channelTotal = report && report.ok ? Math.max(1, report.channels.reduce((s, c) => s + c.sessions, 0)) : 1;
  const labelEvery = report && report.ok ? (report.daily.length > 31 ? 7 : report.daily.length > 14 ? 3 : 1) : 1;

  return (
    <div className="content"><div className="content-pad">
      <div className="page-head" style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8, gap: 12, flexWrap: 'wrap' }}>
        <h1 className="page-title">분석</h1>
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
          <button className="btn btn-secondary" style={{ minWidth: 96 }} onClick={() => setHelpOpen(true)}>지표 설명</button>
          <a className="btn btn-secondary" style={{ minWidth: 112, textDecoration: 'none', display: 'inline-flex', alignItems: 'center', justifyContent: 'center' }} href={realtimeHref} target="_blank" rel="noopener noreferrer">GA4 실시간</a>
        </div>
      </div>
      <p className="page-sub" style={{ marginBottom: 16 }}>사용자 화면(배너 어시스턴트·에디터·내 배너) 방문만 셉니다. 관리자 메뉴는 빼며, 집계는 실시간보다 늦게 붙을 수 있습니다.</p>

      <div style={{ marginBottom: 16, display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'center' }}>
        <select aria-label="집계 기간" style={selectCell} value={days} onChange={(e) => setDays(Number(e.target.value))}>
          <option value={7}>최근 7일</option>
          <option value={28}>최근 28일</option>
          <option value={90}>최근 90일</option>
        </select>
        <button className="btn btn-secondary" disabled={state === 'loading'} onClick={() => reload(days)}>새로고침</button>
      </div>

      {state === 'loading' &&
        <div className="empty-wrap"><div className="empty">
          <div className="spinner" style={{ width: 28, height: 28, marginBottom: 16 }} />
          <p className="empty-text">불러오는 중…</p>
        </div></div>}

      {state === 'ok' && report && !report.ok &&
        <div style={panel}>
          <div style={{ fontSize: 14, fontWeight: 700, marginBottom: 8 }}>아직 숫자를 불러오지 못했어요</div>
          <div style={{ fontSize: 13, color: 'var(--text-subtle)', lineHeight: 1.55 }}>{report.message}</div>
          {report.reason === 'no_access' && report.serviceAccount ?
            <div style={{ marginTop: 10, fontSize: 12.5, fontFamily: 'ui-monospace, monospace', wordBreak: 'break-all' }}>{report.serviceAccount}</div> : null}
          {report.reason === 'not_configured' ?
            <div style={{ marginTop: 10, fontSize: 12.5, color: 'var(--text-subtle)', lineHeight: 1.55 }}>
              서버에 <code>GA4_SA_CLIENT_EMAIL</code>, <code>GA4_SA_PRIVATE_KEY</code> 를 넣으면 숫자가 나옵니다.
            </div> : null}
          {report.reason === 'no_property' ?
            <div style={{ marginTop: 10, fontSize: 12.5, color: 'var(--text-subtle)', lineHeight: 1.55 }}>
              애널리틱스 관리 → 속성 설정의 숫자 ID 를 <code>GA4_PROPERTY_ID</code> 에 넣습니다. 사이트에 심은 <code>G-</code> 측정 ID 와는 다릅니다.
            </div> : null}
        </div>}

      {state === 'ok' && report && report.ok &&
        <React.Fragment>
          <div style={{ fontSize: 12.5, color: 'var(--text-subtle)', marginBottom: 12 }}>최근 {report.days}일 · Google Analytics 4</div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(160px, 1fr))', gap: 10, marginBottom: 12 }}>
            <Tile accent label="실시간 사용자" value={nfmt(report.realtimeUsers)} sub="지금 ~ 30분" />
            <Tile label="활성 사용자" value={nfmt(report.activeUsers)} sub="기간 중 방문한 사람" />
            <Tile label="세션" value={nfmt(report.sessions)} sub="방문 횟수" />
            <Tile label="페이지뷰" value={nfmt(report.pageviews)} sub="화면을 연 횟수" />
            <Tile label="이탈률" value={fmtPct(report.bounceRate)} sub="한 화면만 보고 나간 비율" />
            <Tile label="평균 체류 시간" value={fmtDur(report.avgSessionSeconds)} sub="방문 1번당 머문 시간" />
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(160px, 1fr))', gap: 10, marginBottom: 16 }}>
            <Tile label="신규 사용자" value={nfmt(report.newUsers)} sub="기간 중 처음 방문" />
            <Tile label="재방문 사용자" value={nfmt(report.returningUsers)} sub="활성 − 신규" />
          </div>

          <div style={panel}>
            <div style={{ fontSize: 14, fontWeight: 700, marginBottom: 4 }}>유입 · 활성 사용자 추이</div>
            <div style={{ fontSize: 12.5, color: 'var(--text-subtle)', marginBottom: 16 }}>위는 날짜별 방문, 아래는 어디서 들어왔는지</div>
            {dailyTotal === 0 ?
              <div style={{ fontSize: 13, color: 'var(--text-subtle)', marginBottom: 16 }}>이 기간에 방문이 없습니다. 반영까지 몇 시간 걸릴 수 있습니다.</div> :
              <div style={{ display: 'flex', alignItems: 'flex-end', gap: 2, height: 180, overflowX: 'auto', borderBottom: '1px solid var(--border)', paddingBottom: 4, marginBottom: 20 }} role="img" aria-label="날짜별 활성 사용자">
                {report.daily.map((row, index) => {
                  const h = (row.activeUsers / maxDay) * 100;
                  const show = index % labelEvery === 0 || index === report.daily.length - 1;
                  return (
                    <div key={row.date} title={row.date + ' · ' + nfmt(row.activeUsers) + '명'} style={{ flex: 1, minWidth: 8, height: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'flex-end', gap: 4 }}>
                      <div style={{ width: '100%', maxWidth: 22, height: Math.max(h, row.activeUsers > 0 ? 6 : 0) + '%', background: ACCENT, borderRadius: '3px 3px 0 0', opacity: row.activeUsers === 0 ? 0 : 1 }} />
                      {show ? <span style={{ fontSize: 10, color: 'var(--text-subtle)', flexShrink: 0 }}>{row.date.slice(5)}</span> : <span style={{ height: 10 }} />}
                    </div>
                  );
                })}
              </div>}
            <div style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--text-subtle)', marginBottom: 10 }}>유입 채널</div>
            {!report.channels.length ?
              <div style={{ fontSize: 13, color: 'var(--text-subtle)' }}>채널별 유입이 아직 없습니다.</div> :
              <div>
                {report.channels.map((row) => {
                  const pct = ((row.sessions / channelTotal) * 100).toFixed(1);
                  return (
                    <div key={row.channel} style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 8 }}>
                      <span style={{ width: 96, flexShrink: 0, fontSize: 12.5, color: 'var(--text-subtle)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title={row.channel}>{row.channel}</span>
                      <span style={{ flex: 1, height: 8, background: '#f0f0f3', borderRadius: 99, overflow: 'hidden' }}>
                        <span style={{ display: 'block', height: '100%', width: (row.sessions / channelTotal) * 100 + '%', background: ACCENT, borderRadius: 99 }} />
                      </span>
                      <span style={{ width: 84, flexShrink: 0, textAlign: 'right', fontSize: 12.5 }}>{pct}% · {row.sessions}</span>
                    </div>
                  );
                })}
              </div>}
          </div>

          <div style={panel}>
            <div style={{ fontSize: 14, fontWeight: 700, marginBottom: 4 }}>만든 배너 · 조회 · 완료</div>
            <div style={{ fontSize: 12.5, color: 'var(--text-subtle)', marginBottom: 14 }}>어시스턴트와 에디터를 나눠 셉니다. 첫 줄은 가이드로 시작, 아래는 저장/다운로드입니다. 누끼는 유형별 완료에 붙습니다.</div>
            <div style={{ border: '1px solid var(--border)', borderRadius: 10, overflow: 'hidden', marginBottom: 16 }}>
              <table style={{ width: '100%', borderCollapse: 'collapse' }}>
                <thead>
                  <tr style={{ background: '#fafafa' }}>
                    <th style={th}>배너</th>
                    <th style={{ ...th, textAlign: 'right' }}>조회</th>
                    <th style={{ ...th, textAlign: 'right' }}>완료</th>
                    <th style={{ ...th, textAlign: 'right' }}>전환율</th>
                  </tr>
                </thead>
                <tbody>
                  {(report.funnel || []).map((row) =>
                    <tr key={row.key}>
                      <td style={td}>{row.label}</td>
                      <td style={{ ...td, textAlign: 'right' }}>{nfmt(row.views)}</td>
                      <td style={{ ...td, textAlign: 'right' }}>{nfmt(row.completions)}</td>
                      <td style={{ ...td, textAlign: 'right' }}>{fmtConv(row.views, row.completions)}</td>
                    </tr>)}
                </tbody>
              </table>
            </div>
            <div style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--text-subtle)', marginBottom: 8 }}>유형별 완료</div>
            {!(report.downloads && report.downloads.length) ?
              <div style={{ fontSize: 13, color: 'var(--text-subtle)' }}>아직 저장/다운로드 완료가 없습니다. 배포된 사이트에서 배너를 저장하면 붙습니다.</div> :
              <div style={{ border: '1px solid var(--border)', borderRadius: 10, overflow: 'hidden' }}>
                <table style={{ width: '100%', borderCollapse: 'collapse' }}>
                  <thead>
                    <tr style={{ background: '#fafafa' }}>
                      <th style={th}>유형</th>
                      <th style={{ ...th, textAlign: 'right' }}>완료</th>
                    </tr>
                  </thead>
                  <tbody>
                    {report.downloads.map((row) =>
                      <tr key={row.name}>
                        <td style={td}>{row.label}</td>
                        <td style={{ ...td, textAlign: 'right' }}>{nfmt(row.count)}</td>
                      </tr>)}
                  </tbody>
                </table>
              </div>}
          </div>

          <div style={panel}>
            <div style={{ fontSize: 14, fontWeight: 700, marginBottom: 4 }}>많이 본 주소</div>
            <div style={{ fontSize: 12.5, color: 'var(--text-subtle)', marginBottom: 14 }}>사용자 화면 경로입니다. 예: <code>/app/assistant</code>, <code>/app/550</code></div>
            {!report.pages.length ?
              <div style={{ fontSize: 13, color: 'var(--text-subtle)' }}>이 기간에 페이지 조회가 없습니다.</div> :
              <div style={{ border: '1px solid var(--border)', borderRadius: 10, overflow: 'hidden' }}>
                <table style={{ width: '100%', borderCollapse: 'collapse' }}>
                  <thead>
                    <tr style={{ background: '#fafafa' }}>
                      <th style={th}>주소</th>
                      <th style={{ ...th, textAlign: 'right' }}>조회수</th>
                      <th style={{ ...th, textAlign: 'right' }}>사용자</th>
                      <th style={{ ...th, textAlign: 'right' }}>이탈률</th>
                    </tr>
                  </thead>
                  <tbody>
                    {report.pages.map((p) =>
                      <tr key={p.path}>
                        <td style={{ ...td, fontFamily: 'ui-monospace, monospace', fontSize: 12.5 }}>{p.path}</td>
                        <td style={{ ...td, textAlign: 'right' }}>{nfmt(p.views)}</td>
                        <td style={{ ...td, textAlign: 'right' }}>{nfmt(p.users)}</td>
                        <td style={{ ...td, textAlign: 'right' }}>{p.views > 0 ? fmtPct(p.bounceRate) : '—'}</td>
                      </tr>)}
                  </tbody>
                </table>
              </div>}
          </div>
        </React.Fragment>}

      {helpOpen &&
        <div onClick={() => setHelpOpen(false)} style={{ position: 'fixed', inset: 0, background: 'rgba(20,20,26,.45)', display: 'grid', placeItems: 'center', zIndex: 9990 }}>
          <div onClick={(e) => e.stopPropagation()} style={{ position: 'relative', width: 560, maxWidth: '92vw', maxHeight: '85vh', overflowY: 'auto', background: '#fff', borderRadius: 16, padding: 24, boxShadow: '0 12px 40px rgba(0,0,0,.22)' }}>
            <button onClick={() => setHelpOpen(false)} title="닫기" style={{ position: 'absolute', top: 14, right: 14, border: 'none', background: 'none', cursor: 'pointer', fontSize: 22, lineHeight: 1, color: 'var(--text-subtle)', padding: 4 }}>×</button>
            <div style={{ fontSize: 16, fontWeight: 800, marginBottom: 8 }}>지표 설명</div>
            <p style={{ fontSize: 13, color: 'var(--text-subtle)', lineHeight: 1.55, margin: '0 0 16px' }}>상단 칸은 사이트 전체를 합친 숫자입니다. 아래 표는 주소마다 나눕니다.</p>
            {[
              { t: '실시간 사용자', d: '지금 ~ 30분 사이 사이트에 있는 사람 수. 기간 필터와 무관합니다.' },
              { t: '활성 사용자', d: '선택한 기간에 한 번이라도 들어온 사람 수(중복 제거).' },
              { t: '세션', d: '방문 횟수. 30분 동안 움직임이 없으면 다음 접속은 새 방문입니다.' },
              { t: '페이지뷰', d: '화면을 연 횟수 합. 한 번 들어와서 화면을 여러 번 보면 세션보다 큽니다.' },
              { t: '이탈률', d: '한 화면만 보고 끝난 방문의 비율입니다.' },
              { t: '평균 체류 시간', d: '방문 한 번당 사이트에 머문 평균 시간입니다.' },
              { t: '배너 어시스턴트 완료', d: '가이드로 만들기를 누른 횟수입니다. 앱푸시·550·H1은 어시스턴트/에디터를 나눠 저장·다운로드를 셉니다. 누끼는 팝업에서 결과가 나왔을 때만 셉니다.' },
            ].map((item) =>
              <div key={item.t} style={{ borderTop: '1px solid var(--border)', padding: '12px 0' }}>
                <div style={{ fontSize: 13.5, fontWeight: 700, marginBottom: 4 }}>{item.t}</div>
                <div style={{ fontSize: 13, color: 'var(--text-subtle)', lineHeight: 1.5 }}>{item.d}</div>
              </div>)}
          </div>
        </div>}
    </div></div>
  );
}

window.Ga4AnalyticsView = Ga4AnalyticsView;
