"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleWebSocketMessages = void 0;
const api_1 = require("@atproto/api");
const streamplace_1 = require("streamplace");
const system_messages_1 = require("../lib/system-messages");
const format_handle_1 = require("../utils/format-handle");
const chat_1 = require("./chat");
const problems_1 = require("./problems");
const MAX_RECENT_SEGMENTS = 10;
const handleWebSocketMessages = (state, messages) => {
    for (let message of messages) {
        if (message.$type === "place.stream.error") {
            state = {
                ...state,
                problems: [
                    ...state.problems,
                    {
                        code: message.code,
                        message: message.message,
                        severity: "error",
                    },
                ],
            };
        }
        else {
            if (!state.websocketConnected) {
                state = {
                    ...state,
                    websocketConnected: true,
                };
            }
            if (streamplace_1.PlaceStreamLivestream.isLivestreamView(message)) {
                const newLivestream = message;
                const oldLivestream = state.livestream;
                // check if this is actually new
                if (!oldLivestream || oldLivestream.uri !== newLivestream.uri) {
                    const streamTitle = newLivestream.record.title || "something cool!";
                    const systemMessage = system_messages_1.SystemMessages.streamStart(streamTitle);
                    // set proper times
                    systemMessage.indexedAt = newLivestream.indexedAt;
                    systemMessage.record.createdAt = newLivestream.record.createdAt;
                    state = (0, chat_1.reduceChat)(state, [systemMessage], []);
                }
                state = {
                    ...state,
                    livestream: newLivestream,
                };
            }
            else if (streamplace_1.PlaceStreamLivestream.isViewerCount(message)) {
                message = message;
                state = {
                    ...state,
                    viewers: message.count,
                };
            }
            else if (streamplace_1.PlaceStreamChatDefs.isMessageView(message)) {
                message = message;
                // Explicitly map MessageView to MessageViewHydrated
                const hydrated = {
                    uri: message.uri,
                    cid: message.cid,
                    author: message.author,
                    record: message.record,
                    indexedAt: message.indexedAt,
                    chatProfile: message.chatProfile,
                    replyTo: message.replyTo,
                    deleted: message.deleted,
                    badges: message.badges,
                };
                state = (0, chat_1.reduceChat)(state, [hydrated], [], []);
            }
            else if (streamplace_1.PlaceStreamSegment.isRecord(message)) {
                const newRecentSegments = [...state.recentSegments];
                newRecentSegments.unshift(message);
                if (newRecentSegments.length > MAX_RECENT_SEGMENTS) {
                    newRecentSegments.pop();
                }
                state = {
                    ...state,
                    segment: message,
                    recentSegments: newRecentSegments,
                    problems: (0, problems_1.findProblems)(newRecentSegments),
                    hasReceivedSegment: true,
                };
            }
            else if (streamplace_1.PlaceStreamDefs.isBlockView(message)) {
                const block = message;
                state = (0, chat_1.reduceChat)(state, [], [block], []);
            }
            else if (streamplace_1.PlaceStreamDefs.isRenditions(message)) {
                message = message;
                state = {
                    ...state,
                    renditions: message.renditions,
                };
            }
            else if (api_1.AppBskyActorDefs.isProfileViewBasic(message)) {
                state = {
                    ...state,
                    profile: message,
                };
            }
            else if (streamplace_1.PlaceStreamChatGate.isRecord(message)) {
                const hideRecord = message;
                const hiddenMessageUri = hideRecord.hiddenMessage;
                const newPendingHides = [...state.pendingHides];
                if (!newPendingHides.includes(hiddenMessageUri)) {
                    newPendingHides.push(hiddenMessageUri);
                }
                state = {
                    ...state,
                    pendingHides: newPendingHides,
                };
                state = (0, chat_1.reduceChat)(state, [], [], [hiddenMessageUri]);
            }
            else if (streamplace_1.PlaceStreamChatDefs.isPinnedRecordView(message)) {
                const pinnedView = message;
                state = {
                    ...state,
                    pinnedComment: pinnedView,
                };
            }
            else if (message.$type === "place.stream.chat.pinnedRecord" &&
                message.deleted === true) {
                state = {
                    ...state,
                    pinnedComment: null,
                };
            }
            else if (streamplace_1.PlaceStreamLiveTeleport.isRecord(message)) {
                const teleportRecord = message;
                state = {
                    ...state,
                    activeTeleport: teleportRecord,
                };
            }
            else if (streamplace_1.PlaceStreamLivestream.isTeleportArrival(message)) {
                // teleport has succeeded, we are now at the target stream
                const arrival = message;
                // add the teleporter's chat profile to the authors cache FIRST so mention rendering works
                if (arrival.chatProfile && arrival.source.did) {
                    state = {
                        ...state,
                        authors: {
                            ...state.authors,
                            [arrival.source.did]: arrival.chatProfile,
                        },
                    };
                }
                const systemMessage = system_messages_1.SystemMessages.teleportArrival((0, format_handle_1.formatHandleWithAt)(arrival.source), arrival.source.did, arrival.viewerCount, arrival.chatProfile);
                // set proper times
                systemMessage.indexedAt = arrival.startsAt;
                systemMessage.record.createdAt = arrival.startsAt;
                state = (0, chat_1.reduceChat)(state, [systemMessage], []);
            }
            else if (streamplace_1.PlaceStreamLivestream.isTeleportCanceled(message)) {
                // teleport was canceled (deleted or denied)
                state = {
                    ...state,
                    activeTeleport: null,
                    activeTeleportUri: null,
                };
            }
        }
    }
    return (0, chat_1.reduceChat)(state, [], [], []);
};
exports.handleWebSocketMessages = handleWebSocketMessages;
//# sourceMappingURL=websocket-consumer.js.map