<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AI Gateway 모니터 - 청춘약국</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;500;600;700&display=swap" rel="stylesheet">
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
            font-family: 'Noto Sans KR', -apple-system, BlinkMacSystemFont, sans-serif;
            background: #0f172a;
            -webkit-font-smoothing: antialiased;
            color: #e2e8f0;
            min-height: 100vh;
        }

        /* ── 헤더 ── */
        .header {
            background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
            padding: 28px 32px 24px;
            border-bottom: 1px solid rgba(255,255,255,0.05);
        }
        .header-nav {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 16px;
        }
        .header-nav a {
            color: rgba(255,255,255,0.6);
            text-decoration: none;
            font-size: 14px;
            font-weight: 500;
            transition: color 0.2s;
        }
        .header-nav a:hover { color: #fff; }
        .header h1 {
            font-size: 24px;
            font-weight: 700;
            letter-spacing: -0.5px;
            margin-bottom: 6px;
            display: flex;
            align-items: center;
            gap: 10px;
        }
        .header h1 .live-dot {
            width: 10px;
            height: 10px;
            background: #22c55e;
            border-radius: 50%;
            animation: pulse 2s infinite;
        }
        .header h1 .live-dot.offline { background: #ef4444; animation: none; }
        @keyframes pulse {
            0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.4); }
            50% { opacity: 0.8; box-shadow: 0 0 0 8px rgba(34, 197, 94, 0); }
        }
        .header p {
            font-size: 14px;
            color: rgba(255,255,255,0.5);
            font-weight: 400;
        }

        /* ── 컨텐츠 ── */
        .content {
            max-width: 1100px;
            margin: 0 auto;
            padding: 24px 20px 60px;
        }

        /* ── 메인 카드 ── */
        .main-card {
            background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
            border-radius: 20px;
            padding: 32px;
            margin-bottom: 24px;
            border: 1px solid rgba(255,255,255,0.05);
        }
        .main-header {
            display: flex;
            justify-content: space-between;
            align-items: flex-start;
            margin-bottom: 24px;
        }
        .main-title {
            font-size: 14px;
            font-weight: 600;
            color: rgba(255,255,255,0.5);
            text-transform: uppercase;
            letter-spacing: 0.5px;
            margin-bottom: 8px;
        }
        .main-model {
            font-size: 20px;
            font-weight: 700;
            color: #a78bfa;
        }
        .refresh-btn {
            background: rgba(255,255,255,0.1);
            border: none;
            color: rgba(255,255,255,0.7);
            padding: 10px 18px;
            border-radius: 10px;
            font-size: 13px;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.2s;
            display: flex;
            align-items: center;
            gap: 6px;
        }
        .refresh-btn:hover {
            background: rgba(255,255,255,0.15);
            color: #fff;
        }
        .refresh-btn.loading { opacity: 0.6; pointer-events: none; }

        /* 컨텍스트 표시 */
        .context-display {
            margin-bottom: 24px;
        }
        .context-numbers {
            display: flex;
            align-items: baseline;
            gap: 8px;
            margin-bottom: 12px;
        }
        .context-used {
            font-size: 64px;
            font-weight: 700;
            letter-spacing: -3px;
            line-height: 1;
        }
        .context-max {
            font-size: 24px;
            font-weight: 500;
            color: rgba(255,255,255,0.3);
        }
        .context-percent {
            font-size: 24px;
            font-weight: 600;
            color: #22c55e;
            margin-left: 16px;
        }
        .context-percent.warning { color: #fbbf24; }
        .context-percent.danger { color: #ef4444; }

        /* 프로그레스 바 */
        .progress-wrap {
            background: rgba(255,255,255,0.1);
            border-radius: 100px;
            height: 12px;
            overflow: hidden;
        }
        .progress-bar {
            height: 100%;
            border-radius: 100px;
            background: linear-gradient(90deg, #22c55e, #84cc16);
            transition: width 0.6s ease;
        }
        .progress-bar.warning { background: linear-gradient(90deg, #f59e0b, #fbbf24); }
        .progress-bar.danger { background: linear-gradient(90deg, #ef4444, #f97316); }

        /* 통계 그리드 */
        .stats-grid {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            gap: 16px;
            margin-top: 28px;
        }
        .stat-item {
            background: rgba(0,0,0,0.2);
            border-radius: 14px;
            padding: 18px 20px;
        }
        .stat-label {
            font-size: 12px;
            font-weight: 500;
            color: rgba(255,255,255,0.4);
            margin-bottom: 6px;
        }
        .stat-value {
            font-size: 22px;
            font-weight: 700;
        }
        .stat-value.purple { color: #a78bfa; }
        .stat-value.blue { color: #38bdf8; }
        .stat-value.yellow { color: #fbbf24; }
        .stat-value.green { color: #34d399; }

        /* ── 세션 목록 ── */
        .sessions-card {
            background: #1e293b;
            border-radius: 20px;
            border: 1px solid rgba(255,255,255,0.05);
            overflow: hidden;
        }
        .sessions-header {
            padding: 20px 24px;
            border-bottom: 1px solid rgba(255,255,255,0.05);
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .sessions-title {
            font-size: 16px;
            font-weight: 600;
        }
        .sessions-count {
            font-size: 13px;
            color: rgba(255,255,255,0.4);
        }
        .sessions-list {
            max-height: 500px;
            overflow-y: auto;
        }
        .session-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 16px 24px;
            border-bottom: 1px solid rgba(255,255,255,0.03);
            transition: background 0.15s;
        }
        .session-item:hover { background: rgba(255,255,255,0.02); }
        .session-item:last-child { border-bottom: none; }
        .session-info { flex: 1; }
        .session-name {
            font-size: 14px;
            font-weight: 600;
            color: #e2e8f0;
            margin-bottom: 4px;
        }
        .session-meta {
            font-size: 12px;
            color: rgba(255,255,255,0.4);
            display: flex;
            gap: 12px;
        }
        .session-model {
            color: #a78bfa;
        }
        .session-usage {
            text-align: right;
        }
        .session-percent {
            font-size: 18px;
            font-weight: 700;
            margin-bottom: 2px;
        }
        .session-percent.low { color: #22c55e; }
        .session-percent.mid { color: #fbbf24; }
        .session-percent.high { color: #ef4444; }
        .session-tokens {
            font-size: 12px;
            color: rgba(255,255,255,0.4);
        }
        .session-bar-wrap {
            width: 100px;
            height: 4px;
            background: rgba(255,255,255,0.1);
            border-radius: 100px;
            margin-top: 6px;
        }
        .session-bar {
            height: 100%;
            border-radius: 100px;
            background: #22c55e;
        }
        .session-bar.mid { background: #fbbf24; }
        .session-bar.high { background: #ef4444; }

        /* ── 모델별 통계 ── */
        .model-stats {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 12px;
            margin-bottom: 24px;
        }
        .model-stat-card {
            background: #1e293b;
            border-radius: 14px;
            padding: 18px 20px;
            border: 1px solid rgba(255,255,255,0.05);
        }
        .model-stat-name {
            font-size: 14px;
            font-weight: 600;
            color: #a78bfa;
            margin-bottom: 10px;
        }
        .model-stat-row {
            display: flex;
            justify-content: space-between;
            font-size: 13px;
            color: rgba(255,255,255,0.6);
            margin-bottom: 4px;
        }
        .model-stat-row span:last-child {
            font-weight: 600;
            color: #e2e8f0;
        }

        /* ── 에러 상태 ── */
        .error-state {
            text-align: center;
            padding: 60px 20px;
            color: #f87171;
        }
        .error-icon { font-size: 48px; margin-bottom: 12px; }
        .error-text { font-size: 16px; font-weight: 500; margin-bottom: 8px; }
        .error-sub { font-size: 13px; color: rgba(255,255,255,0.4); }

        /* ── 타임스탬프 ── */
        .timestamp {
            text-align: center;
            padding: 16px;
            font-size: 12px;
            color: rgba(255,255,255,0.3);
        }

        /* ── 반응형 ── */
        @media (max-width: 768px) {
            .stats-grid { grid-template-columns: repeat(2, 1fr); }
            .context-used { font-size: 48px; }
            .context-max { font-size: 18px; }
            .context-percent { font-size: 18px; }
            .header { padding: 20px 16px 18px; }
            .content { padding: 16px 12px 40px; }
            .main-card { padding: 24px 20px; }
            .session-bar-wrap { display: none; }
        }
    </style>
</head>
<body>
    <div class="header">
        <div class="header-nav">
            <a href="/admin">← 관리자 홈</a>
            <div>
                <a href="/admin/ai-crm" style="margin-right: 16px;">AI 업셀링</a>
                <a href="/admin/alimtalk">알림톡 로그</a>
            </div>
        </div>
        <h1>
            <span class="live-dot" id="statusDot"></span>
            AI Gateway 모니터
        </h1>
        <p>Clawdbot Gateway 실시간 상태 · Claude / GPT 토큰 사용량</p>
    </div>

    <div class="content">
        <div id="mainContent">
            <!-- 메인 카드 -->
            <div class="main-card">
                <div class="main-header">
                    <div>
                        <div class="main-title">현재 모델</div>
                        <div class="main-model" id="currentModel">로딩중...</div>
                    </div>
                    <button class="refresh-btn" id="refreshBtn" onclick="refresh()">
                        <span>↻</span> 새로고침
                    </button>
                </div>

                <div class="context-display">
                    <div class="context-numbers">
                        <span class="context-used" id="contextUsed">--</span>
                        <span class="context-max" id="contextMax">/ 200k</span>
                        <span class="context-percent" id="contextPercent">0%</span>
                    </div>
                    <div class="progress-wrap">
                        <div class="progress-bar" id="progressBar" style="width: 0%"></div>
                    </div>
                </div>

                <div class="stats-grid">
                    <div class="stat-item">
                        <div class="stat-label">입력 토큰</div>
                        <div class="stat-value purple" id="inputTokens">-</div>
                    </div>
                    <div class="stat-item">
                        <div class="stat-label">출력 토큰</div>
                        <div class="stat-value blue" id="outputTokens">-</div>
                    </div>
                    <div class="stat-item">
                        <div class="stat-label">전체 토큰 (모든 세션)</div>
                        <div class="stat-value yellow" id="totalTokens">-</div>
                    </div>
                    <div class="stat-item">
                        <div class="stat-label">활성 세션</div>
                        <div class="stat-value green" id="sessionCount">-</div>
                    </div>
                </div>
            </div>

            <!-- 모델별 통계 -->
            <div class="model-stats" id="modelStats"></div>

            <!-- 세션 목록 -->
            <div class="sessions-card">
                <div class="sessions-header">
                    <div class="sessions-title">세션별 상세</div>
                    <div class="sessions-count" id="sessionsCount">-</div>
                </div>
                <div class="sessions-list" id="sessionsList"></div>
            </div>

            <div class="timestamp" id="timestamp">-</div>
        </div>
    </div>

    <script>
    function formatNumber(num) {
        if (num >= 1000000) return (num / 1000000).toFixed(1) + 'M';
        if (num >= 1000) return Math.round(num / 1000) + 'k';
        return num.toString();
    }

    function escapeHtml(str) {
        if (!str) return '';
        return str.replace(/[&<>"']/g, m => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[m]));
    }

    function getPercentClass(percent) {
        if (percent >= 70) return 'high';
        if (percent >= 40) return 'mid';
        return 'low';
    }

    function refresh() {
        const btn = document.getElementById('refreshBtn');
        btn.classList.add('loading');
        btn.innerHTML = '<span>⟳</span> 로딩중...';

        fetch('/api/claude-status?detail=true')
            .then(res => res.json())
            .then(data => {
                btn.classList.remove('loading');
                btn.innerHTML = '<span>↻</span> 새로고침';

                if (!data.ok || !data.connected) {
                    document.getElementById('statusDot').classList.add('offline');
                    document.getElementById('mainContent').innerHTML = `
                        <div class="main-card">
                            <div class="error-state">
                                <div class="error-icon">⚠️</div>
                                <div class="error-text">Gateway 연결 실패</div>
                                <div class="error-sub">${data.error || 'Clawdbot이 실행 중인지 확인하세요'}</div>
                            </div>
                        </div>
                    `;
                    return;
                }

                document.getElementById('statusDot').classList.remove('offline');
                updateUI(data);
            })
            .catch(err => {
                btn.classList.remove('loading');
                btn.innerHTML = '<span>↻</span> 새로고침';
                console.error(err);
            });
    }

    function updateUI(data) {
        const ctx = data.context;
        const main = data.mainSession || {};
        const summary = data.summary;

        // 모델
        document.getElementById('currentModel').textContent = data.model;

        // 컨텍스트
        document.getElementById('contextUsed').textContent = formatNumber(ctx.used);
        document.getElementById('contextMax').textContent = '/ ' + formatNumber(ctx.max);
        
        const percentEl = document.getElementById('contextPercent');
        percentEl.textContent = ctx.percent + '%';
        percentEl.className = 'context-percent';
        if (ctx.percent >= 70) percentEl.classList.add('danger');
        else if (ctx.percent >= 40) percentEl.classList.add('warning');

        // 프로그레스 바
        const bar = document.getElementById('progressBar');
        bar.style.width = ctx.percent + '%';
        bar.className = 'progress-bar';
        if (ctx.percent >= 70) bar.classList.add('danger');
        else if (ctx.percent >= 40) bar.classList.add('warning');

        // 통계
        document.getElementById('inputTokens').textContent = formatNumber(main.inputTokens || 0);
        document.getElementById('outputTokens').textContent = formatNumber(main.outputTokens || 0);
        document.getElementById('totalTokens').textContent = formatNumber(summary.totalTokens);
        document.getElementById('sessionCount').textContent = summary.totalSessions + '개';

        // 모델별 통계
        if (data.modelStats) {
            const statsHtml = Object.entries(data.modelStats).map(([model, stat]) => `
                <div class="model-stat-card">
                    <div class="model-stat-name">${escapeHtml(model)}</div>
                    <div class="model-stat-row">
                        <span>세션 수</span>
                        <span>${stat.sessions}개</span>
                    </div>
                    <div class="model-stat-row">
                        <span>총 토큰</span>
                        <span>${formatNumber(stat.tokens)}</span>
                    </div>
                </div>
            `).join('');
            document.getElementById('modelStats').innerHTML = statsHtml;
        }

        // 세션 목록
        if (data.sessions) {
            document.getElementById('sessionsCount').textContent = 
                `토큰 사용량 순 · ${data.sessions.length}개`;

            const sessionsHtml = data.sessions.map(s => {
                const pct = s.tokens.contextPercent;
                const pctClass = getPercentClass(pct);
                return `
                    <div class="session-item">
                        <div class="session-info">
                            <div class="session-name">${escapeHtml(s.displayName || s.name)}</div>
                            <div class="session-meta">
                                <span class="session-model">${escapeHtml(s.model)}</span>
                                <span>${s.channel || '-'}</span>
                                <span>${s.updatedAt || '-'}</span>
                            </div>
                        </div>
                        <div class="session-usage">
                            <div class="session-percent ${pctClass}">${pct}%</div>
                            <div class="session-tokens">${s.tokens.display}</div>
                            <div class="session-bar-wrap">
                                <div class="session-bar ${pctClass}" style="width: ${pct}%"></div>
                            </div>
                        </div>
                    </div>
                `;
            }).join('');
            document.getElementById('sessionsList').innerHTML = sessionsHtml;
        }

        // 타임스탬프
        const ts = new Date(data.timestamp);
        document.getElementById('timestamp').textContent = 
            `마지막 업데이트: ${ts.toLocaleTimeString('ko-KR')}`;
    }

    // 초기 로드 & 30초 자동 갱신
    refresh();
    setInterval(refresh, 30000);
    </script>
</body>
</html>
