/* global React, Icon, UI, LessonHighData */
// ============================================================
// I8 · 분석 — F8 (매출/전환/LTV) + F9 (채널 ROI · 추천 · 리뷰)
//   학원장이 "이번 달 어떻게 됐나"·"어디에 광고 더 태울까"를 답할 수 있는 페이지
// ============================================================
(function () {
const { useState, useMemo } = React;
const D = LessonHighData;

const RANGES = [
  { id: '1m',  label: '1개월',  months: 1 },
  { id: '3m',  label: '3개월',  months: 3 },
  { id: '6m',  label: '6개월',  months: 6 },
  { id: '12m', label: '12개월', months: 12 },
];

// ────────────────────────────────────────────────────────────
// 메인 페이지
// ────────────────────────────────────────────────────────────
function AnalyticsPage({ onOpenMember, onNav }) {
  const [range, setRange] = useState('12m');
  const [tab,   setTab]   = useState('revenue');
  const [exportOpen, setExportOpen] = useState(false);

  const months = RANGES.find(r => r.id === range).months;
  const trend = D.monthlyRevenue.slice(-months);

  const tabs = [
    { id: 'revenue',  label: '매출 / 트렌드' },
    { id: 'funnel',   label: '회원 Funnel' },
    { id: 'channel',  label: '유입 채널 ROI' },
    { id: 'pass',     label: '패스 분석' },
    { id: 'teacher',  label: '강사 기여' },
    { id: 'churn',    label: '이탈 분석' },
    { id: 'referral', label: '추천 · 리뷰' },
  ];

  return (
    <React.Fragment>
      <header className="page-header">
        <div>
          <h1 className="page-title">분석</h1>
          <div className="page-sub">
            {`매출 ${D.formatMoney(D.thisMonthRevenue.total)} (전월 대비 ${pct(D.thisMonthRevenue.total, D.lastMonthRevenue.total)})`}
            <span style={{ color: 'var(--text-tertiary)' }}> · 활동 회원 {D.thisMonthRevenue.members}명 · 이번 달 신규 +{Math.round(D.thisMonthRevenue.new / 280000)} · 이탈 {D.thisMonthRevenue.churn}</span>
          </div>
        </div>
        <div className="page-actions">
          <RangeToggle value={range} onChange={setRange}/>
          <UI.Button icon={Icon.Receipt} variant="ghost" onClick={() => setExportOpen(true)}>월간 리포트</UI.Button>
          <UI.Button icon={Icon.Send} variant="primary" onClick={() => { window.toast && window.toast('대표 이메일로 리포트 발송 예약됨 · 매월 1일 09시', { tone: 'success' }); }}>월간 발송 예약</UI.Button>
        </div>
      </header>

      {/* 1) KPI 4개 — 매출 / 순증 / 평균 LTV / CAC vs LTV */}
      <KpiRow trend={trend}/>

      {/* 2) 한 줄 스토리 */}
      <StoryCard trend={trend}/>

      {/* 3) 탭 분리 */}
      <UI.Tabs items={tabs} active={tab} onChange={setTab}/>

      <div style={{ marginTop: 16 }}>
        {tab === 'revenue'  && <RevenueSection trend={trend}/>}
        {tab === 'funnel'   && <FunnelSection onOpenMember={onOpenMember}/>}
        {tab === 'channel'  && <ChannelSection/>}
        {tab === 'pass'     && <PassSection/>}
        {tab === 'teacher'  && <TeacherContribSection onNav={onNav}/>}
        {tab === 'churn'    && <ChurnSection onOpenMember={onOpenMember}/>}
        {tab === 'referral' && <ReferralSection onOpenMember={onOpenMember}/>}
      </div>

      <ExportModal open={exportOpen} onClose={() => setExportOpen(false)}/>
    </React.Fragment>
  );
}

// ────────────────────────────────────────────────────────────
// KPI Row
// ────────────────────────────────────────────────────────────
function KpiRow({ trend }) {
  const cur = trend[trend.length - 1];
  const prev = trend[trend.length - 2] || cur;
  const sparkValues = trend.map(t => t.total / 1000000);

  // 평균 LTV — 등록 후 평균 9.4개월 유지 × 월평균 320,000
  const avgLtv = 3008000;
  // CAC 가중평균
  const totalSpend = D.channelROI.reduce((s, c) => s + c.adSpend, 0);
  const totalEnrolled = D.channelROI.reduce((s, c) => s + c.enrolled, 0);
  const avgCAC = Math.round(totalSpend / totalEnrolled);

  const newM   = Math.round(cur.new / 280000);
  const churnM = cur.churn;
  const net = newM - churnM;

  return (
    <div className="grid-4" style={{ marginBottom: 16 }}>
      <AnKpi label="이번 달 매출" value={D.formatMoney(cur.total)} delta={pct(cur.total, prev.total)} tone="success" sparkValues={sparkValues}/>
      <AnKpi label="순증 회원" value={`${net >= 0 ? '+' : ''}${net}`} sub={`신규 +${newM} · 이탈 −${churnM}`} tone={net > 0 ? 'success' : 'warning'}/>
      <AnKpi label="평균 LTV" value={D.formatMoney(avgLtv)} sub="등록 후 평균 9.4개월 × 320,000" tone="accent"/>
      <AnKpi label="평균 CAC : LTV" value={`1 : ${(avgLtv/avgCAC).toFixed(1)}`} sub={`CAC ${D.formatMoney(avgCAC)} · 회수 평균 1.9개월`} tone="accent"/>
    </div>
  );
}

function AnKpi({ label, value, sub, delta, tone = 'neutral', sparkValues }) {
  const toneColor = tone === 'success' ? 'var(--status-success)'
                  : tone === 'warning' ? 'var(--status-warning)'
                  : tone === 'danger'  ? 'var(--status-danger)'
                  : tone === 'accent'  ? 'var(--accent-default)'
                  : 'var(--text-primary)';
  return (
    <UI.Card className="an-kpi">
      <UI.CardBody>
        <div className="t-micro" style={{ marginBottom: 8, color: 'var(--text-tertiary)' }}>{label}</div>
        <div style={{ fontSize: 22, fontWeight: 700, color: 'var(--text-primary)', letterSpacing: '-0.018em', lineHeight: 1.2 }}>{value}</div>
        {delta && <div style={{ fontSize: 11, color: toneColor, marginTop: 4, fontWeight: 600 }}>{delta}</div>}
        {sub && <div style={{ fontSize: 11, color: 'var(--text-tertiary)', marginTop: 4 }}>{sub}</div>}
        {sparkValues && <div style={{ marginTop: 10 }}><UI.Sparkline values={sparkValues} stroke={toneColor} width={180} height={28}/></div>}
      </UI.CardBody>
    </UI.Card>
  );
}

// ────────────────────────────────────────────────────────────
// Story Card — "지난달 대비 한 줄 요약"
// ────────────────────────────────────────────────────────────
function StoryCard({ trend }) {
  const cur = trend[trend.length - 1];
  const prev = trend[trend.length - 2];
  const revDelta = ((cur.total - prev.total) / prev.total * 100).toFixed(1);
  const newM   = Math.round(cur.new / 280000);
  const churn  = cur.churn;
  return (
    <div className="an-story">
      <div className="an-story__icon"><Icon.Sparkle size={18}/></div>
      <div className="an-story__body">
        <strong style={{ fontSize: 14, color: 'var(--text-primary)' }}>이번 달 한 줄 요약</strong>
        <p style={{ margin: '4px 0 0', fontSize: 13.5, color: 'var(--text-secondary)', lineHeight: 1.6 }}>
          전월 대비 매출 <strong>{revDelta >= 0 ? '+' : ''}{revDelta}%</strong> 성장,
          신규 <strong style={{ color: 'var(--status-success)' }}>+{newM}명</strong>·이탈 <strong style={{ color: 'var(--status-warning)' }}>{churn}명</strong> → 순증 <strong>+{newM - churn}명</strong>.
          가장 효율적인 채널은 <strong style={{ color: 'var(--type-rental)' }}>지인 추천 (전환 75%, 회수 0.8개월)</strong>.
          위험 회원은 <strong style={{ color: 'var(--status-danger)' }}>2명 (최도현·임채린)</strong>이며 갱신 제안이 자동 발송 예정입니다.
        </p>
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// Section 1 · 매출 트렌드
// ────────────────────────────────────────────────────────────
function RevenueSection({ trend }) {
  const [hover, setHover] = useState(null);

  // Stacked bar (recurring + new)
  const max = Math.max(...trend.map(t => t.total));
  const W   = Math.max(680, trend.length * 56);
  const H   = 220;
  const Pad = 32;
  const barW = (W - Pad * 2) / trend.length * 0.65;
  const step = (W - Pad * 2) / trend.length;

  return (
    <div className="grid-2" style={{ alignItems: 'flex-start' }}>
      <UI.Card>
        <UI.CardHeader title="매출 트렌드" subtitle="신규 결제 vs 기존 갱신 분리"
          actions={
            <div className="an-legend">
              <span><span className="dot" style={{ background: 'var(--accent-default)' }}/>기존 갱신</span>
              <span><span className="dot" style={{ background: '#B8761F' }}/>신규</span>
            </div>
          }/>
        <UI.CardBody>
          <div style={{ overflowX: 'auto' }}>
            <svg width={W} height={H + 40} style={{ display: 'block' }}>
              {/* y grid */}
              {[0, 0.25, 0.5, 0.75, 1].map((g, i) => {
                const y = Pad + (H - Pad * 2) * (1 - g);
                return (
                  <g key={i}>
                    <line x1={Pad} x2={W - 8} y1={y} y2={y} stroke="var(--border-default)" strokeDasharray="2 4"/>
                    <text x={4} y={y + 4} fontSize="10" fill="var(--text-tertiary)" fontFamily="JetBrains Mono">
                      {Math.round(max / 1000000 * g)}M
                    </text>
                  </g>
                );
              })}
              {trend.map((m, i) => {
                const x = Pad + step * i + (step - barW) / 2;
                const totalH = (m.total / max) * (H - Pad * 2);
                const recurH = (m.recurring / max) * (H - Pad * 2);
                const newH = totalH - recurH;
                const baseY = H - Pad;
                const last = i === trend.length - 1;
                const isHover = hover === i;
                return (
                  <g key={m.month} onMouseEnter={() => setHover(i)} onMouseLeave={() => setHover(null)}>
                    <rect x={x} y={baseY - recurH} width={barW} height={recurH} fill="var(--accent-default)" opacity={isHover ? 1 : (last ? 0.92 : 0.84)}/>
                    <rect x={x} y={baseY - recurH - newH} width={barW} height={newH} fill="#B8761F" opacity={isHover ? 1 : (last ? 0.92 : 0.84)}/>
                    {last && <rect x={x - 2} y={baseY - totalH - 3} width={barW + 4} height={totalH + 6} fill="none" stroke="var(--text-primary)" strokeWidth="1" strokeDasharray="3 2"/>}
                    {/* x label */}
                    <text x={x + barW / 2} y={H} fontSize="10" fill={isHover ? 'var(--text-primary)' : 'var(--text-tertiary)'} fontFamily="JetBrains Mono" textAnchor="middle">
                      {m.month.slice(5)}
                    </text>
                    {isHover && (
                      <g>
                        <rect x={x + barW / 2 - 60} y={baseY - totalH - 42} width={120} height={36} rx={4} fill="var(--text-primary)"/>
                        <text x={x + barW / 2} y={baseY - totalH - 28} fontSize="10" fontWeight="600" fill="#fff" textAnchor="middle" fontFamily="JetBrains Mono">{(m.total/1000000).toFixed(2)}M</text>
                        <text x={x + barW / 2} y={baseY - totalH - 15} fontSize="9" fill="rgba(255,255,255,0.6)" textAnchor="middle">신규 {(m.new/1000000).toFixed(1)}M · 갱신 {(m.recurring/1000000).toFixed(1)}M</text>
                      </g>
                    )}
                  </g>
                );
              })}
              {/* axis baseline */}
              <line x1={Pad} x2={W - 8} y1={H - Pad} y2={H - Pad} stroke="var(--border-strong)"/>
            </svg>
          </div>
        </UI.CardBody>
      </UI.Card>

      <UI.Card>
        <UI.CardHeader title="이번 달 결제 구성" subtitle="결제 수단별 · MTD"/>
        <UI.CardBody>
          <PaymentBreakdown/>
          <div style={{ marginTop: 16, paddingTop: 16, borderTop: '1px dashed var(--border-default)' }}>
            <div className="t-micro" style={{ marginBottom: 8 }}>전월 동일 시점 대비</div>
            <ProgressLine label="총 매출" cur={D.thisMonthRevenue.total} prev={D.lastMonthRevenue.total}/>
            <ProgressLine label="신규 결제" cur={D.thisMonthRevenue.new} prev={D.lastMonthRevenue.new}/>
            <ProgressLine label="기존 갱신" cur={D.thisMonthRevenue.recurring} prev={D.lastMonthRevenue.recurring}/>
          </div>
        </UI.CardBody>
      </UI.Card>
    </div>
  );
}

function PaymentBreakdown() {
  const total = D.thisMonthRevenue.total;
  // 추정 분포 (mock)
  const breakdown = [
    { label: '계좌이체',     share: 62, color: 'var(--accent-default)' },
    { label: '오프라인 카드', share: 24, color: '#B8761F' },
    { label: '현금',         share: 11, color: '#6B5B95' },
    { label: '간편결제',     share: 3,  color: '#5C5A54' },
  ];
  return (
    <div>
      <div style={{ display: 'flex', height: 24, borderRadius: 4, overflow: 'hidden', marginBottom: 12, border: '1px solid var(--border-default)' }}>
        {breakdown.map(b => (
          <div key={b.label} style={{ width: `${b.share}%`, background: b.color, position: 'relative' }} title={`${b.label} · ${b.share}%`}/>
        ))}
      </div>
      {breakdown.map(b => (
        <div key={b.label} style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 12.5, padding: '4px 0', borderBottom: '1px dashed var(--border-default)' }}>
          <span className="dot" style={{ background: b.color, width: 8, height: 8, borderRadius: 99 }}/>
          <span style={{ flex: 1 }}>{b.label}</span>
          <span className="t-mono" style={{ color: 'var(--text-tertiary)', fontSize: 11 }}>{b.share}%</span>
          <span className="t-mono" style={{ minWidth: 90, textAlign: 'right' }}>{D.formatMoney(Math.round(total * b.share / 100))}</span>
        </div>
      ))}
    </div>
  );
}

function ProgressLine({ label, cur, prev }) {
  const ratio = Math.min(1.2, cur / prev);
  const isUp = cur >= prev;
  return (
    <div style={{ marginBottom: 10 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12, marginBottom: 4 }}>
        <span>{label}</span>
        <span className="t-mono" style={{ color: isUp ? 'var(--status-success)' : 'var(--status-warning)' }}>
          {isUp ? '▲' : '▼'} {Math.abs(((cur - prev) / prev) * 100).toFixed(1)}%
        </span>
      </div>
      <div style={{ height: 6, background: 'var(--bg-inset)', borderRadius: 99, overflow: 'hidden', position: 'relative' }}>
        <div style={{ height: '100%', width: `${Math.min(100, ratio * 100)}%`, background: isUp ? 'var(--accent-default)' : 'var(--status-warning)', borderRadius: 99 }}/>
        <div style={{ position: 'absolute', top: 0, left: '100%', transform: 'translateX(-1px)', height: '100%', width: 1, background: 'var(--text-tertiary)' }} title="전월 동기"/>
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// Section 2 · Funnel
// ────────────────────────────────────────────────────────────
function FunnelSection({ onOpenMember }) {
  const f = D.memberFunnel;
  const maxCount = f.steps[0].count;
  return (
    <div className="grid-2" style={{ alignItems: 'flex-start' }}>
      <UI.Card>
        <UI.CardHeader title="회원 Funnel" subtitle={f.cohortDescription}
          actions={<UI.Button variant="ghost" size="sm" icon={Icon.Send} onClick={() => window.toast && window.toast('CSV로 내보내기 완료', { tone: 'success' })}>CSV</UI.Button>}/>
        <UI.CardBody>
          {f.steps.map((s, i) => {
            const width = (s.count / maxCount) * 100;
            const dropRate = i > 0 ? ((f.steps[i - 1].count - s.count) / f.steps[i - 1].count * 100).toFixed(0) : 0;
            return (
              <div key={s.id} className="fnl-row">
                <div className="fnl-label">{s.label}</div>
                <div className="fnl-bar" style={{ width: `${width}%`, background: i === 0 ? 'var(--accent-default)' : i === 1 ? '#3D6B53' : i === 2 ? '#587E68' : i === 3 ? '#B8761F' : i === 4 ? '#6B5B95' : '#5C5A54' }}>
                  <span>{s.count}</span>
                  <span style={{ opacity: 0.7 }}>· {s.rate}%</span>
                </div>
                {i > 0 && (
                  <div className="fnl-drop">
                    <span>↘ {dropRate}% 이탈</span>
                  </div>
                )}
              </div>
            );
          })}
          <div style={{ marginTop: 16, padding: 12, background: 'var(--bg-canvas)', borderRadius: 8, fontSize: 12.5, lineHeight: 1.6, color: 'var(--text-secondary)' }}>
            <strong style={{ color: 'var(--text-primary)' }}>관찰.</strong> 상담 → 첫 등록 전환에서 가장 큰 손실(<strong>31%</strong>). D+3 무응답 처리 자동화(I1)와 등록 직후 환영 메시지가 직접적인 개선 지점입니다.
          </div>
        </UI.CardBody>
      </UI.Card>

      <UI.Card>
        <UI.CardHeader title="단계별 평균 소요" subtitle="중앙값 — 상담 → 다음 단계"/>
        <UI.CardBody>
          <FunnelDuration/>
          <div style={{ marginTop: 16 }}>
            <div className="t-micro" style={{ marginBottom: 8 }}>이탈 회원 단계 분포 (지난 12개월)</div>
            <CohortStacked/>
          </div>
        </UI.CardBody>
      </UI.Card>
    </div>
  );
}

function FunnelDuration() {
  const rows = [
    { from: '상담 신청', to: '상담 진행', avg: '2.4일' },
    { from: '상담 진행', to: '첫 등록',   avg: '5.8일' },
    { from: '첫 등록',  to: '첫 갱신',   avg: '11주' },
    { from: '첫 갱신',  to: '6개월 유지', avg: '13주' },
  ];
  return (
    <div>
      {rows.map((r, i) => (
        <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 0', borderBottom: '1px dashed var(--border-default)' }}>
          <span style={{ fontSize: 12, color: 'var(--text-secondary)', flex: 1 }}>{r.from} → <strong style={{ color: 'var(--text-primary)' }}>{r.to}</strong></span>
          <span className="t-mono" style={{ fontSize: 13, fontWeight: 600 }}>{r.avg}</span>
        </div>
      ))}
    </div>
  );
}

function CohortStacked() {
  // 이탈 시점 분포: 첫 등록 전 / 첫 갱신 전 / 6개월 내 / 6개월~1년 / 1년+
  const buckets = [
    { label: '등록 전 이탈', share: 28, color: '#B23A3A' },
    { label: '첫 갱신 전',   share: 24, color: '#B8761F' },
    { label: '6개월 내',     share: 22, color: '#6B5B95' },
    { label: '6m–1y',        share: 14, color: '#1F4D3A' },
    { label: '1년+',         share: 12, color: '#5C5A54' },
  ];
  return (
    <div>
      <div style={{ display: 'flex', height: 20, borderRadius: 4, overflow: 'hidden', border: '1px solid var(--border-default)' }}>
        {buckets.map(b => <div key={b.label} title={`${b.label} ${b.share}%`} style={{ width: `${b.share}%`, background: b.color }}/>)}
      </div>
      <div style={{ marginTop: 8 }}>
        {buckets.map(b => (
          <div key={b.label} style={{ display: 'flex', gap: 6, alignItems: 'center', fontSize: 11.5, padding: '3px 0' }}>
            <span className="dot" style={{ background: b.color, width: 8, height: 8, borderRadius: 99 }}/>
            <span style={{ flex: 1 }}>{b.label}</span>
            <span className="t-mono">{b.share}%</span>
          </div>
        ))}
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// Section 3 · 채널 ROI (F9)
// ────────────────────────────────────────────────────────────
function ChannelSection() {
  const totalSpend  = D.channelROI.reduce((s, c) => s + c.adSpend, 0);
  const totalEnroll = D.channelROI.reduce((s, c) => s + c.enrolled, 0);
  return (
    <UI.Card>
      <UI.CardHeader title="유입 채널 ROI" subtitle={`광고비 ${D.formatMoney(totalSpend)} · 등록 전환 ${totalEnroll}명 · 평균 CAC ${D.formatMoney(Math.round(totalSpend / totalEnroll))}`}
        actions={
          <div style={{ display: 'flex', gap: 6 }}>
            <UI.Button variant="ghost" size="sm" icon={Icon.Edit} onClick={() => window.toast && window.toast('UTM 캠페인 사전 편집 — 설정으로 이동')}>UTM 편집</UI.Button>
            <UI.Button variant="ghost" size="sm" icon={Icon.Receipt} onClick={() => window.toast && window.toast('채널별 CSV 내보내기 완료', { tone: 'success' })}>CSV</UI.Button>
          </div>
        }/>
      <UI.CardBody flush>
        <table className="tbl tbl--zebra">
          <thead>
            <tr>
              <th style={{ width: 130 }}>채널</th>
              <th>상담 / 등록</th>
              <th>전환율</th>
              <th>광고비</th>
              <th>CAC</th>
              <th>평균 LTV</th>
              <th>회수 기간</th>
              <th>CAC : LTV</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {D.channelROI.map(c => {
              const ratio = c.cac > 0 ? (c.ltvAvg / c.cac).toFixed(1) : '∞';
              const healthy = c.cac === 0 ? 'ok' : (c.ltvAvg / c.cac >= 5 ? 'ok' : c.ltvAvg / c.cac >= 3 ? 'warn' : 'bad');
              return (
                <tr key={c.id}>
                  <td>
                    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
                      <span className="dot" style={{ background: c.color, width: 8, height: 8, borderRadius: 99 }}/>
                      <strong>{c.label}</strong>
                    </span>
                  </td>
                  <td>
                    <span className="t-mono">{c.leads} → {c.enrolled}</span>
                    <span style={{ marginLeft: 6, fontSize: 10, color: 'var(--text-tertiary)' }}>명</span>
                  </td>
                  <td>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                      <div style={{ flex: 1, maxWidth: 80, height: 6, background: 'var(--bg-inset)', borderRadius: 99, overflow: 'hidden' }}>
                        <div style={{ height: '100%', width: `${c.conversionRate}%`, background: c.color }}/>
                      </div>
                      <span className="t-mono" style={{ minWidth: 36 }}>{c.conversionRate}%</span>
                    </div>
                  </td>
                  <td className="t-mono">{c.adSpend > 0 ? D.formatMoney(c.adSpend) : '—'}</td>
                  <td className="t-mono">{c.cac > 0 ? D.formatMoney(c.cac) : '—'}</td>
                  <td className="t-mono">{D.formatMoney(c.ltvAvg)}</td>
                  <td>
                    <span className="t-mono" style={{ color: c.payback > 0 && c.payback < 1.5 ? 'var(--status-success)' : c.payback < 2.5 ? 'var(--text-primary)' : 'var(--status-warning)' }}>
                      {c.payback > 0 ? c.payback + '개월' : '—'}
                    </span>
                  </td>
                  <td>
                    <span style={{
                      padding: '2px 8px', borderRadius: 99, fontSize: 11, fontWeight: 600,
                      background: healthy === 'ok' ? 'var(--status-success-bg)' : healthy === 'warn' ? 'var(--type-rental-bg)' : 'var(--status-danger-bg)',
                      color: healthy === 'ok' ? 'var(--status-success)' : healthy === 'warn' ? 'var(--type-rental)' : 'var(--status-danger)',
                    }}>
                      1 : {ratio}
                    </span>
                  </td>
                  <td style={{ textAlign: 'right' }}>
                    <UI.Button size="sm" variant="ghost" onClick={() => window.toast && window.toast(`${c.label} 광고 캠페인 상세는 다음 분기 합류 예정`)}>상세</UI.Button>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </UI.CardBody>
    </UI.Card>
  );
}

// ────────────────────────────────────────────────────────────
// Section 4 · 패스 분석
// ────────────────────────────────────────────────────────────
function PassSection() {
  return (
    <div className="grid-2" style={{ alignItems: 'flex-start' }}>
      <UI.Card>
        <UI.CardHeader title="패스 종류별 매출 / 활동"/>
        <UI.CardBody flush>
          <table className="tbl tbl--zebra">
            <thead>
              <tr>
                <th>패스</th>
                <th>단가</th>
                <th>활동</th>
                <th>월매출</th>
                <th>소진</th>
                <th>갱신율</th>
              </tr>
            </thead>
            <tbody>
              {D.passTypePerformance.map(p => (
                <tr key={p.id}>
                  <td><strong>{p.label}</strong></td>
                  <td className="t-mono">{D.formatMoney(p.priceKRW)}</td>
                  <td className="t-mono">{p.active}명</td>
                  <td className="t-mono">{D.formatMoney(p.monthlyRevenue)}</td>
                  <td>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                      <span className="t-mono" style={{ fontSize: 11 }}>{p.avgConsumptionWeeks}주</span>
                    </div>
                  </td>
                  <td>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                      <div style={{ flex: 1, height: 4, background: 'var(--bg-inset)', borderRadius: 99 }}>
                        <div style={{ height: '100%', width: `${p.renewalRate}%`, background: p.renewalRate >= 80 ? 'var(--status-success)' : p.renewalRate >= 70 ? 'var(--type-rental)' : 'var(--status-danger)', borderRadius: 99 }}/>
                      </div>
                      <span className="t-mono" style={{ minWidth: 32, fontSize: 11 }}>{p.renewalRate}%</span>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </UI.CardBody>
      </UI.Card>

      <UI.Card>
        <UI.CardHeader title="갱신율 vs 단가" subtitle="비싼 패스일수록 갱신율도 함께 오르는 경향"/>
        <UI.CardBody>
          <PassScatter/>
          <div style={{ marginTop: 14, padding: 12, background: 'var(--bg-canvas)', borderRadius: 8, fontSize: 12.5, lineHeight: 1.6, color: 'var(--text-secondary)' }}>
            <strong style={{ color: 'var(--text-primary)' }}>인사이트.</strong> 24회 패스는 단가도 가장 높지만 갱신율 <strong>88%</strong>로 가장 안정적. 12회 SESSION에서 16회로 업셀하면 갱신율이 6%p 상승하는 패턴. 신규 회원의 첫 패스 권장 = <strong>16회</strong>.
          </div>
        </UI.CardBody>
      </UI.Card>
    </div>
  );
}

function PassScatter() {
  const data = D.passTypePerformance;
  const W = 320, H = 200, Pad = 32;
  const xMax = 400000, yMax = 100;
  return (
    <svg viewBox={`0 0 ${W} ${H}`} style={{ width: '100%', height: 200 }}>
      {/* axes */}
      <line x1={Pad} x2={W - 8} y1={H - Pad} y2={H - Pad} stroke="var(--border-strong)"/>
      <line x1={Pad} x2={Pad} y1={8} y2={H - Pad} stroke="var(--border-strong)"/>
      {/* y labels */}
      {[0, 50, 100].map(v => {
        const y = (H - Pad) - (v / yMax) * (H - Pad - 8);
        return (
          <g key={v}>
            <text x={4} y={y + 3} fontSize="9" fill="var(--text-tertiary)" fontFamily="JetBrains Mono">{v}%</text>
            <line x1={Pad} x2={W - 8} y1={y} y2={y} stroke="var(--border-default)" strokeDasharray="2 4"/>
          </g>
        );
      })}
      <text x={W / 2} y={H - 8} fontSize="9" fill="var(--text-tertiary)" textAnchor="middle">단가 →</text>
      <text x={6} y={14} fontSize="9" fill="var(--text-tertiary)">갱신율</text>
      {data.map(p => {
        const x = Pad + (p.priceKRW / xMax) * (W - Pad - 8);
        const y = (H - Pad) - (p.renewalRate / yMax) * (H - Pad - 8);
        const r = 6 + Math.sqrt(p.active);
        return (
          <g key={p.id}>
            <circle cx={x} cy={y} r={r} fill="var(--accent-default)" opacity="0.18"/>
            <circle cx={x} cy={y} r={4} fill="var(--accent-default)"/>
            <text x={x + r + 4} y={y + 3} fontSize="9" fontFamily="JetBrains Mono" fill="var(--text-secondary)">{p.label.replace('SESSION', '').replace('PERIOD', '월')}</text>
          </g>
        );
      })}
    </svg>
  );
}

// ────────────────────────────────────────────────────────────
// Section 5 · 강사 기여
// ────────────────────────────────────────────────────────────
function TeacherContribSection({ onNav }) {
  const total = Object.values(D.teacherStats).reduce((s, t) => s + t.thisMonth.revenueAttributed, 0);
  return (
    <UI.Card>
      <UI.CardHeader title="강사별 매출 기여 · 이번 달"
        subtitle="담당 회원의 결제 합계 기준 — 정산은 별도 계산"
        actions={<UI.Button size="sm" variant="ghost" icon={Icon.ChevRight} onClick={() => onNav && onNav('instructors')}>강사 운영 페이지</UI.Button>}/>
      <UI.CardBody>
        {D.teachers.map(t => {
          const stats = D.teacherStats[t.id];
          const share = (stats.thisMonth.revenueAttributed / total * 100).toFixed(1);
          const delta = stats.thisMonth.revenueAttributed - stats.lastMonth.revenueAttributed;
          return (
            <div key={t.id} className="contrib-row" onClick={() => onNav && onNav({ view: 'instructors', teacherId: t.id })}>
              <div className="contrib-avatar" style={{ background: t.color }}>{t.initials}</div>
              <div className="contrib-info">
                <strong>{t.name}</strong>
                <span style={{ color: 'var(--text-tertiary)', fontSize: 11 }}>{stats.thisMonth.members}명 · 출석률 {stats.thisMonth.avgAttendanceRate}%</span>
              </div>
              <div className="contrib-bar">
                <div className="contrib-bar__track">
                  <div className="contrib-bar__fill" style={{ width: `${share}%`, background: t.color }}/>
                </div>
                <span className="t-mono" style={{ fontSize: 11, color: 'var(--text-tertiary)' }}>{share}%</span>
              </div>
              <div className="contrib-amt">
                <span className="t-mono" style={{ fontWeight: 600 }}>{D.formatMoney(stats.thisMonth.revenueAttributed)}</span>
                <span className="t-mono" style={{ fontSize: 11, color: delta >= 0 ? 'var(--status-success)' : 'var(--status-warning)' }}>
                  {delta >= 0 ? '▲' : '▼'} {D.formatMoney(Math.abs(delta))}
                </span>
              </div>
            </div>
          );
        })}
      </UI.CardBody>
    </UI.Card>
  );
}

// ────────────────────────────────────────────────────────────
// Section 6 · 이탈 분석
// ────────────────────────────────────────────────────────────
function ChurnSection({ onOpenMember }) {
  return (
    <div className="grid-2" style={{ alignItems: 'flex-start' }}>
      <UI.Card>
        <UI.CardHeader title="이탈 사유 분포" subtitle="최근 12개월 퇴원 12명"/>
        <UI.CardBody>
          <DonutChurn/>
          <div style={{ marginTop: 14 }}>
            {D.churnReasons.map((r, i) => (
              <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '5px 0', borderBottom: '1px dashed var(--border-default)' }}>
                <span className="dot" style={{ background: donutColor(i), width: 8, height: 8, borderRadius: 99 }}/>
                <span style={{ fontSize: 12.5, flex: 1 }}>{r.reason}</span>
                <span className="t-mono" style={{ fontSize: 11, color: 'var(--text-tertiary)' }}>{r.count}명</span>
                <span className="t-mono" style={{ fontSize: 11, minWidth: 32, textAlign: 'right' }}>{r.share}%</span>
              </div>
            ))}
          </div>
        </UI.CardBody>
      </UI.Card>

      <UI.Card>
        <UI.CardHeader title="이탈 직전 신호 사후 분석"
          subtitle="퇴원 회원의 마지막 일지 키워드"
          actions={<UI.Button size="sm" variant="ghost" onClick={() => window.toast && window.toast('이탈 회고 리포트 PDF 생성 완료', { tone: 'success' })}>회고 PDF</UI.Button>}/>
        <UI.CardBody flush>
          {D.churnRetrospective.map(r => {
            const m = D.getMember(r.memberId);
            return (
              <div key={r.memberId} className="churn-row" onClick={() => onOpenMember && onOpenMember(r.memberId)}>
                <div>
                  <strong>{m.name}</strong>
                  <span style={{ marginLeft: 6, fontSize: 11, color: 'var(--text-tertiary)' }}>· {r.withdrawnAt}</span>
                </div>
                <div style={{ fontSize: 12, color: 'var(--text-secondary)', margin: '4px 0 6px' }}>{r.reason}</div>
                <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>
                  {r.lastJournalKeywords.map(k => (
                    <span key={k} className="kw-chip">{k}</span>
                  ))}
                  <span style={{ marginLeft: 'auto', fontSize: 10.5, color: 'var(--text-tertiary)' }}>위험 점수 {r.score}</span>
                </div>
                <div style={{ fontSize: 11, color: 'var(--text-tertiary)', marginTop: 4 }}>대응: {r.action}</div>
              </div>
            );
          })}
        </UI.CardBody>
      </UI.Card>
    </div>
  );
}

function DonutChurn() {
  const data = D.churnReasons;
  const cx = 100, cy = 100, r = 70, sr = 44;
  let acc = 0;
  return (
    <svg viewBox="0 0 200 200" style={{ width: 200, height: 200, display: 'block', margin: '0 auto' }}>
      {data.map((d, i) => {
        const startA = acc * Math.PI * 2 / 100 - Math.PI / 2;
        acc += d.share;
        const endA = acc * Math.PI * 2 / 100 - Math.PI / 2;
        const large = d.share > 50 ? 1 : 0;
        const x1 = cx + r * Math.cos(startA), y1 = cy + r * Math.sin(startA);
        const x2 = cx + r * Math.cos(endA),   y2 = cy + r * Math.sin(endA);
        const x3 = cx + sr * Math.cos(endA),  y3 = cy + sr * Math.sin(endA);
        const x4 = cx + sr * Math.cos(startA),y4 = cy + sr * Math.sin(startA);
        const path = `M ${x1} ${y1} A ${r} ${r} 0 ${large} 1 ${x2} ${y2} L ${x3} ${y3} A ${sr} ${sr} 0 ${large} 0 ${x4} ${y4} Z`;
        return <path key={i} d={path} fill={donutColor(i)}/>;
      })}
      <text x="100" y="96" textAnchor="middle" fontSize="22" fontWeight="700" fontFamily="JetBrains Mono">12</text>
      <text x="100" y="116" textAnchor="middle" fontSize="10" fill="var(--text-tertiary)">12개월 누적</text>
    </svg>
  );
}
function donutColor(i) {
  const palette = ['#B23A3A', '#B8761F', '#6B5B95', '#1F4D3A', '#5C5A54', '#8A8780'];
  return palette[i % palette.length];
}

// ────────────────────────────────────────────────────────────
// Section 7 · 추천 / 리뷰
// ────────────────────────────────────────────────────────────
function ReferralSection({ onOpenMember }) {
  return (
    <div className="grid-2" style={{ alignItems: 'flex-start' }}>
      <UI.Card>
        <UI.CardHeader title="추천 코드" subtitle="회원당 고유 코드 · 등록 시 양쪽 30,000원 차감"
          actions={<UI.Button size="sm" icon={Icon.Plus} onClick={() => window.toast && window.toast('새 추천 코드 발급 — 회원 상세에서 공유 링크 확인', { tone: 'success' })}>코드 발급</UI.Button>}/>
        <UI.CardBody flush>
          <table className="tbl tbl--zebra">
            <thead>
              <tr><th>코드</th><th>오너</th><th>사용</th><th>전환율</th><th>지급액</th><th></th></tr>
            </thead>
            <tbody>
              {D.referralCodes.map(c => {
                const m = D.getMember(c.ownerMemberId);
                return (
                  <tr key={c.code} onClick={() => onOpenMember && onOpenMember(c.ownerMemberId)} style={{ cursor: 'pointer' }}>
                    <td><span className="t-mono" style={{ fontWeight: 700, fontSize: 13 }}>{c.code}</span></td>
                    <td><strong>{m.name}</strong></td>
                    <td className="t-mono">{c.uses}회</td>
                    <td className="t-mono">{c.conversionRate}%</td>
                    <td className="t-mono">{D.formatMoney(c.rewardPaid)}</td>
                    <td style={{ textAlign: 'right' }}>
                      <UI.Button size="sm" variant="ghost" onClick={(e) => { e.stopPropagation(); window.toast && window.toast(`${m.name}님께 코드 ${c.code} 공유 링크 알림톡 발송 완료`, { tone: 'success' }); }}>알림</UI.Button>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </UI.CardBody>
      </UI.Card>

      <UI.Card>
        <UI.CardHeader title="리뷰 요청" subtitle="3개월 이상 유지 회원에게 학원장이 직접 발송"
          actions={<UI.Button size="sm" icon={Icon.Send} onClick={() => window.toast && window.toast('대기중 2건 일괄 발송 완료', { tone: 'success' })}>대기 일괄</UI.Button>}/>
        <UI.CardBody flush>
          {D.reviewRequests.map(r => {
            const m = D.getMember(r.memberId);
            const sent = r.status !== 'pending';
            return (
              <div key={r.id} className="rev-row">
                <UI.Avatar name={m.name}/>
                <div style={{ flex: 1 }}>
                  <strong>{m.name}</strong>
                  <div style={{ fontSize: 11, color: 'var(--text-tertiary)' }}>{r.platform} · {sent ? '발송 ' + r.sentAt : '대기중'}</div>
                </div>
                <UI.Badge tone={r.status === 'reviewed' ? 'success' : r.status === 'sent' ? 'accent' : 'neutral'}>
                  {r.status === 'reviewed' ? '리뷰 작성' : r.status === 'sent' ? '클릭' : '대기'}
                </UI.Badge>
                <UI.Button size="sm" variant={sent ? 'ghost' : 'primary'} onClick={() => window.toast && window.toast(`${m.name}님께 ${r.platform} 리뷰 링크 알림톡 발송`, { tone: 'success' })}>
                  {sent ? '재발송' : '발송'}
                </UI.Button>
              </div>
            );
          })}
        </UI.CardBody>
      </UI.Card>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// Sub UI
// ────────────────────────────────────────────────────────────
function RangeToggle({ value, onChange }) {
  return (
    <div className="seg-toggle">
      {RANGES.map(r => (
        <button key={r.id} className={`seg-toggle__btn ${value === r.id ? 'is-active' : ''}`} onClick={() => onChange(r.id)}>
          {r.label}
        </button>
      ))}
    </div>
  );
}

function ExportModal({ open, onClose }) {
  const [fmt, setFmt] = useState('pdf');
  const [scope, setScope] = useState('this-month');
  return (
    <UI.Modal open={open} onClose={onClose} title="월간 리포트 내보내기" width={520}
      footer={
        <React.Fragment>
          <UI.Button variant="ghost" onClick={onClose}>취소</UI.Button>
          <UI.Button variant="primary" icon={Icon.Send} onClick={() => { onClose(); window.toast && window.toast(`${scope === 'this-month' ? '2025-11' : '2025-10'} 리포트 ${fmt.toUpperCase()} 생성 완료 · 이메일 발송`, { tone: 'success' }); }}>생성 + 발송</UI.Button>
        </React.Fragment>
      }>
      <div style={{ display: 'grid', gap: 14 }}>
        <div>
          <div className="t-micro" style={{ marginBottom: 8 }}>대상 기간</div>
          <div style={{ display: 'flex', gap: 6 }}>
            {[{id: 'this-month', label: '이번 달'},{id: 'last-month', label: '지난 달'},{id: 'last-quarter', label: '직전 분기'}].map(o => (
              <button key={o.id} className={`pill ${scope === o.id ? 'is-active' : ''}`} onClick={() => setScope(o.id)}>{o.label}</button>
            ))}
          </div>
        </div>
        <div>
          <div className="t-micro" style={{ marginBottom: 8 }}>포맷</div>
          <div style={{ display: 'flex', gap: 6 }}>
            {[{id: 'pdf', label: 'PDF'},{id: 'xlsx', label: 'Excel'},{id: 'csv', label: 'CSV'}].map(o => (
              <button key={o.id} className={`pill ${fmt === o.id ? 'is-active' : ''}`} onClick={() => setFmt(o.id)}>{o.label}</button>
            ))}
          </div>
        </div>
        <div style={{ background: 'var(--bg-canvas)', padding: 12, borderRadius: 8, fontSize: 12, color: 'var(--text-secondary)', lineHeight: 1.6 }}>
          포함: 매출 트렌드 · Funnel · 채널 ROI · 패스 분석 · 강사별 기여 · 이탈 사후 분석<br/>
          수신 이메일: <strong>academy@songyui.kr</strong> (설정에서 변경)
        </div>
      </div>
    </UI.Modal>
  );
}

// ────────────────────────────────────────────────────────────
// Helpers
// ────────────────────────────────────────────────────────────
function pct(cur, prev) {
  const d = ((cur - prev) / prev * 100).toFixed(1);
  return (d >= 0 ? '▲ +' : '▼ ') + d + '%';
}

window.AnalyticsPage = { AnalyticsPage };
})();
