import { toast } from "sonner";
import uuid from "react-uuid";
import { getComponentById } from "../componentTreeHelper";
import { computeReorderTarget } from "./reorderComponent";
function getHistoryEntries(context, favoritesOnly, options) {
    const browseHistory = context.editContext.browseHistory;
    if (!favoritesOnly)
        return browseHistory;
    const favorites = context.editContext.favorites;
    if (!favorites) {
        if (!options?.silent) {
            toast.info("Favorites not loaded yet");
        }
        return undefined;
    }
    const favoriteIds = new Set(favorites.map((favorite) => `${favorite.itemId}:${favorite.language}`));
    const filteredHistory = browseHistory.filter((historyItem) => favoriteIds.has(`${historyItem.id}:${historyItem.language}`));
    if (filteredHistory.length === 0) {
        if (!options?.silent) {
            toast.info("No favorite items found in browse history");
        }
        return undefined;
    }
    return filteredHistory;
}
async function navigateHistory(context, direction, favoritesOnly) {
    const currentItem = context.editContext.item;
    if (!currentItem)
        return;
    const historyToNavigate = getHistoryEntries(context, favoritesOnly);
    if (!historyToNavigate)
        return;
    const currentIndex = historyToNavigate.findIndex((entry) => entry.id === currentItem.id && entry.language === currentItem.language);
    const targetEntry = direction === "forward"
        ? currentIndex < historyToNavigate.length - 1
            ? historyToNavigate[currentIndex + 1]
            : undefined
        : currentIndex > 0
            ? historyToNavigate[currentIndex - 1]
            : undefined;
    if (!targetEntry)
        return;
    await context.editContext.loadItem({
        id: targetEntry.id,
        language: targetEntry.language,
        version: targetEntry.version || 0,
    }, { addToBrowseHistory: false });
}
export const toggleInsertModeCommand = {
    id: "toggleInsertMode",
    label: "Toggle Insert Mode",
    icon: null,
    keyBinding: {
        key: "Insert",
    },
    disabled: () => false,
    execute: async (context) => {
        context.editContext.setInsertMode((current) => !current);
    },
};
export const historyForwardCommand = {
    id: "historyForward",
    label: "History Forward",
    icon: null,
    keyBinding: {
        key: "ArrowLeft",
        alt: true,
    },
    disabled: (context) => {
        const currentItem = context.editContext.item;
        if (!currentItem)
            return true;
        return (context.editContext.browseHistory.findIndex((entry) => entry.id === currentItem.id &&
            entry.language === currentItem.language) >=
            context.editContext.browseHistory.length - 1);
    },
    execute: async (context) => {
        await navigateHistory(context, "forward", false);
    },
};
export const historyBackCommand = {
    id: "historyBack",
    label: "History Back",
    icon: null,
    keyBinding: {
        key: "ArrowRight",
        alt: true,
    },
    disabled: (context) => {
        const currentItem = context.editContext.item;
        if (!currentItem)
            return true;
        return (context.editContext.browseHistory.findIndex((entry) => entry.id === currentItem.id &&
            entry.language === currentItem.language) <= 0);
    },
    execute: async (context) => {
        await navigateHistory(context, "back", false);
    },
};
export const favoriteHistoryForwardCommand = {
    id: "favoriteHistoryForward",
    label: "Favorite History Forward",
    icon: null,
    keyBinding: {
        key: "ArrowLeft",
        alt: true,
        shift: true,
    },
    disabled: (context) => {
        const historyToNavigate = getHistoryEntries(context, true, {
            silent: true,
        });
        const currentItem = context.editContext.item;
        if (!historyToNavigate || !currentItem)
            return true;
        return (historyToNavigate.findIndex((entry) => entry.id === currentItem.id &&
            entry.language === currentItem.language) >=
            historyToNavigate.length - 1);
    },
    execute: async (context) => {
        await navigateHistory(context, "forward", true);
    },
};
export const favoriteHistoryBackCommand = {
    id: "favoriteHistoryBack",
    label: "Favorite History Back",
    icon: null,
    keyBinding: {
        key: "ArrowRight",
        alt: true,
        shift: true,
    },
    disabled: (context) => {
        const historyToNavigate = getHistoryEntries(context, true, {
            silent: true,
        });
        const currentItem = context.editContext.item;
        if (!historyToNavigate || !currentItem)
            return true;
        return (historyToNavigate.findIndex((entry) => entry.id === currentItem.id &&
            entry.language === currentItem.language) <= 0);
    },
    execute: async (context) => {
        await navigateHistory(context, "back", true);
    },
};
function resolveComponentReorder(editContext, direction) {
    const page = editContext.page;
    if (!page || !page.item.canWriteItem)
        return null;
    const selection = editContext.selection ?? [];
    if (selection.length !== 1)
        return null;
    const component = getComponentById(selection[0], page);
    const placeholder = component?.parentPlaceholder;
    if (!component || !placeholder)
        return null;
    // Layout components are only reorderable when they are shown/editable.
    if (component.layoutId && !editContext.showLayoutComponents)
        return null;
    const target = computeReorderTarget(placeholder.components, component.id, direction);
    if (!target)
        return null;
    return {
        component,
        placeholderKey: placeholder.key,
        mainItem: page.item.descriptor,
        target,
    };
}
function buildReorderCommand(direction) {
    const isUp = direction === "up";
    return {
        id: isUp ? "moveComponentUp" : "moveComponentDown",
        label: isUp ? "Move Component Up" : "Move Component Down",
        icon: null,
        keyBinding: {
            key: isUp ? "ArrowUp" : "ArrowDown",
            alt: true,
            shift: true,
        },
        disabled: (context) => !resolveComponentReorder(context.editContext, direction),
        execute: async (context) => {
            const resolved = resolveComponentReorder(context.editContext, direction);
            if (!resolved)
                return;
            const { component, placeholderKey, mainItem, target } = resolved;
            // placeholderKey encodes the parent component id after an underscore, the
            // same convention droppedInPlaceholder uses to populate `parent`.
            const placeholderKeyParts = placeholderKey.split("_");
            const parentId = placeholderKeyParts.length === 1 ? undefined : placeholderKeyParts[1];
            const op = {
                type: "move-component",
                mainItem,
                parent: parentId
                    ? {
                        id: parentId,
                        language: mainItem.language,
                        version: mainItem.version,
                    }
                    : undefined,
                placeholderKey,
                placeholderIndex: target.targetAdjustedIndex,
                componentIds: [component.id],
                date: new Date().toISOString(),
                id: uuid(),
                title: `Move ${component.name}`,
            };
            await context.editContext.operations.executeEditOperation(op);
            // sonner's toast region is aria-live="polite", so this doubles as the
            // screen-reader announcement of the move.
            toast.success(`Moved ${component.name} to position ${target.newPosition} of ${target.totalReal}`);
        },
    };
}
export const moveComponentUpCommand = buildReorderCommand("up");
export const moveComponentDownCommand = buildReorderCommand("down");
//# sourceMappingURL=keyboardCommands.js.map