import { loadRoutingInstructionStateSync, saveRoutingInstructionStateSync } from '../../../router/virtual-router/sticky-session-store.js';
import { countRequestTokens } from '../../../router/virtual-router/token-counter.js';
function createEmptyRoutingInstructionState() {
    return {
        allowedProviders: new Set(),
        disabledProviders: new Set(),
        disabledKeys: new Map(),
        disabledModels: new Map()
    };
}
function resolveSessionUsageScope(record) {
    const sessionId = typeof record?.sessionId === 'string' ? record.sessionId.trim() : '';
    if (sessionId) {
        return `session:${sessionId}`;
    }
    const conversationId = typeof record?.conversationId === 'string' ? record.conversationId.trim() : '';
    if (conversationId) {
        return `conversation:${conversationId}`;
    }
    return undefined;
}
function loadState(scope) {
    try {
        return loadRoutingInstructionStateSync(scope);
    }
    catch {
        return null;
    }
}
function readRoundedToken(value) {
    if (typeof value !== 'number' || !Number.isFinite(value)) {
        return undefined;
    }
    const rounded = Math.round(value);
    return rounded > 0 ? rounded : undefined;
}
function buildSnapshot(scope, state) {
    if (!state) {
        return null;
    }
    const totalTokens = readRoundedToken(state.chatProcessLastTotalTokens);
    const inputTokens = readRoundedToken(state.chatProcessLastInputTokens);
    const messageCount = readRoundedToken(state.chatProcessLastMessageCount);
    const updatedAtMs = readRoundedToken(state.chatProcessLastUpdatedAt);
    if (totalTokens === undefined && inputTokens === undefined) {
        return null;
    }
    return {
        scope,
        ...(totalTokens !== undefined ? { totalTokens } : {}),
        ...(inputTokens !== undefined ? { inputTokens } : {}),
        ...(messageCount !== undefined ? { messageCount } : {}),
        ...(updatedAtMs !== undefined ? { updatedAtMs } : {})
    };
}
function normalizeUsage(usage) {
    if (!usage || typeof usage !== 'object') {
        return null;
    }
    const inputTokens = readRoundedToken(usage.input_tokens ??
        usage.prompt_tokens ??
        usage.inputTokens ??
        usage.promptTokens ??
        usage.request_tokens ??
        usage.requestTokens);
    const outputTokens = readRoundedToken(usage.output_tokens ??
        usage.completion_tokens ??
        usage.outputTokens ??
        usage.completionTokens ??
        usage.response_tokens ??
        usage.responseTokens);
    const totalTokens = readRoundedToken(usage.total_tokens ??
        usage.totalTokens ??
        ((inputTokens ?? 0) + (outputTokens ?? 0) > 0
            ? (inputTokens ?? 0) + (outputTokens ?? 0)
            : undefined));
    if (totalTokens === undefined && inputTokens === undefined) {
        return null;
    }
    return {
        ...(inputTokens !== undefined ? { inputTokens } : {}),
        ...(outputTokens !== undefined ? { outputTokens } : {}),
        ...(totalTokens !== undefined ? { totalTokens } : {})
    };
}
function estimateDeltaTokens(request, previousMessageCount) {
    const messages = Array.isArray(request.messages) ? request.messages : [];
    if (previousMessageCount < 0 || previousMessageCount > messages.length) {
        return undefined;
    }
    const appendedMessages = messages.slice(previousMessageCount);
    if (appendedMessages.length === 0) {
        return 0;
    }
    return countRequestTokens({
        model: request.model,
        messages: appendedMessages,
        parameters: {},
        metadata: { originalEndpoint: request.metadata?.originalEndpoint ?? '/v1/chat/completions' }
    });
}
export function estimateSessionBoundTokens(request, metadata) {
    const scope = resolveSessionUsageScope(metadata);
    if (!scope) {
        return undefined;
    }
    const snapshot = buildSnapshot(scope, loadState(scope));
    if (!snapshot) {
        return undefined;
    }
    const previousTotal = snapshot.totalTokens ?? snapshot.inputTokens;
    const previousMessageCount = snapshot.messageCount;
    if (previousTotal === undefined || previousMessageCount === undefined) {
        return undefined;
    }
    const deltaTokens = estimateDeltaTokens(request, previousMessageCount);
    if (deltaTokens === undefined) {
        return undefined;
    }
    return Math.max(1, Math.round(previousTotal + deltaTokens));
}
export function saveChatProcessSessionActualUsage(options) {
    const scope = resolveSessionUsageScope(options.context);
    if (!scope) {
        return;
    }
    const normalizedUsage = normalizeUsage(options.usage);
    if (!normalizedUsage) {
        return;
    }
    const capturedChatRequest = options.context.capturedChatRequest;
    const messageCount = Array.isArray(capturedChatRequest?.messages)
        ? (capturedChatRequest.messages ?? []).length
        : undefined;
    const state = loadState(scope) ?? createEmptyRoutingInstructionState();
    if (normalizedUsage.totalTokens !== undefined) {
        state.chatProcessLastTotalTokens = normalizedUsage.totalTokens;
    }
    if (normalizedUsage.inputTokens !== undefined) {
        state.chatProcessLastInputTokens = normalizedUsage.inputTokens;
    }
    if (typeof messageCount === 'number' && Number.isFinite(messageCount)) {
        state.chatProcessLastMessageCount = Math.max(0, Math.round(messageCount));
    }
    state.chatProcessLastUpdatedAt = Date.now();
    saveRoutingInstructionStateSync(scope, state);
}
