import { parsePeerRuntimeContextKey } from "../../peers/peer-context.js";
export function telegramContextKeyFromMessage(chatId, messageThreadId) {
    if (messageThreadId !== undefined) {
        return `${chatId}:${messageThreadId}`;
    }
    return `${chatId}`;
}
export function telegramContextKeyFromCtx(ctx) {
    const chatId = ctx.chat?.id;
    if (chatId === undefined) {
        return null;
    }
    const threadId = ctx.message?.message_thread_id ?? ctx.callbackQuery?.message?.message_thread_id;
    return telegramContextKeyFromMessage(chatId, threadId);
}
export function parseTelegramContextKey(key) {
    const parts = key.split(":");
    const chatId = Number(parts[0]);
    const messageThreadId = parts[1] ? Number(parts[1]) : undefined;
    return { chatId, messageThreadId };
}
export function contextKeyFromMessage(chatId, messageThreadId) {
    return telegramContextKeyFromMessage(chatId, messageThreadId);
}
export function contextKeyFromCtx(ctx) {
    return telegramContextKeyFromCtx(ctx);
}
export function parseContextKey(key) {
    return parseTelegramContextKey(key);
}
export function isTopicContextKey(key) {
    const parsed = parseChannelContextKey(key);
    return Boolean(parsed?.topicId);
}
export function isTelegramContextKey(key) {
    const parts = key.split(":");
    if (parts.length < 1 || parts.length > 2) {
        return false;
    }
    const chatIdText = parts[0];
    if (!chatIdText || !/^-?\d+$/.test(chatIdText)) {
        return false;
    }
    const chatId = Number(chatIdText);
    if (!Number.isSafeInteger(chatId) || chatId === 0) {
        return false;
    }
    const threadIdText = parts[1];
    if (threadIdText === undefined) {
        return true;
    }
    if (!/^\d+$/.test(threadIdText)) {
        return false;
    }
    const threadId = Number(threadIdText);
    return Number.isSafeInteger(threadId) && threadId > 0;
}
export function discordContextKey(input) {
    const guildId = input.guildId || "dm";
    const topic = input.threadId && input.threadId !== input.channelId ? `:${input.threadId}` : "";
    return `discord:${guildId}:${input.channelId}${topic}`;
}
export function isDiscordContextKey(key) {
    return /^discord:[^:]+:[^:]+(?::[^:]+)?$/.test(key);
}
export function parseDiscordContextKey(key) {
    if (!isDiscordContextKey(key)) {
        return null;
    }
    const [, guild, channelId, threadId] = key.split(":");
    if (!channelId) {
        return null;
    }
    return {
        guildId: guild === "dm" ? undefined : guild,
        channelId,
        threadId,
    };
}
export function slackContextKey(input) {
    const teamId = input.teamId || "team";
    const thread = input.threadTs && input.threadTs !== input.channelId ? `:${input.threadTs}` : "";
    return `slack:${teamId}:${input.channelId}${thread}`;
}
export function isSlackContextKey(key) {
    return /^slack:[^:]+:[^:]+(?::[^:]+)?$/.test(key);
}
export function parseSlackContextKey(key) {
    if (!isSlackContextKey(key)) {
        return null;
    }
    const [, team, channelId, threadTs] = key.split(":");
    if (!channelId) {
        return null;
    }
    return {
        teamId: team === "team" ? undefined : team,
        channelId,
        threadTs,
    };
}
export function matrixContextKey(input) {
    const homeserver = input.homeserver || "homeserver";
    const thread = input.threadId && input.threadId !== input.roomId ? `:${encodeContextPart(input.threadId)}` : "";
    return `matrix:${encodeContextPart(homeserver)}:${encodeContextPart(input.roomId)}${thread}`;
}
export function isMatrixContextKey(key) {
    return /^matrix:[^:]+:[^:]+(?::[^:]+)?$/.test(key);
}
export function parseMatrixContextKey(key) {
    if (!isMatrixContextKey(key)) {
        return null;
    }
    const [, homeserverRaw, roomRaw, threadRaw] = key.split(":");
    const roomId = decodeContextPart(roomRaw ?? "");
    if (!roomId) {
        return null;
    }
    const homeserver = decodeContextPart(homeserverRaw ?? "");
    return {
        homeserver: homeserver === "homeserver" ? undefined : homeserver,
        roomId,
        threadId: threadRaw ? decodeContextPart(threadRaw) : undefined,
    };
}
export function parseChannelContextKey(key) {
    const rawKey = String(key);
    if (isTelegramContextKey(rawKey)) {
        const parsed = parseTelegramContextKey(rawKey);
        return {
            channelId: "telegram",
            contextKey: rawKey,
            chatId: String(parsed.chatId),
            topicId: parsed.messageThreadId === undefined ? undefined : String(parsed.messageThreadId),
        };
    }
    const discord = parseDiscordContextKey(rawKey);
    if (discord) {
        return {
            channelId: "discord",
            contextKey: rawKey,
            chatId: discord.channelId,
            topicId: discord.threadId,
            guildId: discord.guildId,
        };
    }
    const slack = parseSlackContextKey(rawKey);
    if (slack) {
        return {
            channelId: "slack",
            contextKey: rawKey,
            chatId: slack.channelId,
            topicId: slack.threadTs,
            guildId: slack.teamId,
        };
    }
    const matrix = parseMatrixContextKey(rawKey);
    if (matrix) {
        return {
            channelId: "matrix",
            contextKey: rawKey,
            chatId: matrix.roomId,
            topicId: matrix.threadId,
            guildId: matrix.homeserver,
        };
    }
    if (rawKey.startsWith("web:")) {
        return {
            channelId: "web",
            contextKey: rawKey,
            chatId: rawKey.slice("web:".length) || "dashboard",
        };
    }
    if (rawKey.startsWith("cli:")) {
        return {
            channelId: "cli",
            contextKey: rawKey,
            chatId: rawKey.slice("cli:".length) || "local",
        };
    }
    const peer = parsePeerRuntimeContextKey(rawKey);
    if (peer) {
        return {
            channelId: "peer",
            contextKey: rawKey,
            chatId: peer.peerId,
            topicId: peer.sourceContextKey,
        };
    }
    return null;
}
function encodeContextPart(value) {
    return Buffer.from(value, "utf8").toString("base64url");
}
function decodeContextPart(value) {
    try {
        return Buffer.from(value, "base64url").toString("utf8");
    }
    catch {
        return "";
    }
}
export function channelIdForContextKey(key) {
    return parseChannelContextKey(key)?.channelId ?? "cli";
}
