// admin-pages2.jsx — additional 8 admin pages
const C2 = window.ADMIN_COLORS;
const { Card, StatCard, Pill, Btn, Input, Select, Tabs } = window.AdminShell;

// ===== shared table =====
function Table2({ columns, rows, empty = '데이터 없음' }) {
  return (
    <div style={{ overflowX: 'auto', border: `1px solid ${C2.border}`, borderRadius: 10, background: C2.panel }}>
      <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 13 }}>
        <thead>
          <tr style={{ background: C2.primarySofter }}>
            {columns.map((col, i) => (
              <th key={i} style={{
                textAlign: col.align || 'left',
                padding: '10px 14px',
                fontSize: 11, fontWeight: 700, letterSpacing: '0.04em',
                color: C2.muted, textTransform: 'uppercase',
                borderBottom: `1px solid ${C2.border}`,
                whiteSpace: 'nowrap', width: col.width,
              }}>{col.header}</th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows.length === 0 ? (
            <tr><td colSpan={columns.length} style={{ padding: '60px 20px', textAlign: 'center', color: C2.faint, fontSize: 13 }}>{empty}</td></tr>
          ) : rows.map((row, i) => (
            <tr key={i} style={{ borderBottom: i === rows.length - 1 ? 'none' : `1px solid ${C2.border}` }}
              onMouseEnter={e => e.currentTarget.style.background = C2.primarySofter}
              onMouseLeave={e => e.currentTarget.style.background = ''}
            >
              {columns.map((col, j) => (
                <td key={j} style={{
                  padding: '12px 14px', textAlign: col.align || 'left',
                  color: col.muted ? C2.muted : C2.text,
                  fontFamily: col.mono ? "'JetBrains Mono', ui-monospace, monospace" : undefined,
                  fontSize: col.mono ? 12.5 : 13, verticalAlign: 'middle',
                }}>{col.render ? col.render(row, i) : row[col.key]}</td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

// ============================================================
// 1. AI COST
// ============================================================
function AICost() {
  const [range, setRange] = React.useState('30d');
  const todayCap = 50;
  const todayUsed = 12.34;
  const pct = (todayUsed / todayCap) * 100;

  const stats = [
    { label: '총 비용', value: '$184.22', sub: '30일 누적' },
    { label: '총 호출', value: '5,841', sub: '평균 195/일' },
    { label: '입력 토큰', value: '4.21M', sub: 'p90 입력 8.4k' },
    { label: '출력 토큰', value: '1.86M', sub: 'p90 출력 3.1k' },
  ];

  const models = [
    { model: 'claude-sonnet-4', calls: 3214, inTok: '2.84M', outTok: '1.21M', cost: '$108.42', avg: '$0.0337' },
    { model: 'claude-haiku-4-5', calls: 2104, inTok: '1.12M', outTok: '0.51M', cost: '$48.91', avg: '$0.0232' },
    { model: 'gpt-5-mini', calls: 412, inTok: '0.18M', outTok: '0.09M', cost: '$18.04', avg: '$0.0438' },
    { model: 'gemini-2.5-pro', calls: 111, inTok: '0.07M', outTok: '0.05M', cost: '$8.85', avg: '$0.0797' },
  ];
  const expensive = [
    { time: '2026.5.4. 11:03', user: 'memnyan35@gmail.com', model: 'claude-sonnet-4', tokens: '14,210', cost: '$0.281', reason: 'Long context · AAPL deep' },
    { time: '2026.5.4. 09:47', user: 'mybj0610@gmail.com', model: 'claude-sonnet-4', tokens: '11,802', cost: '$0.234', reason: 'NVDA · multi-source' },
    { time: '2026.5.3. 22:18', user: 'memnyan35@gmail.com', model: 'gpt-5-mini', tokens: '8,401', cost: '$0.198', reason: 'Retry × 3' },
    { time: '2026.5.3. 14:05', user: '2261071@pcu.ac.kr', model: 'claude-sonnet-4', tokens: '7,998', cost: '$0.158', reason: 'TSLA · vibe_check' },
  ];

  return (
    <>
      {/* 오늘 비용 + 게이지 */}
      <Card padding={0} style={{ marginBottom: 12 }}>
        <div style={{ padding: '16px 20px', borderBottom: `1px solid ${C2.border}`, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <div>
            <div style={{ fontSize: 11, fontWeight: 700, color: C2.muted, letterSpacing: '0.04em', textTransform: 'uppercase' }}>오늘 비용 (KST)</div>
            <div className="mono" style={{ fontSize: 32, fontWeight: 700, color: C2.text, marginTop: 6, letterSpacing: '-0.02em' }}>${todayUsed.toFixed(4)}</div>
          </div>
          <div style={{ textAlign: 'right' }}>
            <div className="mono" style={{ fontSize: 11, color: C2.faint }}>일한도 ${todayCap.toFixed(2)}</div>
            <div className="mono" style={{ fontSize: 13, color: pct > 80 ? C2.bad : C2.muted, marginTop: 4, fontWeight: 600 }}>{pct.toFixed(1)}% 사용</div>
          </div>
        </div>
        <div style={{ padding: '14px 20px' }}>
          <div style={{ height: 10, background: C2.primarySofter, borderRadius: 5, overflow: 'hidden' }}>
            <div style={{ width: `${pct}%`, height: '100%', background: pct > 80 ? C2.bad : C2.primary, borderRadius: 5 }}/>
          </div>
        </div>
      </Card>

      {/* 기간 토글 */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 12 }}>
        <span style={{ fontSize: 11, color: C2.muted, fontWeight: 700, letterSpacing: '0.04em', textTransform: 'uppercase' }}>기간</span>
        <Tabs value={range} onChange={setRange} tabs={[
          { value: '7d', label: '7일' }, { value: '30d', label: '30일' }, { value: '90d', label: '90일' },
        ]}/>
      </div>

      {/* KPI 4개 */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: 12, marginBottom: 12 }}>
        {stats.map((s, i) => <StatCard key={i} {...s}/>)}
      </div>

      {/* 모델별 사용 */}
      <div style={{ fontSize: 11, fontWeight: 700, color: C2.muted, letterSpacing: '0.04em', textTransform: 'uppercase', margin: '20px 0 10px' }}>모델별 사용</div>
      <Table2
        columns={[
          { header: '모델', mono: true, render: r => <span style={{ color: C2.primary, fontWeight: 600 }}>{r.model}</span> },
          { header: '호출 수', mono: true, align: 'right' },
          { header: '입력 토큰', mono: true, align: 'right', render: r => r.inTok },
          { header: '출력 토큰', mono: true, align: 'right', render: r => r.outTok },
          { header: '비용 (USD)', mono: true, align: 'right', render: r => <span style={{ fontWeight: 600 }}>{r.cost}</span> },
          { header: '건당 평균', mono: true, align: 'right', render: r => <span style={{ color: C2.muted }}>{r.avg}</span> },
        ]}
        rows={models.map(m => ({ ...m, '호출 수': m.calls.toLocaleString() }))}
      />

      {/* 고비용 호출 */}
      <div style={{ fontSize: 11, fontWeight: 700, color: C2.muted, letterSpacing: '0.04em', textTransform: 'uppercase', margin: '20px 0 10px' }}>최근 고비용 호출</div>
      <Table2
        columns={[
          { header: '시각', mono: true, render: r => <span style={{ fontSize: 11.5, color: C2.muted }}>{r.time}</span> },
          { header: '유저', mono: true, render: r => <span style={{ color: C2.primary, fontWeight: 600 }}>{r.user}</span> },
          { header: '모델', render: r => <Pill tone="mono" size="xs">{r.model}</Pill> },
          { header: '토큰', mono: true, align: 'right' },
          { header: '비용', mono: true, align: 'right', render: r => <span style={{ fontWeight: 600 }}>{r.cost}</span> },
          { header: '사유', render: r => <span style={{ color: C2.muted, fontSize: 12 }}>{r.reason}</span> },
        ]}
        rows={expensive}
      />
    </>
  );
}

// ============================================================
// 2. REVIEW QUEUE
// ============================================================
function ReviewQueue() {
  const [filter, setFilter] = React.useState('all');
  const queue = [
    { sev: 'critical', type: 'abuse_burst', user: 'unknown@temp-mail.org', detected: '2026.5.4. 13:42', data: '5분간 회원가입 12건 (IP 동일)', status: 'pending' },
    { sev: 'high', type: 'cost_spike', user: 'memnyan35@gmail.com', detected: '2026.5.4. 11:03', data: '단일 세션 $0.84 (평균 12배)', status: 'pending' },
    { sev: 'high', type: 'judge_error', user: 'system', detected: '2026.5.4. 09:21', data: 'claude-sonnet-4 timeout × 8 (5분)', status: 'pending' },
    { sev: 'medium', type: 'feedback_low', user: 'rina@studio.io', detected: '2026.5.3. 22:11', data: 'Judge 응답에 1점 (3회 연속)', status: 'pending' },
    { sev: 'low', type: 'whitelist_unused', user: 'system', detected: '2026.5.3. 00:00', data: '14일째 미사용 항목 3건', status: 'pending' },
  ];
  const filtered = filter === 'all' ? queue : queue.filter(q => q.sev === filter);
  const sevPill = (s) => {
    const map = { critical: { tone: 'bad', label: 'Critical' }, high: { tone: 'warn', label: 'High' }, medium: { tone: 'primary', label: 'Medium' }, low: { tone: 'mono', label: 'Low' } };
    const m = map[s];
    return <Pill tone={m.tone} size="xs">● {m.label}</Pill>;
  };

  return (
    <>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12, flexWrap: 'wrap', gap: 10 }}>
        <Tabs value={filter} onChange={setFilter} tabs={[
          { value: 'all', label: '전체', count: queue.length },
          { value: 'critical', label: 'Critical', count: queue.filter(q => q.sev === 'critical').length },
          { value: 'high', label: 'High', count: queue.filter(q => q.sev === 'high').length },
          { value: 'medium', label: 'Medium', count: queue.filter(q => q.sev === 'medium').length },
          { value: 'low', label: 'Low', count: queue.filter(q => q.sev === 'low').length },
        ]}/>
        <div style={{ fontSize: 11, color: C2.faint }} className="mono">실시간 polling · 30s</div>
      </div>

      <Table2
        columns={[
          { header: '심각도', render: r => sevPill(r.sev) },
          { header: '유형', mono: true, render: r => <span style={{ color: C2.primary, fontWeight: 600 }}>{r.type}</span> },
          { header: '유저', mono: true, render: r => <span style={{ fontSize: 12, color: r.user === 'system' ? C2.faint : C2.text }}>{r.user}</span> },
          { header: '탐지 시각', mono: true, render: r => <span style={{ fontSize: 11.5, color: C2.muted }}>{r.detected}</span> },
          { header: '탐지 데이터', render: r => <span style={{ color: C2.muted, fontSize: 12.5 }}>{r.data}</span> },
          { header: '처리', align: 'right', render: () => (
            <div style={{ display: 'flex', gap: 6, justifyContent: 'flex-end' }}>
              <Btn kind="ghost" size="sm">무시</Btn>
              <Btn kind="primary" size="sm">조치</Btn>
            </div>
          )},
        ]}
        rows={filtered}
        empty="검토 대기 없음 — 어뷰징 자동 감지가 아직 발동되지 않았거나, 큐가 비어있습니다."
      />
    </>
  );
}

// ============================================================
// 3. ACTION LOGS
// ============================================================
function ActionLogs() {
  const [action, setAction] = React.useState('all');
  const [target, setTarget] = React.useState('all');

  const rows = [
    { time: '2026.5.4. 20:03:00', admin: '40bb01c81', action: 'beta_reject', target: 'beta_request 0f385eff', ip: '157.52.116.34', detail: '—' },
    { time: '2026.5.4. 18:42:11', admin: '40bb01c81', action: 'beta_approve', target: 'beta_request 8a2e1c9d', ip: '157.52.116.34', detail: 'memo: 학생 베타 1차' },
    { time: '2026.5.4. 14:21:55', admin: '40bb01c81', action: 'whitelist_add', target: 'whitelist 2261071@pcu.ac.kr', ip: '157.52.116.34', detail: '무기한' },
    { time: '2026.5.4. 11:08:02', admin: '40bb01c81', action: 'toggle_change', target: 'feature_flag judge_lite_mode', ip: '157.52.116.34', detail: 'OFF → ON' },
    { time: '2026.5.4. 10:33:18', admin: '40bb01c81', action: 'message_send', target: 'user memnyan35@gmail.com', ip: '157.52.116.34', detail: '제목: 베타 안내' },
    { time: '2026.5.3. 22:14:09', admin: '40bb01c81', action: 'announcement_create', target: 'announcement notice_240503', ip: '157.52.116.34', detail: 'severity: Info' },
  ];

  return (
    <>
      <div style={{ display: 'flex', gap: 10, alignItems: 'center', marginBottom: 12, flexWrap: 'wrap' }}>
        <Select value={action} onChange={e => setAction(e.target.value)} options={[
          { value: 'all', label: '액션: 전체' },
          { value: 'beta', label: 'beta_*' },
          { value: 'whitelist', label: 'whitelist_*' },
          { value: 'toggle', label: 'toggle_*' },
          { value: 'message', label: 'message_*' },
        ]}/>
        <Select value={target} onChange={e => setTarget(e.target.value)} options={[
          { value: 'all', label: '대상: 전체' },
          { value: 'user', label: 'user' },
          { value: 'beta_request', label: 'beta_request' },
          { value: 'whitelist', label: 'whitelist' },
        ]}/>
        <Input icon="🔍" placeholder="관리자 ID / IP 검색" style={{ flex: 1, minWidth: 180 }}/>
        <Btn kind="default" size="sm">CSV 내려받기</Btn>
      </div>

      <Table2
        columns={[
          { header: '시각', mono: true, render: r => <span style={{ fontSize: 11.5, color: C2.muted }}>{r.time}</span> },
          { header: '관리자', mono: true, render: r => <span className="mono" style={{ fontSize: 11.5, color: C2.text }}>{r.admin}</span> },
          { header: '액션', render: r => <Pill tone="primary" size="xs">{r.action}</Pill> },
          { header: '대상', mono: true, render: r => <span style={{ fontSize: 11.5, color: C2.muted }}>{r.target}</span> },
          { header: 'IP', mono: true, render: r => <span style={{ fontSize: 11.5, color: C2.faint }}>{r.ip}</span> },
          { header: '상세', render: r => <span style={{ color: C2.muted, fontSize: 12 }}>{r.detail}</span> },
        ]}
        rows={rows}
      />

      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 14, fontSize: 12, color: C2.muted }}>
        <span className="mono">전체 {rows.length}건 · 7일 보존</span>
        <div style={{ display: 'flex', gap: 4 }}>
          <button style={{ width: 28, height: 28, border: `1px solid ${C2.border}`, background: C2.panel, borderRadius: 6, color: C2.faint }}>‹</button>
          <button style={{ width: 28, height: 28, border: `1px solid ${C2.primary}`, background: C2.primary, borderRadius: 6, color: 'white', fontWeight: 700 }}>1</button>
          <button style={{ width: 28, height: 28, border: `1px solid ${C2.border}`, background: C2.panel, borderRadius: 6, color: C2.faint }}>›</button>
        </div>
      </div>
    </>
  );
}

// ============================================================
// 4. TOGGLES
// ============================================================
function Toggle({ on, onChange }) {
  return (
    <button onClick={() => onChange(!on)} style={{
      width: 38, height: 22, borderRadius: 11,
      background: on ? C2.primary : C2.borderStrong,
      border: 0, cursor: 'pointer', padding: 2,
      transition: 'background 0.18s',
      position: 'relative',
    }}>
      <div style={{
        width: 18, height: 18, borderRadius: '50%', background: 'white',
        boxShadow: '0 1px 3px rgba(0,0,0,0.2)',
        transform: on ? 'translateX(16px)' : 'translateX(0)',
        transition: 'transform 0.18s',
      }}/>
    </button>
  );
}

function Toggles() {
  const [s, setS] = React.useState({ gemini: false, lite: false, maint: false, signupBlock: false });
  const items = [
    { key: 'gemini', emoji: '🪐', title: 'Gemini 폴백', desc: 'Anthropic 장애 시 Gemini로 폴백. (현재 Gemini 미들웨어 — placeholder, 후속 PR에서 동작)', userMsg: 'AI 서비스 장애로 일부 기능이 제한됩니다.' },
    { key: 'lite', emoji: '⚡', title: 'Judge 간소 모드', desc: 'Judge 5단계 → 3단계로 비용 절감. (서버 라우트 통합은 후속 PR — 현재 토글만 박힘)', userMsg: 'Judge 분석이 간소 모드로 작동 중입니다.' },
    { key: 'maint', emoji: '🚧', title: '점검 모드', desc: '모든 일반 API 503 응답. 어드민 라우트 (/api/admin/*) + /api/health 는 우회 — Brian 토큰으로 들어올 수 있음.', userMsg: '시스템 점검 중입니다. 잠시 후 다시 시도해주세요.' },
    { key: 'signupBlock', emoji: '🚫', title: '신규 가입 차단', desc: '회원가입 (이메일/OAuth) + 베타 신청 (/api/beta-request) 차단. (서버 라우트 통합은 후속 PR — 현재 토글만 박힘)', userMsg: '신규 가입이 일시 중단되었습니다.' },
  ];

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
      {items.map((it) => (
        <Card key={it.key} padding={0}>
          <div style={{ padding: '16px 20px', borderBottom: s[it.key] ? `1px solid ${C2.border}` : 'none' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 16 }}>
              <div style={{ flex: 1 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 }}>
                  <span style={{ fontSize: 16 }}>{it.emoji}</span>
                  <span style={{ fontSize: 14.5, fontWeight: 700, color: C2.text }}>{it.title}</span>
                  {s[it.key] && <Pill tone="bad" size="xs">● ACTIVE</Pill>}
                </div>
                <div style={{ fontSize: 12.5, color: C2.muted, lineHeight: 1.55 }}>{it.desc}</div>
              </div>
              <Toggle on={s[it.key]} onChange={v => setS(p => ({ ...p, [it.key]: v }))}/>
            </div>
            <div style={{ marginTop: 12, fontSize: 10.5, color: C2.muted, fontWeight: 700, letterSpacing: '0.04em', textTransform: 'uppercase', marginBottom: 4 }}>사용자 표시 메시지</div>
            <div style={{
              padding: '10px 12px', background: C2.primarySofter, borderRadius: 7,
              fontSize: 12.5, color: C2.textSoft, fontFamily: "'JetBrains Mono', ui-monospace, monospace",
            }}>{it.userMsg}</div>
            <div className="mono" style={{ fontSize: 10.5, color: C2.faint, marginTop: 8 }}>마지막 변경: 2026.5.4. 오후 2:51 · admin@40bb01c81</div>
          </div>
        </Card>
      ))}
    </div>
  );
}

// ============================================================
// 5. ALERTS
// ============================================================
function Alerts() {
  const [items, setItems] = React.useState([
    { key: 'beta_request_new', emoji: '📨', title: '베타 신청 신규', discord: true, email: false, both: false, on: true },
    { key: 'user_signup', emoji: '🎉', title: '신규 가입', discord: true, email: false, both: false, on: true },
    { key: 'first_judge', emoji: '✨', title: '첫 Judge 호출', discord: true, email: false, both: false, on: true },
    { key: 'abuse_high', emoji: '🚨', title: '어뷰징 high (다중 계정 등)', discord: true, email: true, both: false, on: true },
    { key: 'abuse_critical', emoji: '🔴', title: '어뷰징 critical', discord: true, email: true, both: true, on: true },
    { key: 'cost_threshold_exceed', emoji: '🪙', title: 'AI 비용 일한도 초과', discord: true, email: true, both: false, on: true },
    { key: 'judge_error_spike', emoji: '⚠️', title: 'Judge 에러 스파이크', discord: true, email: false, both: false, on: true },
    { key: 'system_toggle_changed', emoji: '⚡', title: '시스템 토글 변경', discord: true, email: false, both: false, on: true },
  ]);
  const setItem = (i, patch) => setItems(prev => prev.map((it, j) => j === i ? { ...it, ...patch } : it));

  return (
    <>
      <Card padding={16} style={{ marginBottom: 14 }}>
        <div style={{ fontSize: 13, color: C2.muted, lineHeight: 1.6 }}>
          이벤트별로 어떤 채널 (Discord / Email / 둘 다) 로 알림 받을지 설정.
          <br/>구독 안 된 이벤트는 default 동작 — 모든 어드민에게 디스코드 발송 가능.
        </div>
        <div style={{ marginTop: 12, display: 'flex', gap: 16, fontSize: 11, color: C2.faint }}>
          <span>환경변수</span>
          <span className="mono" style={{ background: C2.primarySofter, padding: '2px 6px', borderRadius: 4, color: C2.primary }}>DISCORD_WEBHOOK_URL</span>
          <span className="mono" style={{ background: C2.primarySofter, padding: '2px 6px', borderRadius: 4, color: C2.primary }}>RESEND_API_KEY</span>
          <span>설정 필요 (미설정 시 silent skip).</span>
        </div>
      </Card>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {items.map((it, i) => (
          <Card key={it.key} padding={14}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
              <div style={{ flex: 1, display: 'flex', alignItems: 'center', gap: 10 }}>
                <span style={{ fontSize: 16 }}>{it.emoji}</span>
                <div>
                  <div style={{ fontSize: 13.5, fontWeight: 600, color: C2.text }}>{it.title}</div>
                  <div className="mono" style={{ fontSize: 10.5, color: C2.faint, marginTop: 3, background: C2.rowSofter, display: 'inline-block', padding: '1px 6px', borderRadius: 3 }}>{it.key}</div>
                </div>
              </div>
              <div style={{ display: 'flex', gap: 4 }}>
                {[
                  { k: 'discord', label: 'Discord' },
                  { k: 'email', label: 'Email' },
                  { k: 'both', label: '둘 다' },
                ].map(ch => (
                  <button key={ch.k} onClick={() => setItem(i, { [ch.k]: !it[ch.k] })} style={{
                    padding: '5px 10px', borderRadius: 6,
                    background: it[ch.k] ? C2.primary : C2.panel,
                    color: it[ch.k] ? 'white' : C2.muted,
                    border: `1px solid ${it[ch.k] ? C2.primary : C2.border}`,
                    fontSize: 11, fontWeight: 600, cursor: 'pointer',
                  }}>{ch.label}</button>
                ))}
              </div>
              <Toggle on={it.on} onChange={v => setItem(i, { on: v })}/>
            </div>
          </Card>
        ))}
      </div>
    </>
  );
}

// ============================================================
// 6. FEEDBACK
// ============================================================
function Feedback() {
  const [tab, setTab] = React.useState('new');
  const tabs = [
    { value: 'new', label: '🆕 신규' },
    { value: 'progress', label: '🚧 진행' },
    { value: 'closed', label: '✓ 처리' },
    { value: 'reject', label: '❌ 거절' },
    { value: 'unfinished', label: '◐ 미수정' },
    { value: 'reply', label: '💬 응답' },
  ];
  return (
    <>
      <Tabs value={tab} onChange={setTab} tabs={tabs}/>
      <div style={{ marginTop: 14 }}>
        <Card padding={0}>
          <div style={{ padding: '60px 20px', textAlign: 'center', color: C2.faint, fontSize: 13.5 }}>
            #눈누가 없습니다.
            <div style={{ fontSize: 11.5, color: C2.faint, marginTop: 8 }} className="mono">feedback 테이블에 status='new' 인 항목이 없습니다.</div>
          </div>
        </Card>
      </div>
    </>
  );
}

// ============================================================
// 7. MESSAGES
// ============================================================
function Messages() {
  const [recipient, setRecipient] = React.useState('');
  const [type, setType] = React.useState('admin_reply');
  const [title, setTitle] = React.useState('');
  const [body, setBody] = React.useState('');

  return (
    <Card padding={24}>
      <div style={{ fontSize: 13, color: C2.muted, lineHeight: 1.6, marginBottom: 20, padding: '12px 14px', background: C2.primarySofter, borderRadius: 8 }}>
        개별 사용자에게 1:1 인앱 메시지를 보냅니다. 사용자는 메인 앱 헤더의 종 배지로 받아봅니다.<br/>
        피드백 회신은 피드백 인박스 → "회신" 버튼으로 자동 처리됩니다 (이 화면은 직접 발송용).
      </div>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
        <div>
          <div style={{ fontSize: 11, color: C2.muted, fontWeight: 700, letterSpacing: '0.04em', textTransform: 'uppercase', marginBottom: 6 }}>recipient_id (users.id UUID)</div>
          <Input value={recipient} onChange={e => setRecipient(e.target.value)} placeholder="00000000-0000-0000-0000-000000000000"/>
        </div>

        <div>
          <div style={{ fontSize: 11, color: C2.muted, fontWeight: 700, letterSpacing: '0.04em', textTransform: 'uppercase', marginBottom: 6 }}>type</div>
          <Tabs value={type} onChange={setType} tabs={[
            { value: 'admin_reply', label: '어드민 회신' },
            { value: 'system', label: '시스템' },
            { value: 'support', label: '지원' },
            { value: 'reward', label: '보상' },
          ]}/>
        </div>

        <div>
          <div style={{ fontSize: 11, color: C2.muted, fontWeight: 700, letterSpacing: '0.04em', textTransform: 'uppercase', marginBottom: 6 }}>제목</div>
          <Input value={title} onChange={e => setTitle(e.target.value)} placeholder=""/>
        </div>

        <div>
          <div style={{ fontSize: 11, color: C2.muted, fontWeight: 700, letterSpacing: '0.04em', textTransform: 'uppercase', marginBottom: 6 }}>본문</div>
          <textarea value={body} onChange={e => setBody(e.target.value)} rows={6} style={{
            width: '100%', padding: '10px 12px',
            background: C2.panel, border: `1px solid ${C2.border}`, borderRadius: 7,
            fontSize: 13, color: C2.text, fontFamily: 'inherit',
            resize: 'vertical', outline: 'none',
          }}
            onFocus={e => { e.currentTarget.style.borderColor = C2.primary; e.currentTarget.style.boxShadow = `0 0 0 3px ${C2.primarySoft}`; }}
            onBlur={e => { e.currentTarget.style.borderColor = C2.border; e.currentTarget.style.boxShadow = 'none'; }}
          />
        </div>

        <div style={{ display: 'flex', justifyContent: 'center', marginTop: 8 }}>
          <Btn kind="primary">메시지 발송</Btn>
        </div>
      </div>
    </Card>
  );
}

// ============================================================
// 8. ANNOUNCEMENTS
// ============================================================
function Announcements() {
  const [title, setTitle] = React.useState('');
  const [body, setBody] = React.useState('');
  const [sev, setSev] = React.useState('info');
  const [target, setTarget] = React.useState('all');
  const [showBanner, setShowBanner] = React.useState(true);
  const [silentEmail, setSilentEmail] = React.useState(false);

  return (
    <>
      <Card padding={24} style={{ marginBottom: 16 }}>
        <div style={{ fontSize: 14, fontWeight: 700, color: C2.text, marginBottom: 14, display: 'flex', alignItems: 'center', gap: 8 }}>
          ✨ 새 공지 작성
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <div>
            <div style={{ fontSize: 11, color: C2.muted, fontWeight: 700, letterSpacing: '0.04em', textTransform: 'uppercase', marginBottom: 6 }}>제목</div>
            <Input value={title} onChange={e => setTitle(e.target.value)}/>
          </div>
          <div>
            <div style={{ fontSize: 11, color: C2.muted, fontWeight: 700, letterSpacing: '0.04em', textTransform: 'uppercase', marginBottom: 6 }}>내용</div>
            <textarea value={body} onChange={e => setBody(e.target.value)} rows={5} placeholder="유니코드 그대로 표시됩니다." style={{
              width: '100%', padding: '10px 12px',
              background: C2.panel, border: `1px solid ${C2.border}`, borderRadius: 7,
              fontSize: 13, color: C2.text, fontFamily: 'inherit', resize: 'vertical', outline: 'none',
            }}/>
          </div>

          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
            <div>
              <div style={{ fontSize: 11, color: C2.muted, fontWeight: 700, letterSpacing: '0.04em', textTransform: 'uppercase', marginBottom: 6 }}>심각도</div>
              <Tabs value={sev} onChange={setSev} tabs={[
                { value: 'info', label: '🔵 Info' },
                { value: 'warning', label: '⚠ Warning' },
                { value: 'critical', label: '🔴 Critical' },
              ]}/>
            </div>
            <div>
              <div style={{ fontSize: 11, color: C2.muted, fontWeight: 700, letterSpacing: '0.04em', textTransform: 'uppercase', marginBottom: 6 }}>대상</div>
              <Tabs value={target} onChange={setTarget} tabs={[
                { value: 'all', label: '전체' },
                { value: 'beta', label: '베타 사용자' },
                { value: 'paid', label: '유료 구독자' },
                { value: 'admin', label: '어드민' },
              ]}/>
            </div>
          </div>

          <div style={{ display: 'flex', gap: 14, fontSize: 13, color: C2.muted }}>
            <label style={{ display: 'flex', alignItems: 'center', gap: 6, cursor: 'pointer' }}>
              <input type="checkbox" checked={showBanner} onChange={e => setShowBanner(e.target.checked)} style={{ accentColor: C2.primary }}/>
              메인 앱 배너 노출
            </label>
            <label style={{ display: 'flex', alignItems: 'center', gap: 6, cursor: 'pointer' }}>
              <input type="checkbox" checked={silentEmail} onChange={e => setSilentEmail(e.target.checked)} style={{ accentColor: C2.primary }}/>
              발송 시 대상에게 이메일 별송 (1회 한정)
            </label>
          </div>

          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
            <div>
              <div style={{ fontSize: 11, color: C2.muted, fontWeight: 700, letterSpacing: '0.04em', textTransform: 'uppercase', marginBottom: 6 }}>시작 (선택, 기본: 즉시)</div>
              <Input type="datetime-local" value="" onChange={() => {}}/>
            </div>
            <div>
              <div style={{ fontSize: 11, color: C2.muted, fontWeight: 700, letterSpacing: '0.04em', textTransform: 'uppercase', marginBottom: 6 }}>종료 (선택, 빈 값 = 무기한)</div>
              <Input type="datetime-local" value="" onChange={() => {}}/>
            </div>
          </div>

          <div>
            <Btn kind="primary">📢 공지 생성 (초안)</Btn>
          </div>
        </div>
      </Card>

      <div style={{ fontSize: 11, fontWeight: 700, color: C2.muted, letterSpacing: '0.04em', textTransform: 'uppercase', margin: '24px 0 10px' }}>📋 기존 공지 (0건)</div>
      <Card padding={0}>
        <div style={{ padding: '50px 20px', textAlign: 'center', color: C2.faint, fontSize: 13 }}>등록된 공지가 없습니다.</div>
      </Card>
    </>
  );
}

window.AdminPages2 = { AICost, ReviewQueue, ActionLogs, Toggles, Alerts, Feedback, Messages, Announcements };
