"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseSystemMessageMetadata = exports.getSystemMessageType = exports.isSystemMessage = exports.SystemMessages = exports.createSystemMessage = exports.SystemMessageType = void 0;
var SystemMessageType;
(function (SystemMessageType) {
    SystemMessageType["stream_start"] = "stream_start";
    SystemMessageType["stream_end"] = "stream_end";
    SystemMessageType["notification"] = "notification";
    SystemMessageType["command_error"] = "command_error";
})(SystemMessageType || (exports.SystemMessageType = SystemMessageType = {}));
/**
 * Creates a system message with the proper structure
 * @param type The type of system message
 * @param text The message text
 * @param metadata Optional metadata for the message
 * @returns A properly formatted ChatMessageViewHydrated object
 */
let systemMessageCounter = 0;
const createSystemMessage = (type, text, metadata, date = new Date()) => {
    const now = date;
    const uniqueId = `${now.getTime()}-${systemMessageCounter++}`;
    return {
        uri: `at://did:sys:system/place.stream.chat.message/${uniqueId}`,
        cid: `system-${uniqueId}`,
        author: {
            did: "did:sys:system",
            handle: type, // Use handle to specify the type of system message
        },
        record: {
            text,
            createdAt: now.toISOString(),
            streamer: "system",
            $type: "place.stream.chat.message",
        },
        indexedAt: now.toISOString(),
        chatProfile: {
            color: { red: 128, green: 128, blue: 128 }, // Gray color for system messages
            $type: "place.stream.chat.profile",
        },
    };
};
exports.createSystemMessage = createSystemMessage;
/**
 * System message factory functions for common scenarios
 */
exports.SystemMessages = {
    streamStart: (streamerName) => (0, exports.createSystemMessage)(SystemMessageType.stream_start, `Now streaming - ${streamerName}`, {
        streamerName,
    }),
    // technically, streams can't 'end' on Streamplace
    // possibly we could use deleting or editing streams (`endedAt` param) for this?
    streamEnd: (duration) => (0, exports.createSystemMessage)(SystemMessageType.stream_end, duration ? `Stream has ended. Duration: ${duration}` : "Stream has ended", { duration }),
    teleportArrival: (streamerName, streamerDid, count, chatProfile) => {
        const text = count > 0
            ? `${count} viewer${count !== 1 ? "s" : ""} teleported from ${streamerName}'s stream! Say hi!`
            : `Someone teleported from ${streamerName}'s stream! Say hi!`;
        const message = (0, exports.createSystemMessage)(SystemMessageType.notification, text, {
            streamerName,
            count,
        });
        // create a mention facet for the streamer name so it gets colored using existing mention rendering
        if (chatProfile && streamerDid) {
            const nameStart = text.indexOf(streamerName);
            // encode byte positions
            const encoder = new TextEncoder();
            const byteStart = encoder.encode(text.substring(0, nameStart)).length;
            const byteEnd = byteStart + encoder.encode(streamerName).length;
            message.record.facets = [
                {
                    index: {
                        byteStart,
                        byteEnd,
                    },
                    features: [
                        {
                            $type: "app.bsky.richtext.facet#mention",
                            did: streamerDid,
                        },
                    ],
                },
            ];
        }
        return message;
    },
    notification: (message) => (0, exports.createSystemMessage)(SystemMessageType.notification, message),
    commandError: (message) => (0, exports.createSystemMessage)(SystemMessageType.command_error, message),
};
/**
 * Checks if a message is a system message
 * @param message The message to check
 * @returns True if the message is a system message
 */
const isSystemMessage = (message) => {
    return message.author.did === "did:sys:system";
};
exports.isSystemMessage = isSystemMessage;
/**
 * Gets the system message type from a message
 * @param message The message to check
 * @returns The system message type or null if not a system message
 */
const getSystemMessageType = (message) => {
    if (!(0, exports.isSystemMessage)(message)) {
        return null;
    }
    return message.author.handle;
};
exports.getSystemMessageType = getSystemMessageType;
/**
 * Parses metadata from a system message based on its type
 * @param message The system message to parse
 * @returns The parsed metadata
 */
const parseSystemMessageMetadata = (message) => {
    const metadata = {};
    const type = (0, exports.getSystemMessageType)(message);
    const text = message.record.text;
    if (!type)
        return metadata;
    switch (type) {
        case "stream_end": {
            const durationMatch = text.match(/Duration:\s*(\d+:\d+(?::\d+)?)/);
            if (durationMatch) {
                metadata.duration = durationMatch[1];
            }
            break;
        }
        case "stream_start": {
            const streamerMatch = text.match(/^(.+?)\s+is now live!/);
            if (streamerMatch) {
                metadata.streamerName = streamerMatch[1];
            }
            break;
        }
    }
    return metadata;
};
exports.parseSystemMessageMetadata = parseSystemMessageMetadata;
//# sourceMappingURL=system-messages.js.map