import { parseChannelContextKey } from "./context-key.js";
export class ChannelMirrorRegistry {
    config;
    promptStore;
    states = new Map();
    constructor(config, promptStore) {
        this.config = config;
        this.promptStore = promptStore;
    }
    activeMirrorsForThread(agentId, threadId, knownContexts, preferences) {
        const mirrors = [];
        const seen = new Set();
        for (const meta of knownContexts) {
            const metaAgentId = meta.agentId ?? this.config.defaultAgent;
            if (meta.threadId !== threadId || metaAgentId !== agentId) {
                continue;
            }
            const source = activeSessionSourceForContextKey(meta.contextKey);
            if (!isMirrorChannelSource(source) || seen.has(meta.contextKey)) {
                continue;
            }
            const mode = this.effectiveMirrorMode(meta.contextKey, source, preferences);
            if (mode === "off") {
                this.states.delete(this.stateKey(source, meta.contextKey, agentId, threadId));
                continue;
            }
            seen.add(meta.contextKey);
            const mirror = {
                source,
                contextKey: meta.contextKey,
                mode,
                queueLength: this.promptStore.list(meta.contextKey).length,
                queuePaused: this.promptStore.isPaused(meta.contextKey),
            };
            mirrors.push(mirror);
            this.states.set(this.stateKey(source, meta.contextKey, agentId, threadId), {
                ...mirror,
                agentId,
                threadId,
                updatedAt: new Date().toISOString(),
            });
        }
        return mirrors;
    }
    queueLengthForExternalSource(sourceContextKey, mirrors) {
        return mirrors.reduce((sum, mirror) => sum + mirror.queueLength, this.promptStore.list(sourceContextKey).length);
    }
    queuePausedForExternalSource(sourceContextKey, mirrors) {
        return mirrors.some((mirror) => mirror.queuePaused) || this.promptStore.isPaused(sourceContextKey);
    }
    effectiveMirrorMode(contextKey, source, preferences) {
        const configured = configuredMirrorMode(this.config, source);
        return preferences.get(contextKey).mirrorMode ?? configured;
    }
    snapshot() {
        return [...this.states.values()].sort((left, right) => Date.parse(right.updatedAt) - Date.parse(left.updatedAt));
    }
    stateKey(source, contextKey, agentId, threadId) {
        return `${source}:${contextKey}:${agentId}:${threadId}`;
    }
}
export function activeSessionSourceForContextKey(contextKey) {
    const parsed = parseChannelContextKey(contextKey);
    if (parsed?.channelId === "peer" && parsed.topicId) {
        return activeSessionSourceForContextKey(parsed.topicId);
    }
    const channelId = parsed?.channelId ?? "cli";
    if (channelId === "telegram") {
        return "telegram";
    }
    if (channelId === "discord") {
        return "discord";
    }
    if (channelId === "slack") {
        return "slack";
    }
    if (channelId === "matrix") {
        return "matrix";
    }
    if (channelId === "web") {
        return "web";
    }
    return "cli";
}
export function isMirrorChannelSource(source) {
    return source === "telegram" || source === "discord" || source === "slack" || source === "matrix" || source === "web";
}
function configuredMirrorMode(config, source) {
    if (source === "telegram") {
        return config.telegramMirrorMode;
    }
    if (source === "discord") {
        return config.discordMirrorMode;
    }
    if (source === "slack") {
        return config.slackMirrorMode;
    }
    if (source === "matrix") {
        return config.matrixMirrorMode;
    }
    return config.webMirrorMode;
}
