"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CompositionSelectorItem = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const studio_shared_1 = require("@remotion/studio-shared");
const react_1 = require("react");
const client_id_1 = require("../helpers/client-id");
const colors_1 = require("../helpers/colors");
const get_folder_id_1 = require("../helpers/get-folder-id");
const noop_1 = require("../helpers/noop");
const sidebar_scroll_into_view_1 = require("../helpers/sidebar-scroll-into-view");
const url_state_1 = require("../helpers/url-state");
const folder_1 = require("../icons/folder");
const modals_1 = require("../state/modals");
const composition_menu_items_1 = require("./composition-menu-items");
const CompositionContextButton_1 = require("./CompositionContextButton");
const CompositionOrStillIcon_1 = require("./CompositionOrStillIcon");
const ContextMenu_1 = require("./ContextMenu");
const folder_menu_items_1 = require("./folder-menu-items");
const layout_1 = require("./layout");
const NotificationCenter_1 = require("./Notifications/NotificationCenter");
const actions_1 = require("./RenderQueue/actions");
const SidebarRenderButton_1 = require("./SidebarRenderButton");
const use_resolved_stack_1 = require("./Timeline/use-resolved-stack");
const COMPOSITION_ITEM_HEIGHT = 32;
const itemStyle = {
    paddingRight: 10,
    paddingTop: 6,
    paddingBottom: 6,
    fontSize: 13,
    display: 'flex',
    textDecoration: 'none',
    cursor: 'default',
    alignItems: 'center',
    marginBottom: 1,
    appearance: 'none',
    border: 'none',
    width: '100%',
    textAlign: 'left',
    backgroundColor: colors_1.BACKGROUND,
    height: COMPOSITION_ITEM_HEIGHT,
    userSelect: 'none',
};
const labelStyle = {
    textAlign: 'left',
    textDecoration: 'none',
    fontSize: 13,
    flex: 1,
    whiteSpace: 'nowrap',
    overflow: 'hidden',
    textOverflow: 'ellipsis',
};
const iconStyle = {
    width: 18,
    height: 18,
    flexShrink: 0,
};
const CompositionSelectorItem = ({ item, level, currentComposition, tabIndex, selectComposition, toggleFolder, clearRootDragHover, }) => {
    const selected = (0, react_1.useMemo)(() => {
        if (item.type === 'composition') {
            return currentComposition === item.composition.id;
        }
        return false;
    }, [item, currentComposition]);
    const [hovered, setHovered] = (0, react_1.useState)(false);
    const onPointerEnter = (0, react_1.useCallback)(() => {
        setHovered(true);
    }, []);
    const onPointerLeave = (0, react_1.useCallback)(() => {
        setHovered(false);
    }, []);
    const [dragHovered, setDragHovered] = (0, react_1.useState)(false);
    const compositionRowRef = (0, react_1.useRef)(null);
    const compositionId = item.type === 'composition' ? item.composition.id : null;
    (0, react_1.useLayoutEffect)(() => {
        if (compositionId === null) {
            return;
        }
        (0, sidebar_scroll_into_view_1.maybeScrollCompositionSidebarRowIntoView)({
            element: compositionRowRef.current,
            compositionId,
            selected,
        });
    }, [compositionId, selected]);
    const style = (0, react_1.useMemo)(() => {
        return {
            ...itemStyle,
            backgroundColor: dragHovered
                ? colors_1.WHITE_ALPHA_12
                : (0, colors_1.getBackgroundFromHoverState)({ hovered, selected }),
            paddingLeft: 12 + level * 8,
        };
    }, [dragHovered, hovered, level, selected]);
    const label = (0, react_1.useMemo)(() => {
        return {
            ...labelStyle,
            color: selected || hovered ? colors_1.WHITE : colors_1.LIGHT_TEXT,
        };
    }, [hovered, selected]);
    const onClick = (0, react_1.useCallback)((evt) => {
        evt.preventDefault();
        if (item.type === 'composition') {
            (0, sidebar_scroll_into_view_1.markCompositionSidebarScrollFromRowClick)(item.composition.id);
            selectComposition(item.composition, true);
        }
        else {
            toggleFolder(item.folderName, item.parentName);
        }
    }, [item, selectComposition, toggleFolder]);
    const onKeyDown = (0, react_1.useCallback)((evt) => {
        if (evt.key === 'Enter' || evt.key === ' ') {
            onClick(evt);
        }
    }, [onClick]);
    const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
    const connectionStatus = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx)
        .previewServerState.type;
    const resolvedLocation = (0, use_resolved_stack_1.useResolvedStack)(item.type === 'composition' ? item.composition.stack : item.folder.stack);
    const contextMenu = (0, react_1.useMemo)(() => {
        if (item.type === 'composition') {
            const compositionMenuItems = (0, composition_menu_items_1.getCompositionMenuItems)({
                closeMenu: noop_1.noop,
                composition: item.composition,
                connectionStatus,
                resolvedLocation,
                setSelectedModal,
                readOnlyStudio: window.remotion_isReadOnlyStudio,
            });
            return [
                {
                    id: 'open-in-new-window',
                    keyHint: null,
                    label: 'Open in new window',
                    leftItem: null,
                    onClick: () => {
                        var _a, _b;
                        const screen = window.screen;
                        const width = Math.min(1200, Math.floor(screen.availWidth * 0.8));
                        const height = Math.min(800, Math.floor(screen.availHeight * 0.8));
                        const displayLeft = (_a = screen.availLeft) !== null && _a !== void 0 ? _a : 0;
                        const displayTop = (_b = screen.availTop) !== null && _b !== void 0 ? _b : 0;
                        const left = Math.round(Math.min(Math.max(window.screenX + (window.outerWidth - width) / 2, displayLeft), displayLeft + screen.availWidth - width));
                        const top = Math.round(Math.min(Math.max(window.screenY + (window.outerHeight - height) / 2, displayTop), displayTop + screen.availHeight - height));
                        window.open((0, url_state_1.getUrlForRoute)(`/${item.composition.id}`), '_blank', `popup,width=${width},height=${height},left=${left},top=${top}`);
                    },
                    quickSwitcherLabel: null,
                    subMenu: null,
                    type: 'item',
                    value: 'open-in-new-window',
                },
                {
                    type: 'divider',
                    id: 'open-in-new-window-divider',
                },
                ...compositionMenuItems,
            ];
        }
        return (0, folder_menu_items_1.getFolderMenuItems)({
            closeMenu: noop_1.noop,
            connectionStatus,
            folder: item.folder,
            resolvedLocation,
            setSelectedModal,
            readOnlyStudio: window.remotion_isReadOnlyStudio,
        });
    }, [connectionStatus, item, resolvedLocation, setSelectedModal]);
    const onCompositionDragStart = (0, react_1.useCallback)((event) => {
        var _a;
        if (item.type !== 'composition' || window.remotion_isReadOnlyStudio) {
            event.preventDefault();
            return;
        }
        event.dataTransfer.effectAllowed = 'copyMove';
        event.dataTransfer.setData(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE, JSON.stringify((0, studio_shared_1.makeCompositionDragData)({
            compositionFile: (_a = resolvedLocation === null || resolvedLocation === void 0 ? void 0 : resolvedLocation.source) !== null && _a !== void 0 ? _a : null,
            compositionId: item.composition.id,
        })));
    }, [item, resolvedLocation === null || resolvedLocation === void 0 ? void 0 : resolvedLocation.source]);
    const onFolderDragOver = (0, react_1.useCallback)((event) => {
        if (item.type !== 'folder' ||
            window.remotion_isReadOnlyStudio ||
            !Array.from(event.dataTransfer.types).includes(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE)) {
            return;
        }
        event.preventDefault();
        event.stopPropagation();
        event.dataTransfer.dropEffect = 'move';
        clearRootDragHover();
        setDragHovered(true);
    }, [clearRootDragHover, item]);
    const onFolderDragLeave = (0, react_1.useCallback)(() => {
        setDragHovered(false);
    }, []);
    const onFolderChildListDragOver = (0, react_1.useCallback)((event) => {
        if (item.type !== 'folder' ||
            window.remotion_isReadOnlyStudio ||
            !Array.from(event.dataTransfer.types).includes(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE)) {
            return;
        }
        event.preventDefault();
        event.stopPropagation();
        event.dataTransfer.dropEffect = 'move';
        clearRootDragHover();
    }, [clearRootDragHover, item]);
    const onFolderDrop = (0, react_1.useCallback)(async (event) => {
        if (item.type !== 'folder' || window.remotion_isReadOnlyStudio) {
            return;
        }
        const raw = event.dataTransfer.getData(studio_shared_1.COMPOSITION_DRAG_MIME_TYPE);
        const parsed = raw ? (0, studio_shared_1.parseCompositionDragData)(raw) : null;
        if (parsed === null) {
            return;
        }
        event.preventDefault();
        event.stopPropagation();
        clearRootDragHover();
        setDragHovered(false);
        const isAlreadyDirectChild = item.items.some((child) => {
            return (child.type === 'composition' &&
                child.composition.id === parsed.compositionId);
        });
        if (isAlreadyDirectChild) {
            return;
        }
        const folderId = (0, get_folder_id_1.getFolderId)({
            folderName: item.folderName,
            parentName: item.parentName,
        });
        const notification = (0, NotificationCenter_1.showNotification)(`Moving ${parsed.compositionId}...`, null);
        const controller = new AbortController();
        try {
            const result = await (0, actions_1.applyCodemod)({
                codemod: {
                    type: 'move-composition-to-folder',
                    idToMove: parsed.compositionId,
                    folderName: item.folderName,
                    parentName: item.parentName,
                },
                dryRun: false,
                signal: controller.signal,
                symbolicatedStack: (0, studio_shared_1.compositionDragDataToSymbolicatedStack)(parsed),
            });
            notification.replaceContent(result.success
                ? `Moved ${parsed.compositionId} to ${folderId}`
                : result.reason, result.success ? 2000 : 4000);
            if (result.success && !item.expanded) {
                toggleFolder(item.folderName, item.parentName);
            }
        }
        catch (err) {
            notification.replaceContent(err instanceof Error ? err.message : String(err), 4000);
        }
    }, [clearRootDragHover, item, toggleFolder]);
    if (item.type === 'folder') {
        return (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
                jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenu, onOpen: null, children: jsx_runtime_1.jsx(layout_1.Row, { align: "center", children: jsx_runtime_1.jsxs("div", { style: style, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, tabIndex: tabIndex, onClick: onClick, onKeyDown: onKeyDown, onDragOver: onFolderDragOver, onDragLeave: onFolderDragLeave, onDrop: onFolderDrop, title: item.folderName, role: "button", children: [item.expanded ? (jsx_runtime_1.jsx(folder_1.ExpandedFolderIcon, { style: iconStyle, color: hovered || selected ? colors_1.WHITE : colors_1.LIGHT_TEXT })) : (jsx_runtime_1.jsx(folder_1.CollapsedFolderIcon, { color: hovered || selected ? colors_1.WHITE : colors_1.LIGHT_TEXT, style: iconStyle })), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("div", { style: label, children: item.folderName }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(CompositionContextButton_1.CompositionContextButton, { values: contextMenu, visible: hovered })
                            ] }) }) }), item.expanded ? (jsx_runtime_1.jsx("div", { onDragOver: onFolderChildListDragOver, onDrop: onFolderDrop, children: item.items.map((childItem) => {
                        return (jsx_runtime_1.jsx(exports.CompositionSelectorItem, { currentComposition: currentComposition, selectComposition: selectComposition, item: childItem, tabIndex: tabIndex, level: level + 1, toggleFolder: toggleFolder, clearRootDragHover: clearRootDragHover }, childItem.key + childItem.type));
                    }) })) : null] }));
    }
    return (jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { values: contextMenu, onOpen: null, children: jsx_runtime_1.jsx(layout_1.Row, { align: "center", children: jsx_runtime_1.jsxs("a", { ref: compositionRowRef, style: style, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, tabIndex: tabIndex, onClick: onClick, onKeyDown: onKeyDown, draggable: !window.remotion_isReadOnlyStudio, onDragStart: onCompositionDragStart, type: "button", title: item.composition.id, className: "__remotion-composition", "data-compname": item.composition.id, children: [
                    jsx_runtime_1.jsx(CompositionOrStillIcon_1.CompositionOrStillIcon, { composition: item.composition, color: hovered || selected ? colors_1.WHITE : colors_1.LIGHT_TEXT, style: iconStyle }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 1 }), jsx_runtime_1.jsx("div", { style: label, children: item.composition.id }), jsx_runtime_1.jsx(layout_1.Spacing, { x: 0.5 }), jsx_runtime_1.jsx(CompositionContextButton_1.CompositionContextButton, { values: contextMenu, visible: hovered }), jsx_runtime_1.jsx(SidebarRenderButton_1.SidebarRenderButton, { visible: hovered, composition: item.composition })
                ] }) }) }));
};
exports.CompositionSelectorItem = CompositionSelectorItem;
