import { openCommentsFeedback } from "../editor/reviews/openCommentsFeedback";
import { clearPendingFeedbackFocus, feedbackIdsEqual, setPendingFeedbackFocus, } from "../editor/reviews/pendingFeedbackFocus";
const TASKBOARD_PROJECT_QUERY_KEY = "tbProjectId";
const TASKBOARD_TASK_QUERY_KEY = "tbTaskId";
const TASKBOARD_VIEW_QUERY_KEY = "tbView";
const TASKBOARD_WIZARD_QUERY_KEY = "tbWizard";
const EDITOR_ITEM_QUERY_KEY = "itemid";
const EDITOR_LANGUAGE_QUERY_KEYS = ["lang", "language"];
const EDITOR_VERSION_QUERY_KEY = "version";
const REVIEW_SIDEBAR_ID = "reviews";
function asNotificationRecord(value) {
    if (!value || typeof value !== "object" || Array.isArray(value))
        return null;
    return value;
}
function getNotificationStringField(record, key) {
    if (!record)
        return null;
    const value = record[key];
    if (typeof value !== "string")
        return null;
    const trimmed = value.trim();
    return trimmed.length > 0 ? trimmed : null;
}
function replaceNotificationUrlParams(params) {
    if (typeof window === "undefined")
        return;
    const currentParams = new URLSearchParams(window.location.search);
    for (const [key, value] of Object.entries(params)) {
        if (value)
            currentParams.set(key, value);
        else
            currentParams.delete(key);
    }
    const queryString = currentParams.toString();
    const newUrl = queryString
        ? `${window.location.pathname}?${queryString}`
        : window.location.pathname;
    window.history.replaceState(null, "", newUrl);
    window.dispatchEvent(new PopStateEvent("popstate"));
}
function clearEditorUrlParams() {
    return {
        [EDITOR_ITEM_QUERY_KEY]: undefined,
        [EDITOR_LANGUAGE_QUERY_KEYS[0]]: undefined,
        [EDITOR_LANGUAGE_QUERY_KEYS[1]]: undefined,
        [EDITOR_VERSION_QUERY_KEY]: undefined,
    };
}
function createWorkspaceNotificationRoute(options) {
    const { workspaceId, parseContext, buildParams, openSidebars = [] } = options;
    return {
        parseContext,
        open: async (editContext, context) => {
            if (editContext.workspaceId !== workspaceId) {
                editContext.switchWorkspace(workspaceId, {
                    skipNavigationHistory: true,
                });
            }
            for (const sidebarId of openSidebars) {
                editContext.openSidebar(sidebarId);
            }
            replaceNotificationUrlParams({
                workspace: workspaceId,
                ...(workspaceId === "editor" ? {} : clearEditorUrlParams()),
                ...buildParams(context),
            });
            return true;
        },
    };
}
function parseItemNotificationContext(context) {
    const record = asNotificationRecord(context);
    const itemId = getNotificationStringField(record, "itemId");
    if (!itemId)
        return null;
    const language = getNotificationStringField(record, "language") ?? undefined;
    const versionValue = getNotificationStringField(record, "version");
    const version = versionValue && Number.isFinite(Number(versionValue))
        ? Number(versionValue)
        : undefined;
    return { itemId, language, version };
}
function parseItemFeedbackNotificationContext(context) {
    const base = parseItemNotificationContext(context);
    if (!base)
        return null;
    const record = asNotificationRecord(context);
    return {
        ...base,
        commentId: getNotificationStringField(record, "commentId") ?? undefined,
        suggestedEditId: getNotificationStringField(record, "suggestedEditId") ?? undefined,
    };
}
/**
 * Navigate the editor workspace to the notification's item and sync the URL.
 * Returns the loaded item descriptor, or null if the item could not load.
 */
async function openItemInEditor(editContext, context) {
    if (editContext.workspaceId !== "editor") {
        editContext.switchWorkspace("editor", { skipNavigationHistory: true });
    }
    const loaded = await editContext.loadItem(context.language
        ? {
            id: context.itemId,
            language: context.language,
            version: context.version ?? 0,
        }
        : context.itemId);
    if (!loaded)
        return null;
    const loadedDescriptor = (loaded.descriptor ?? loaded);
    replaceNotificationUrlParams({
        workspace: "editor",
        itemid: context.itemId,
        lang: context.language,
        language: undefined,
        version: context.version != null
            ? String(context.version)
            : loadedDescriptor?.version != null
                ? String(loadedDescriptor.version)
                : undefined,
        reviewId: undefined,
        [TASKBOARD_PROJECT_QUERY_KEY]: undefined,
        [TASKBOARD_TASK_QUERY_KEY]: undefined,
        [TASKBOARD_VIEW_QUERY_KEY]: undefined,
        [TASKBOARD_WIZARD_QUERY_KEY]: undefined,
    });
    return loadedDescriptor;
}
/**
 * Open a comment/suggestion notification: navigate to the item, open the
 * comments & suggestions panel, and focus the specific entry once it loads.
 */
async function openItemFeedbackNotification(editContext, context) {
    openCommentsFeedback(editContext);
    const focus = context.commentId
        ? { kind: "comment", id: context.commentId }
        : context.suggestedEditId
            ? { kind: "suggestion", id: context.suggestedEditId }
            : null;
    if (focus)
        setPendingFeedbackFocus(focus);
    const before = editContext.currentItemDescriptor;
    const loadedDescriptor = await openItemInEditor(editContext, context);
    if (!loadedDescriptor) {
        if (focus)
            clearPendingFeedbackFocus(focus);
        return false;
    }
    // When the target item was already loaded, no descriptor change fires the
    // feedback refetch — and the entry the notification points at may be missing
    // locally if its socket message was missed. Refetch to be safe.
    const wasAlreadyOnItem = !!before &&
        feedbackIdsEqual(before.id, loadedDescriptor.id) &&
        before.language === loadedDescriptor.language &&
        before.version === loadedDescriptor.version;
    if (wasAlreadyOnItem) {
        editContext.loadComments?.();
        editContext.loadSuggestedEdits?.();
    }
    return true;
}
function parseReviewNotificationContext(context) {
    const record = asNotificationRecord(context);
    const reviewId = getNotificationStringField(record, "reviewId");
    if (!reviewId)
        return null;
    return { reviewId };
}
function parseTaskNotificationContext(context) {
    const record = asNotificationRecord(context);
    const projectId = getNotificationStringField(record, "projectId");
    if (!projectId)
        return null;
    const taskId = getNotificationStringField(record, "taskId") ?? undefined;
    return { projectId, taskId };
}
function parseMentionNotificationContext(context) {
    const record = asNotificationRecord(context);
    const targetType = getNotificationStringField(record, "targetType")?.toLowerCase();
    if (targetType === "task") {
        const projectId = getNotificationStringField(record, "projectId");
        if (!projectId)
            return null;
        const taskId = getNotificationStringField(record, "taskId") ??
            getNotificationStringField(record, "targetId") ??
            undefined;
        return { targetType: "task", projectId, taskId };
    }
    const itemContext = parseItemFeedbackNotificationContext(context);
    if (!itemContext)
        return null;
    return { targetType: "item", ...itemContext };
}
function parseAgentNotificationContext(context) {
    const record = asNotificationRecord(context);
    const agentId = getNotificationStringField(record, "agentId");
    if (!agentId)
        return null;
    return { agentId };
}
export const coreNotificationRoutes = {
    "item-changed": {
        parseContext: parseItemNotificationContext,
        open: async (editContext, context) => Boolean(await openItemInEditor(editContext, context)),
    },
    feedback: {
        parseContext: parseItemFeedbackNotificationContext,
        open: openItemFeedbackNotification,
    },
    mention: {
        parseContext: parseMentionNotificationContext,
        open: async (editContext, context) => {
            if (context.targetType === "task") {
                if (editContext.workspaceId !== "taskboard") {
                    editContext.switchWorkspace("taskboard", {
                        skipNavigationHistory: true,
                    });
                }
                replaceNotificationUrlParams({
                    workspace: "taskboard",
                    ...clearEditorUrlParams(),
                    reviewId: undefined,
                    [TASKBOARD_PROJECT_QUERY_KEY]: context.projectId,
                    [TASKBOARD_TASK_QUERY_KEY]: context.taskId,
                    [TASKBOARD_VIEW_QUERY_KEY]: undefined,
                    [TASKBOARD_WIZARD_QUERY_KEY]: undefined,
                });
                return true;
            }
            return openItemFeedbackNotification(editContext, context);
        },
    },
    "review-invitation": createWorkspaceNotificationRoute({
        workspaceId: "editor",
        parseContext: parseReviewNotificationContext,
        openSidebars: [REVIEW_SIDEBAR_ID],
        buildParams: ({ reviewId }) => ({
            reviewId,
            [TASKBOARD_PROJECT_QUERY_KEY]: undefined,
            [TASKBOARD_TASK_QUERY_KEY]: undefined,
        }),
    }),
    "review-completed": createWorkspaceNotificationRoute({
        workspaceId: "editor",
        parseContext: parseReviewNotificationContext,
        openSidebars: [REVIEW_SIDEBAR_ID],
        buildParams: ({ reviewId }) => ({
            reviewId,
            [TASKBOARD_PROJECT_QUERY_KEY]: undefined,
            [TASKBOARD_TASK_QUERY_KEY]: undefined,
        }),
    }),
    "review-rejected": createWorkspaceNotificationRoute({
        workspaceId: "editor",
        parseContext: parseReviewNotificationContext,
        openSidebars: [REVIEW_SIDEBAR_ID],
        buildParams: ({ reviewId }) => ({
            reviewId,
            [TASKBOARD_PROJECT_QUERY_KEY]: undefined,
            [TASKBOARD_TASK_QUERY_KEY]: undefined,
        }),
    }),
    "project-attention-required": createWorkspaceNotificationRoute({
        workspaceId: "taskboard",
        parseContext: parseTaskNotificationContext,
        buildParams: ({ projectId, taskId }) => ({
            reviewId: undefined,
            [TASKBOARD_PROJECT_QUERY_KEY]: projectId,
            [TASKBOARD_TASK_QUERY_KEY]: taskId,
            [TASKBOARD_VIEW_QUERY_KEY]: undefined,
        }),
    }),
    "project-task-completed": createWorkspaceNotificationRoute({
        workspaceId: "taskboard",
        parseContext: parseTaskNotificationContext,
        buildParams: ({ projectId, taskId }) => ({
            reviewId: undefined,
            [TASKBOARD_PROJECT_QUERY_KEY]: projectId,
            [TASKBOARD_TASK_QUERY_KEY]: taskId,
            [TASKBOARD_VIEW_QUERY_KEY]: undefined,
        }),
    }),
    "project-finished": createWorkspaceNotificationRoute({
        workspaceId: "taskboard",
        parseContext: parseTaskNotificationContext,
        buildParams: ({ projectId, taskId }) => ({
            reviewId: undefined,
            [TASKBOARD_PROJECT_QUERY_KEY]: projectId,
            [TASKBOARD_TASK_QUERY_KEY]: taskId,
            [TASKBOARD_VIEW_QUERY_KEY]: undefined,
        }),
    }),
    "task-assigned": createWorkspaceNotificationRoute({
        workspaceId: "taskboard",
        parseContext: parseTaskNotificationContext,
        buildParams: ({ projectId, taskId }) => ({
            reviewId: undefined,
            [TASKBOARD_PROJECT_QUERY_KEY]: projectId,
            [TASKBOARD_TASK_QUERY_KEY]: taskId,
            [TASKBOARD_VIEW_QUERY_KEY]: undefined,
        }),
    }),
    "task-status-changed": createWorkspaceNotificationRoute({
        workspaceId: "taskboard",
        parseContext: parseTaskNotificationContext,
        buildParams: ({ projectId, taskId }) => ({
            reviewId: undefined,
            [TASKBOARD_PROJECT_QUERY_KEY]: projectId,
            [TASKBOARD_TASK_QUERY_KEY]: taskId,
            [TASKBOARD_VIEW_QUERY_KEY]: undefined,
        }),
    }),
    "agent-notification": createWorkspaceNotificationRoute({
        workspaceId: "agents",
        parseContext: parseAgentNotificationContext,
        buildParams: ({ agentId }) => ({
            reviewId: undefined,
            [TASKBOARD_PROJECT_QUERY_KEY]: undefined,
            [TASKBOARD_TASK_QUERY_KEY]: undefined,
            [TASKBOARD_VIEW_QUERY_KEY]: undefined,
            [TASKBOARD_WIZARD_QUERY_KEY]: undefined,
            agentId,
        }),
    }),
};
//# sourceMappingURL=notificationRoutes.js.map