"use strict";
/**
 * CLIProxy Quota Management
 *
 * Handles:
 * - ccs cliproxy quota [--provider <name>]
 * - ccs cliproxy default <account>
 * - ccs cliproxy pause <account>
 * - ccs cliproxy resume <account>
 * - ccs cliproxy doctor
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleResumeAccount = exports.handlePauseAccount = exports.handleSetDefault = exports.handleDoctor = exports.handleQuotaStatus = exports.__testExports = void 0;
const account_manager_1 = require("../../cliproxy/accounts/account-manager");
const quota_fetcher_1 = require("../../cliproxy/quota/quota-fetcher");
const quota_fetcher_codex_1 = require("../../cliproxy/quota/quota-fetcher-codex");
const quota_fetcher_claude_1 = require("../../cliproxy/quota/quota-fetcher-claude");
const quota_fetcher_claude_normalizer_1 = require("../../cliproxy/quota/quota-fetcher-claude-normalizer");
const quota_fetcher_gemini_cli_1 = require("../../cliproxy/quota/quota-fetcher-gemini-cli");
const quota_fetcher_ghcp_1 = require("../../cliproxy/quota/quota-fetcher-ghcp");
const quota_manager_1 = require("../../cliproxy/quota/quota-manager");
const provider_capabilities_1 = require("../../cliproxy/provider-capabilities");
const email_account_identity_1 = require("../../cliproxy/accounts/email-account-identity");
const ui_1 = require("../../utils/ui");
function parseProfileArgs(args) {
    const result = {};
    for (let i = 0; i < args.length; i++) {
        const arg = args[i];
        if (arg === '--provider' && args[i + 1]) {
            result.provider = args[++i];
        }
        else if (arg === '--model' && args[i + 1]) {
            result.model = args[++i];
        }
        else if (arg === '--account' && args[i + 1]) {
            result.account = args[++i];
        }
        else if (arg === '--force') {
            result.force = true;
        }
        else if (arg === '--yes' || arg === '-y') {
            result.yes = true;
        }
        else if (!arg.startsWith('-') && !result.name) {
            result.name = arg;
        }
    }
    return result;
}
function formatQuotaBar(percentage) {
    const width = 20;
    const clampedPct = Math.max(0, Math.min(100, percentage));
    const filled = Math.round((clampedPct / 100) * width);
    const empty = width - filled;
    const filledChar = clampedPct > 50 ? '█' : clampedPct > 10 ? '▓' : '░';
    return `[${filledChar.repeat(filled)}${' '.repeat(empty)}]`;
}
function formatResetTime(seconds) {
    if (seconds <= 0)
        return 'now';
    if (seconds < 60)
        return `in ${seconds}s`;
    if (seconds < 3600)
        return `in ${Math.round(seconds / 60)}m`;
    if (seconds < 86400)
        return `in ${Math.round(seconds / 3600)}h`;
    const days = Math.floor(seconds / 86400);
    const hours = Math.round((seconds % 86400) / 3600);
    if (hours <= 0)
        return `in ${days}d`;
    if (hours >= 24)
        return `in ${days + 1}d`;
    return `in ${days}d ${hours}h`;
}
function formatResetTimeISO(isoTime) {
    if (!isoTime)
        return 'unknown';
    const resetDate = new Date(isoTime);
    if (isNaN(resetDate.getTime()))
        return 'unknown';
    const seconds = Math.max(0, Math.round((resetDate.getTime() - Date.now()) / 1000));
    return formatResetTime(seconds);
}
function formatCliAccountLabel(account) {
    const displayName = (0, email_account_identity_1.formatAccountDisplayName)(account);
    return account.nickname ? `${account.nickname} (${displayName})` : displayName;
}
function resolveDisplayedTier(accountTier, liveTier) {
    return (liveTier && liveTier !== 'unknown' ? liveTier : accountTier) || 'unknown';
}
function getQuotaFailureDisplayEntries(quota) {
    const entries = [
        {
            tone: 'error',
            text: quota.error || 'Failed to fetch quota',
        },
    ];
    if (quota.actionHint) {
        entries.push({
            tone: 'info',
            text: quota.actionHint,
        });
    }
    const diagnostics = [];
    if (typeof quota.httpStatus === 'number') {
        diagnostics.push(`HTTP ${quota.httpStatus}`);
    }
    if (quota.errorCode) {
        diagnostics.push(`Code: ${quota.errorCode}`);
    }
    if (quota.retryable) {
        diagnostics.push('Retryable');
    }
    if (diagnostics.length > 0) {
        entries.push({
            tone: 'dim',
            text: diagnostics.join(' | '),
        });
    }
    const normalizedError = quota.error?.trim();
    const normalizedDetail = quota.errorDetail?.trim();
    if (normalizedDetail && normalizedDetail !== normalizedError) {
        entries.push({
            tone: 'dim',
            text: `Detail: ${normalizedDetail}`,
        });
    }
    return entries;
}
function displayQuotaFailure(quota) {
    for (const entry of getQuotaFailureDisplayEntries(quota)) {
        const rendered = entry.tone === 'error'
            ? (0, ui_1.color)(entry.text, 'error')
            : entry.tone === 'info'
                ? (0, ui_1.info)(entry.text)
                : (0, ui_1.dim)(entry.text);
        console.log(`    ${rendered}`);
    }
}
function formatAbsoluteResetTime(isoTime) {
    if (!isoTime)
        return null;
    const resetDate = new Date(isoTime);
    if (isNaN(resetDate.getTime()))
        return null;
    const date = resetDate.toLocaleDateString(undefined, {
        month: '2-digit',
        day: '2-digit',
    });
    const time = resetDate.toLocaleTimeString(undefined, {
        hour: '2-digit',
        minute: '2-digit',
    });
    return `${date} ${time}`;
}
function formatCodexWindowReset(window) {
    if (typeof window.resetAfterSeconds === 'number' && isFinite(window.resetAfterSeconds)) {
        const relative = formatResetTime(Math.max(0, window.resetAfterSeconds));
        if (window.resetAfterSeconds >= 86400 && window.resetAt) {
            const absolute = formatAbsoluteResetTime(window.resetAt);
            return absolute ? `${relative} (${absolute})` : relative;
        }
        return relative;
    }
    if (window.resetAt) {
        return formatResetTimeISO(window.resetAt);
    }
    return null;
}
function getCodexWindowKind(label) {
    const lower = (label || '').toLowerCase();
    const isCodeReview = lower.includes('code review') || lower.includes('code_review');
    const isPrimary = lower.includes('primary');
    const isSecondary = lower.includes('secondary');
    if (isCodeReview) {
        if (isPrimary)
            return 'code-review-5h';
        if (isSecondary)
            return 'code-review-weekly';
        return 'code-review';
    }
    if (isPrimary)
        return 'usage-5h';
    if (isSecondary)
        return 'usage-weekly';
    return 'unknown';
}
function inferCodeReviewCadence(window, allWindows) {
    const kind = getCodexWindowKind(window.label);
    if (kind === 'code-review-weekly')
        return 'weekly';
    const reset = window.resetAfterSeconds;
    if (typeof reset !== 'number' || !isFinite(reset) || reset <= 0)
        return null;
    const usage5h = allWindows.find((w) => getCodexWindowKind(w.label) === 'usage-5h' &&
        typeof w.resetAfterSeconds === 'number' &&
        isFinite(w.resetAfterSeconds) &&
        w.resetAfterSeconds > 0);
    const usageWeekly = allWindows.find((w) => getCodexWindowKind(w.label) === 'usage-weekly' &&
        typeof w.resetAfterSeconds === 'number' &&
        isFinite(w.resetAfterSeconds) &&
        w.resetAfterSeconds > 0);
    if (!usage5h || !usageWeekly)
        return null;
    const diffTo5h = Math.abs(reset - usage5h.resetAfterSeconds);
    const diffToWeekly = Math.abs(reset - usageWeekly.resetAfterSeconds);
    return diffToWeekly <= diffTo5h ? 'weekly' : '5h';
}
/**
 * Strip a leading "GPT-X.Y-Codex-" prefix from a feature label and turn the
 * remainder into a Codex-prefixed display name. Other labels pass through unchanged.
 */
function prettifyCodexFeatureLabel(featureLabel) {
    const trimmed = featureLabel.trim();
    if (!trimmed)
        return 'Additional';
    const stripped = trimmed.replace(/^GPT-[\d.]+-Codex-/i, '');
    if (stripped !== trimmed && stripped.length > 0) {
        return `Codex ${stripped}`;
    }
    return trimmed;
}
function getCodexWindowDisplayLabel(window, allWindows = []) {
    const context = allWindows.length > 0 ? allWindows : [window];
    // Prefer explicit category metadata when present (post-2026-04 windows).
    if (window.category === 'usage') {
        if (window.cadence === '5h')
            return '5h usage limit';
        if (window.cadence === 'weekly')
            return 'Weekly usage limit';
    }
    if (window.category === 'additional') {
        const pretty = prettifyCodexFeatureLabel(window.featureLabel || window.label || 'Additional');
        if (window.cadence === '5h')
            return `${pretty} (5h)`;
        if (window.cadence === 'weekly')
            return `${pretty} (weekly)`;
        return pretty;
    }
    if (window.category === 'code-review') {
        if (window.cadence === '5h')
            return 'Code review (5h)';
        if (window.cadence === 'weekly')
            return 'Code review (weekly)';
        return 'Code review';
    }
    // Legacy fallback: classify via label sniffing for cached windows without metadata.
    switch (getCodexWindowKind(window.label)) {
        case 'usage-5h':
            return '5h usage limit';
        case 'usage-weekly':
            return 'Weekly usage limit';
        case 'code-review-5h':
        case 'code-review-weekly':
        case 'code-review': {
            const inferred = inferCodeReviewCadence(window, context);
            if (inferred === '5h')
                return 'Code review (5h)';
            if (inferred === 'weekly')
                return 'Code review (weekly)';
            return 'Code review';
        }
        case 'unknown':
            return window.label;
    }
}
function getCodexCoreUsageWindows(windows) {
    let fiveHourWindow = null;
    let weeklyWindow = null;
    const nonCodeReviewWindows = [];
    // Prefer explicit category metadata when present so 'additional' windows
    // (e.g. GPT-5.3 Codex Spark) do not displace core usage windows in the summary.
    const hasCategoryMetadata = windows.some((window) => Boolean(window.category));
    if (hasCategoryMetadata) {
        for (const window of windows) {
            if (window.category === 'usage') {
                if (window.cadence === '5h' && !fiveHourWindow)
                    fiveHourWindow = window;
                else if (window.cadence === 'weekly' && !weeklyWindow)
                    weeklyWindow = window;
                nonCodeReviewWindows.push(window);
            }
            // 'code-review' and 'additional' are excluded from the core usage summary.
        }
    }
    else {
        for (const window of windows) {
            const kind = getCodexWindowKind(window.label);
            if (kind === 'usage-5h') {
                if (!fiveHourWindow)
                    fiveHourWindow = window;
                nonCodeReviewWindows.push(window);
                continue;
            }
            if (kind === 'usage-weekly') {
                if (!weeklyWindow)
                    weeklyWindow = window;
                nonCodeReviewWindows.push(window);
                continue;
            }
            if (kind === 'unknown') {
                nonCodeReviewWindows.push(window);
            }
        }
    }
    if ((!fiveHourWindow || !weeklyWindow) && nonCodeReviewWindows.length > 0) {
        const withReset = nonCodeReviewWindows
            .filter((w) => typeof w.resetAfterSeconds === 'number' && w.resetAfterSeconds >= 0)
            .sort((a, b) => (a.resetAfterSeconds || 0) - (b.resetAfterSeconds || 0));
        if (!fiveHourWindow) {
            fiveHourWindow = withReset[0] || nonCodeReviewWindows[0] || null;
        }
        if (!weeklyWindow) {
            weeklyWindow =
                withReset.length > 1
                    ? withReset[withReset.length - 1]
                    : nonCodeReviewWindows.find((w) => w !== fiveHourWindow) || null;
        }
    }
    return { fiveHourWindow, weeklyWindow };
}
function displayAntigravityQuotaSection(quotaResult) {
    const provider = 'agy';
    const accounts = (0, account_manager_1.getProviderAccounts)(provider);
    console.log((0, ui_1.subheader)(`Antigravity (${accounts.length} account${accounts.length !== 1 ? 's' : ''})`));
    console.log('');
    const rows = [];
    for (const account of accounts) {
        const quotaData = quotaResult.accounts.find((q) => q.account.id === account.id);
        const quota = quotaData?.quota;
        let avgQuota = 'N/A';
        if (quota?.success && quota.models.length > 0) {
            const avg = Math.round(quota.models.reduce((sum, m) => sum + m.percentage, 0) / quota.models.length);
            avgQuota = `${avg}%`;
        }
        const statusParts = [];
        if (account.paused)
            statusParts.push((0, ui_1.color)('PAUSED', 'warning'));
        if ((0, quota_manager_1.isOnCooldown)(provider, account.id))
            statusParts.push((0, ui_1.color)('COOLDOWN', 'warning'));
        const defaultMark = account.isDefault ? (0, ui_1.color)('*', 'success') : ' ';
        const tier = resolveDisplayedTier(account.tier, quota?.entitlement?.normalizedTier);
        const status = statusParts.join(', ');
        rows.push([defaultMark, formatCliAccountLabel(account), tier, avgQuota, status]);
    }
    console.log((0, ui_1.table)(rows, {
        head: ['', 'Account', 'Tier', 'Quota', 'Status'],
        colWidths: [3, 30, 10, 10, 20],
    }));
    console.log('');
}
function displayCodexQuotaSection(results) {
    console.log((0, ui_1.subheader)(`Codex (${results.length} account${results.length !== 1 ? 's' : ''})`));
    console.log('');
    for (const { account, quota } of results) {
        const accountInfo = (0, account_manager_1.findAccountByQuery)('codex', account);
        const accountLabel = accountInfo ? formatCliAccountLabel(accountInfo) : account;
        const defaultMark = accountInfo?.isDefault ? (0, ui_1.color)(' (default)', 'info') : '';
        if (!quota.success) {
            console.log(`  ${(0, ui_1.fail)(accountLabel)}${defaultMark}`);
            displayQuotaFailure(quota);
            console.log('');
            continue;
        }
        const { fiveHourWindow, weeklyWindow } = getCodexCoreUsageWindows(quota.windows);
        const coreUsageWindows = [fiveHourWindow, weeklyWindow].filter((w, index, arr) => !!w && arr.indexOf(w) === index);
        const statusWindows = coreUsageWindows.length > 0 ? coreUsageWindows : quota.windows;
        const avgQuota = statusWindows.length > 0
            ? statusWindows.reduce((sum, w) => sum + w.remainingPercent, 0) / statusWindows.length
            : 0;
        const statusIcon = avgQuota > 50 ? (0, ui_1.ok)('') : avgQuota > 10 ? (0, ui_1.warn)('') : (0, ui_1.fail)('');
        const planBadge = quota.planType ? (0, ui_1.color)(` [${quota.planType}]`, 'info') : '';
        console.log(`  ${statusIcon}${accountLabel}${defaultMark}${planBadge}`);
        const coreUsageSummary = quota.coreUsage ?? {
            fiveHour: fiveHourWindow
                ? {
                    label: fiveHourWindow.label,
                    remainingPercent: fiveHourWindow.remainingPercent,
                    resetAfterSeconds: fiveHourWindow.resetAfterSeconds,
                    resetAt: fiveHourWindow.resetAt,
                }
                : null,
            weekly: weeklyWindow
                ? {
                    label: weeklyWindow.label,
                    remainingPercent: weeklyWindow.remainingPercent,
                    resetAfterSeconds: weeklyWindow.resetAfterSeconds,
                    resetAt: weeklyWindow.resetAt,
                }
                : null,
        };
        const resetParts = [];
        const fiveHourReset = coreUsageSummary.fiveHour
            ? formatCodexWindowReset(coreUsageSummary.fiveHour)
            : null;
        const weeklyReset = coreUsageSummary.weekly
            ? formatCodexWindowReset(coreUsageSummary.weekly)
            : null;
        if (fiveHourReset)
            resetParts.push(`5h ${fiveHourReset}`);
        if (weeklyReset)
            resetParts.push(`weekly ${weeklyReset}`);
        if (resetParts.length > 0) {
            console.log(`    ${(0, ui_1.dim)(`Reset schedule: ${resetParts.join(' | ')}`)}`);
        }
        const orderedWindows = [fiveHourWindow, weeklyWindow, ...quota.windows].filter((w, index, arr) => !!w && arr.indexOf(w) === index);
        for (const window of orderedWindows) {
            const bar = formatQuotaBar(window.remainingPercent);
            const resetValue = formatCodexWindowReset(window);
            const resetLabel = resetValue ? (0, ui_1.dim)(` Resets ${resetValue}`) : '';
            console.log(`    ${getCodexWindowDisplayLabel(window, orderedWindows).padEnd(24)} ${bar} ${window.remainingPercent.toFixed(0)}%${resetLabel}`);
        }
        console.log('');
    }
}
function getClaudeWindowDisplayLabel(window) {
    switch (window.rateLimitType) {
        case 'five_hour':
            return '5h usage limit';
        case 'seven_day':
            return 'Weekly usage limit';
        case 'seven_day_opus':
            return 'Weekly usage (Opus)';
        case 'seven_day_sonnet':
            return 'Weekly usage (Sonnet)';
        case 'seven_day_oauth_apps':
            return 'Weekly usage (OAuth apps)';
        case 'seven_day_cowork':
            return 'Weekly usage (Cowork)';
        case 'overage':
            return 'Extra usage';
        default:
            return window.label;
    }
}
function toClaudeDisplayWindow(window) {
    return {
        rateLimitType: window.rateLimitType,
        label: window.label,
        remainingPercent: window.remainingPercent,
        resetAt: window.resetAt,
        status: window.status,
    };
}
function toClaudeCoreDisplayWindow(window) {
    if (!window)
        return null;
    return {
        rateLimitType: window.rateLimitType,
        label: window.label,
        remainingPercent: window.remainingPercent,
        resetAt: window.resetAt,
        status: window.status,
    };
}
function getClaudeCoreUsageWindows(quota) {
    const coreUsage = quota.coreUsage;
    const fiveHourFromCore = toClaudeCoreDisplayWindow(coreUsage?.fiveHour ?? null);
    const weeklyFromCore = toClaudeCoreDisplayWindow(coreUsage?.weekly ?? null);
    if (fiveHourFromCore || weeklyFromCore) {
        return {
            fiveHourWindow: fiveHourFromCore,
            weeklyWindow: weeklyFromCore,
        };
    }
    const fiveHourPolicy = quota.windows.find((window) => window.rateLimitType === 'five_hour') ?? null;
    const weeklyPolicy = (0, quota_fetcher_claude_normalizer_1.pickMostRestrictiveClaudeWeeklyWindow)(quota.windows);
    return {
        fiveHourWindow: fiveHourPolicy ? toClaudeDisplayWindow(fiveHourPolicy) : null,
        weeklyWindow: weeklyPolicy ? toClaudeDisplayWindow(weeklyPolicy) : null,
    };
}
function displayClaudeQuotaSection(results) {
    console.log((0, ui_1.subheader)(`Claude (${results.length} account${results.length !== 1 ? 's' : ''})`));
    console.log('');
    for (const { account, quota } of results) {
        const accountInfo = (0, account_manager_1.findAccountByQuery)('claude', account);
        const accountLabel = accountInfo ? formatCliAccountLabel(accountInfo) : account;
        const defaultMark = accountInfo?.isDefault ? (0, ui_1.color)(' (default)', 'info') : '';
        if (!quota.success) {
            console.log(`  ${(0, ui_1.fail)(accountLabel)}${defaultMark}`);
            displayQuotaFailure(quota);
            console.log('');
            continue;
        }
        const { fiveHourWindow, weeklyWindow } = getClaudeCoreUsageWindows(quota);
        const coreWindows = [fiveHourWindow, weeklyWindow].filter((window, index, arr) => !!window && arr.indexOf(window) === index);
        const statusWindows = coreWindows.length > 0 ? coreWindows : quota.windows.map(toClaudeDisplayWindow);
        const minQuota = statusWindows.length > 0
            ? Math.min(...statusWindows.map((window) => window.remainingPercent))
            : null;
        const statusIcon = minQuota === null ? (0, ui_1.info)('') : minQuota > 50 ? (0, ui_1.ok)('') : minQuota > 10 ? (0, ui_1.warn)('') : (0, ui_1.fail)('');
        console.log(`  ${statusIcon}${accountLabel}${defaultMark}`);
        const resetParts = [];
        if (fiveHourWindow?.resetAt)
            resetParts.push(`5h ${formatResetTimeISO(fiveHourWindow.resetAt)}`);
        if (weeklyWindow?.resetAt)
            resetParts.push(`weekly ${formatResetTimeISO(weeklyWindow.resetAt)}`);
        if (resetParts.length > 0) {
            console.log(`    ${(0, ui_1.dim)(`Reset schedule: ${resetParts.join(' | ')}`)}`);
        }
        const orderedWindows = [...coreWindows, ...quota.windows.map(toClaudeDisplayWindow)].filter((window, index, arr) => arr.findIndex((candidate) => candidate.rateLimitType === window.rateLimitType &&
            candidate.resetAt === window.resetAt &&
            candidate.status === window.status) === index);
        if (orderedWindows.length === 0) {
            console.log(`    ${(0, ui_1.dim)('Policy limits unavailable for this account')}`);
            console.log('');
            continue;
        }
        for (const window of orderedWindows) {
            const bar = formatQuotaBar(window.remainingPercent);
            const resetLabel = window.resetAt ? (0, ui_1.dim)(` Resets ${formatResetTimeISO(window.resetAt)}`) : '';
            const statusLabel = window.status === 'rejected'
                ? (0, ui_1.dim)(' [blocked]')
                : window.status === 'allowed_warning'
                    ? (0, ui_1.dim)(' [warning]')
                    : '';
            console.log(`    ${getClaudeWindowDisplayLabel(window).padEnd(24)} ${bar} ${window.remainingPercent.toFixed(0)}%${statusLabel}${resetLabel}`);
        }
        console.log('');
    }
}
function displayGeminiCliQuotaSection(results) {
    console.log((0, ui_1.subheader)(`Gemini CLI (${results.length} account${results.length !== 1 ? 's' : ''})`));
    console.log('');
    for (const { account, quota } of results) {
        const accountInfo = (0, account_manager_1.findAccountByQuery)('gemini', account);
        const accountLabel = accountInfo ? formatCliAccountLabel(accountInfo) : account;
        const defaultMark = accountInfo?.isDefault ? (0, ui_1.color)(' (default)', 'info') : '';
        if (!quota.success) {
            console.log(`  ${(0, ui_1.fail)(accountLabel)}${defaultMark}`);
            displayQuotaFailure(quota);
            console.log('');
            continue;
        }
        const avgQuota = quota.buckets.length > 0
            ? quota.buckets.reduce((sum, b) => sum + b.remainingPercent, 0) / quota.buckets.length
            : 0;
        const statusIcon = avgQuota > 50 ? (0, ui_1.ok)('') : avgQuota > 10 ? (0, ui_1.warn)('') : (0, ui_1.fail)('');
        console.log(`  ${statusIcon}${accountLabel}${defaultMark}`);
        if (quota.projectId) {
            console.log(`    Project: ${(0, ui_1.dim)(quota.projectId)}`);
        }
        if (quota.tierLabel) {
            console.log(`    Tier: ${(0, ui_1.dim)(quota.tierLabel)}`);
        }
        if (quota.entitlement?.rawTierId) {
            console.log(`    Tier ID: ${(0, ui_1.dim)(quota.entitlement.rawTierId)}`);
        }
        if (quota.creditBalance !== null && quota.creditBalance !== undefined) {
            console.log(`    Credits: ${(0, ui_1.dim)(quota.creditBalance.toLocaleString())}`);
        }
        for (const bucket of quota.buckets) {
            const bar = formatQuotaBar(bucket.remainingPercent);
            const tokenLabel = bucket.tokenType ? (0, ui_1.dim)(` (${bucket.tokenType})`) : '';
            const amountLabel = bucket.remainingAmount !== null && bucket.remainingAmount !== undefined
                ? (0, ui_1.dim)(` ${bucket.remainingAmount.toLocaleString()} left`)
                : '';
            const resetLabel = bucket.resetTime
                ? (0, ui_1.dim)(` Resets ${formatResetTimeISO(bucket.resetTime)}`)
                : '';
            console.log(`    ${bucket.label.padEnd(24)} ${bar} ${bucket.remainingPercent.toFixed(0)}%${tokenLabel}${amountLabel}${resetLabel}`);
        }
        console.log('');
    }
}
function formatSnapshotLabel(snapshot) {
    if (snapshot.unlimited) {
        return `${snapshot.percentUsed.toFixed(0)}% used (unlimited)`;
    }
    return `${snapshot.used}/${snapshot.entitlement} used`;
}
function displayGhcpQuotaSection(results) {
    console.log((0, ui_1.subheader)(`GitHub Copilot (${results.length} account${results.length !== 1 ? 's' : ''})`));
    console.log('');
    for (const { account, quota } of results) {
        const accountInfo = (0, account_manager_1.findAccountByQuery)('ghcp', account);
        const accountLabel = accountInfo ? formatCliAccountLabel(accountInfo) : account;
        const defaultMark = accountInfo?.isDefault ? (0, ui_1.color)(' (default)', 'info') : '';
        if (!quota.success) {
            console.log(`  ${(0, ui_1.fail)(accountLabel)}${defaultMark}`);
            displayQuotaFailure(quota);
            console.log('');
            continue;
        }
        const reportedSnapshots = [
            quota.snapshots.premiumInteractions,
            quota.snapshots.chat,
            quota.snapshots.completions,
        ].filter((snapshot) => snapshot.reported !== false);
        const rows = reportedSnapshots.map((snapshot) => snapshot.unlimited ? 100 : snapshot.percentRemaining);
        const minQuota = rows.length > 0 ? Math.min(...rows) : null;
        const statusIcon = minQuota === null ? (0, ui_1.info)('') : minQuota > 50 ? (0, ui_1.ok)('') : minQuota > 10 ? (0, ui_1.warn)('') : (0, ui_1.fail)('');
        const planBadge = quota.planType ? (0, ui_1.color)(` [${quota.planType}]`, 'info') : '';
        console.log(`  ${statusIcon}${accountLabel}${defaultMark}${planBadge}`);
        if (quota.quotaResetDate) {
            console.log(`    ${(0, ui_1.dim)(`Resets ${formatResetTimeISO(quota.quotaResetDate)}`)}`);
        }
        const allItems = [
            ['Premium interactions', quota.snapshots.premiumInteractions],
            ['Chat', quota.snapshots.chat],
            ['Completions', quota.snapshots.completions],
        ];
        const items = allItems.filter(([, snapshot]) => snapshot.reported !== false);
        for (const [label, snapshot] of items) {
            const bar = formatQuotaBar(snapshot.percentRemaining);
            const usageLabel = (0, ui_1.dim)(` ${formatSnapshotLabel(snapshot)}`);
            console.log(`    ${label.padEnd(24)} ${bar} ${snapshot.percentRemaining.toFixed(0)}%${usageLabel}`);
        }
        console.log('');
    }
}
const QUOTA_PROVIDER_RUNTIME = {
    agy: {
        fetch: (verbose) => (0, quota_fetcher_1.fetchAllProviderQuotas)('agy', verbose),
        hasData: (result) => result.accounts.length > 0,
        render: (result) => displayAntigravityQuotaSection(result),
        emptyTitle: 'Antigravity (0 accounts)',
        emptyMessage: 'No Antigravity accounts configured',
        authCommand: 'ccs agy --auth',
    },
    codex: {
        fetch: (verbose) => (0, quota_fetcher_codex_1.fetchAllCodexQuotas)(verbose),
        hasData: (result) => result.length > 0,
        render: (result) => displayCodexQuotaSection(result),
        emptyTitle: 'Codex (0 accounts)',
        emptyMessage: 'No Codex accounts configured',
        authCommand: 'ccs codex --auth',
    },
    claude: {
        fetch: (verbose) => (0, quota_fetcher_claude_1.fetchAllClaudeQuotas)(verbose),
        hasData: (result) => result.length > 0,
        render: (result) => displayClaudeQuotaSection(result),
        emptyTitle: 'Claude (0 accounts)',
        emptyMessage: 'No Claude accounts configured',
        authCommand: 'ccs claude --auth',
    },
    gemini: {
        fetch: (verbose) => (0, quota_fetcher_gemini_cli_1.fetchAllGeminiCliQuotas)(verbose),
        hasData: (result) => result.length > 0,
        render: (result) => displayGeminiCliQuotaSection(result),
        emptyTitle: 'Gemini CLI (0 accounts)',
        emptyMessage: 'No Gemini CLI accounts configured',
        authCommand: 'ccs gemini --auth',
    },
    ghcp: {
        fetch: (verbose) => (0, quota_fetcher_ghcp_1.fetchAllGhcpQuotas)(verbose),
        hasData: (result) => result.length > 0,
        render: (result) => displayGhcpQuotaSection(result),
        emptyTitle: 'GitHub Copilot (0 accounts)',
        emptyMessage: 'No GitHub Copilot accounts configured',
        authCommand: 'ccs ghcp --auth',
    },
};
exports.__testExports = {
    getQuotaFailureDisplayEntries,
    resolveDisplayedTier,
};
async function handleQuotaStatus(verbose = false, providerFilter = 'all') {
    await (0, ui_1.initUI)();
    console.log((0, ui_1.header)('Quota Status'));
    console.log('');
    const requestedProviders = new Set(providerFilter === 'all' ? provider_capabilities_1.QUOTA_SUPPORTED_PROVIDER_IDS : [providerFilter]);
    const shouldFetch = (provider) => requestedProviders.has(provider);
    console.log((0, ui_1.dim)('Fetching quotas...'));
    const providerResults = new Map(await Promise.all(provider_capabilities_1.QUOTA_SUPPORTED_PROVIDER_IDS.map(async (provider) => {
        if (!shouldFetch(provider)) {
            return [provider, null];
        }
        return [provider, await QUOTA_PROVIDER_RUNTIME[provider].fetch(verbose)];
    })));
    console.log('');
    for (const provider of provider_capabilities_1.QUOTA_SUPPORTED_PROVIDER_IDS) {
        if (!shouldFetch(provider)) {
            continue;
        }
        const runtime = QUOTA_PROVIDER_RUNTIME[provider];
        const result = providerResults.get(provider) ?? null;
        if (result !== null && runtime.hasData(result)) {
            runtime.render(result);
            continue;
        }
        console.log((0, ui_1.subheader)(runtime.emptyTitle));
        console.log((0, ui_1.info)(runtime.emptyMessage));
        console.log(`  Run: ${(0, ui_1.color)(runtime.authCommand, 'command')} to authenticate`);
        console.log('');
    }
}
exports.handleQuotaStatus = handleQuotaStatus;
async function handleDoctor(verbose = false) {
    await (0, ui_1.initUI)();
    console.log((0, ui_1.header)('CLIProxy Quota Diagnostics'));
    console.log('');
    const provider = 'agy';
    const accounts = (0, account_manager_1.getProviderAccounts)(provider);
    if (accounts.length === 0) {
        console.log((0, ui_1.info)('No Antigravity accounts configured'));
        console.log(`    Run: ${(0, ui_1.color)('ccs agy --auth', 'command')} to authenticate`);
        return;
    }
    console.log((0, ui_1.subheader)(`Antigravity Accounts (${accounts.length})`));
    console.log('');
    console.log((0, ui_1.dim)('Fetching quotas...'));
    const quotaResult = await (0, quota_fetcher_1.fetchAllProviderQuotas)(provider, verbose);
    for (const { account, quota } of quotaResult.accounts) {
        const accountLabel = formatCliAccountLabel(account);
        const defaultBadge = account.isDefault ? (0, ui_1.color)(' (default)', 'info') : '';
        if (!quota.success) {
            console.log(`  ${(0, ui_1.fail)(accountLabel)}${defaultBadge}`);
            displayQuotaFailure(quota);
            if (quota.isUnprovisioned) {
                console.log(`    ${(0, ui_1.warn)('Account not provisioned - open Gemini Code Assist in IDE first')}`);
            }
            console.log('');
            continue;
        }
        const avgQuota = quota.models.length > 0
            ? quota.models.reduce((sum, m) => sum + m.percentage, 0) / quota.models.length
            : 0;
        const statusIcon = avgQuota > 50 ? (0, ui_1.ok)('') : avgQuota > 10 ? (0, ui_1.warn)('') : (0, ui_1.fail)('');
        console.log(`  ${statusIcon}${accountLabel}${defaultBadge}`);
        if (quota.projectId) {
            console.log(`    Project: ${(0, ui_1.dim)(quota.projectId)}`);
        }
        for (const model of quota.models) {
            const bar = formatQuotaBar(model.percentage);
            console.log(`    ${model.name.padEnd(20)} ${bar} ${model.percentage.toFixed(0)}%`);
        }
        console.log('');
    }
    const sharedProjects = Object.entries(quotaResult.projectGroups).filter(([, accountIds]) => accountIds.length > 1);
    if (sharedProjects.length > 0) {
        console.log('');
        console.log((0, ui_1.subheader)('Shared Project Warning'));
        console.log('');
        for (const [projectId, accountIds] of sharedProjects) {
            console.log((0, ui_1.fail)(`Project ${projectId.substring(0, 20)}... shared by ${accountIds.length} accounts:`));
            for (const accountId of accountIds) {
                console.log(`    - ${accountId}`);
            }
            console.log('');
            console.log((0, ui_1.warn)('These accounts share the same quota pool!'));
            console.log((0, ui_1.warn)('Failover between them will NOT help when quota is exhausted.'));
            console.log((0, ui_1.info)('Solution: Use accounts from different GCP projects.'));
        }
    }
    console.log('');
    console.log((0, ui_1.subheader)('Summary'));
    const healthyAccounts = quotaResult.accounts.filter(({ quota }) => quota.success && quota.models.some((m) => m.percentage > 5));
    console.log(`  Accounts with quota: ${healthyAccounts.length}/${accounts.length}`);
    if (sharedProjects.length > 0) {
        console.log(`  ${(0, ui_1.fail)(`Shared projects: ${sharedProjects.length} (failover limited)`)}`);
    }
    else if (accounts.length > 1) {
        console.log(`  ${(0, ui_1.ok)('No shared projects (failover fully operational)')}`);
    }
    console.log('');
}
exports.handleDoctor = handleDoctor;
async function handleSetDefault(args) {
    await (0, ui_1.initUI)();
    const parsed = parseProfileArgs(args);
    if (!parsed.name) {
        console.log((0, ui_1.fail)('Usage: ccs cliproxy default <account> [--provider <provider>]'));
        console.log('');
        console.log('Examples:');
        console.log('  ccs cliproxy default ultra@gmail.com');
        console.log('  ccs cliproxy default john --provider agy');
        process.exit(1);
    }
    const provider = (parsed.provider || 'agy');
    const account = (0, account_manager_1.findAccountByQuery)(provider, parsed.name);
    if (!account) {
        console.log((0, ui_1.fail)(`Account not found: ${parsed.name}`));
        console.log('');
        const accounts = (0, account_manager_1.getProviderAccounts)(provider);
        if (accounts.length > 0) {
            console.log('Available accounts:');
            for (const acc of accounts) {
                const badge = acc.isDefault ? (0, ui_1.color)(' (current default)', 'info') : '';
                console.log(`  - ${formatCliAccountLabel(acc)}${badge}`);
            }
        }
        else {
            console.log(`No accounts found for provider: ${provider}`);
            console.log(`Run: ccs ${provider} --auth`);
        }
        process.exit(1);
    }
    const success = (0, account_manager_1.setDefaultAccount)(provider, account.id);
    if (success) {
        console.log((0, ui_1.ok)(`Default account set to: ${formatCliAccountLabel(account)}`));
        console.log((0, ui_1.info)(`Provider: ${provider}`));
    }
    else {
        console.log((0, ui_1.fail)('Failed to set default account'));
        process.exit(1);
    }
}
exports.handleSetDefault = handleSetDefault;
async function handlePauseAccount(args) {
    await (0, ui_1.initUI)();
    const parsed = parseProfileArgs(args);
    if (!parsed.name) {
        console.log((0, ui_1.fail)('Usage: ccs cliproxy pause <account> [--provider <provider>]'));
        console.log('');
        console.log('Pauses an account so it will be skipped in quota rotation.');
        process.exit(1);
    }
    const provider = (parsed.provider || 'agy');
    const account = (0, account_manager_1.findAccountByQuery)(provider, parsed.name);
    if (!account) {
        console.log((0, ui_1.fail)(`Account not found: ${parsed.name}`));
        process.exit(1);
    }
    if (account.paused) {
        console.log((0, ui_1.warn)(`Account already paused: ${formatCliAccountLabel(account)}`));
        console.log((0, ui_1.info)(`Paused at: ${account.pausedAt || 'unknown'}`));
        return;
    }
    const success = (0, account_manager_1.pauseAccount)(provider, account.id);
    if (success) {
        console.log((0, ui_1.ok)(`Account paused: ${formatCliAccountLabel(account)}`));
        console.log((0, ui_1.info)('Account will be skipped in quota rotation'));
    }
    else {
        console.log((0, ui_1.fail)('Failed to pause account'));
        process.exit(1);
    }
}
exports.handlePauseAccount = handlePauseAccount;
async function handleResumeAccount(args) {
    await (0, ui_1.initUI)();
    const parsed = parseProfileArgs(args);
    if (!parsed.name) {
        console.log((0, ui_1.fail)('Usage: ccs cliproxy resume <account> [--provider <provider>]'));
        console.log('');
        console.log('Resumes a paused account for quota rotation.');
        process.exit(1);
    }
    const provider = (parsed.provider || 'agy');
    const account = (0, account_manager_1.findAccountByQuery)(provider, parsed.name);
    if (!account) {
        console.log((0, ui_1.fail)(`Account not found: ${parsed.name}`));
        process.exit(1);
    }
    if (!account.paused) {
        console.log((0, ui_1.warn)(`Account is not paused: ${formatCliAccountLabel(account)}`));
        return;
    }
    const success = (0, account_manager_1.resumeAccount)(provider, account.id);
    if (success) {
        console.log((0, ui_1.ok)(`Account resumed: ${formatCliAccountLabel(account)}`));
        console.log((0, ui_1.info)('Account is now active in quota rotation'));
    }
    else {
        console.log((0, ui_1.fail)('Failed to resume account'));
        process.exit(1);
    }
}
exports.handleResumeAccount = handleResumeAccount;
//# sourceMappingURL=quota-subcommand.js.map