"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.InspectorSequenceSection = exports.hasSequenceControls = exports.getInspectorSelectableItems = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = __importStar(require("react"));
const client_id_1 = require("../helpers/client-id");
const colors_1 = require("../helpers/colors");
const timeline_layout_1 = require("../helpers/timeline-layout");
const plus_1 = require("../icons/plus");
const modals_1 = require("../state/modals");
const InlineAction_1 = require("./InlineAction");
const styles_1 = require("./InspectorPanel/styles");
const TimelineExpandedRow_1 = require("./Timeline/TimelineExpandedRow");
const TimelineSelection_1 = require("./Timeline/TimelineSelection");
const use_timeline_expanded_tree_1 = require("./Timeline/use-timeline-expanded-tree");
const container = {
    color: colors_1.WHITE,
    display: 'flex',
    flexDirection: 'column',
    fontFamily: 'Arial, Helvetica, sans-serif',
    fontSize: 12,
};
const emptyState = {
    color: colors_1.LIGHT_TEXT,
    fontFamily: 'sans-serif',
    fontSize: 12,
    lineHeight: 1.4,
    padding: '0 12px 8px',
};
const controlsEffectsDivider = {
    ...styles_1.sequenceHeaderDivider,
    margin: '8px 0 4px',
};
const effectsHeaderTitle = {
    ...styles_1.sectionHeaderTitle,
    flexShrink: 1,
};
const plusIcon = {
    width: 15,
    height: 15,
};
const isEffectsRoot = (node) => {
    if (node.kind !== 'group' || node.effectInfo !== null) {
        return false;
    }
    const { auxiliaryKeys } = node.nodePathInfo;
    return auxiliaryKeys[auxiliaryKeys.length - 1] === 'effects';
};
const INSPECTOR_COLLAPSED_ROWS_SESSION_STORAGE_KEY = 'remotion.editor.inspectorCollapsedRows';
const getInspectorExpansionKey = (nodePathInfo) => {
    return JSON.stringify(nodePathInfo);
};
const loadInspectorCollapsedKeys = () => {
    if (typeof window === 'undefined') {
        return new Set();
    }
    try {
        const raw = window.sessionStorage.getItem(INSPECTOR_COLLAPSED_ROWS_SESSION_STORAGE_KEY);
        if (raw === null) {
            return new Set();
        }
        const parsed = JSON.parse(raw);
        if (!Array.isArray(parsed)) {
            return new Set();
        }
        return new Set(parsed.filter((key) => typeof key === 'string'));
    }
    catch (_a) {
        return new Set();
    }
};
const persistInspectorCollapsedKeys = (keys) => {
    if (typeof window === 'undefined') {
        return;
    }
    try {
        window.sessionStorage.setItem(INSPECTOR_COLLAPSED_ROWS_SESSION_STORAGE_KEY, JSON.stringify([...keys]));
    }
    catch (_a) {
        // Ignore quota errors or disabled storage.
    }
};
const getInspectorControlGroups = (rows) => {
    return timeline_layout_1.SCHEMA_FIELD_GROUPS.map((group) => ({
        ...group,
        rows: rows.filter(({ node }) => {
            var _a;
            return node.kind === 'field' && ((_a = node.field) === null || _a === void 0 ? void 0 : _a.group) === group.id;
        }),
    })).filter((group) => group.rows.length > 0);
};
const getInspectorSelectableItems = (rows) => {
    return rows.flatMap(({ node }) => {
        const selection = (0, TimelineSelection_1.getTimelineSelectionFromNodePathInfo)(node.nodePathInfo);
        return selection ? [selection] : [];
    });
};
exports.getInspectorSelectableItems = getInspectorSelectableItems;
const hasSequenceControls = (sequence) => {
    return sequence.controls !== null;
};
exports.hasSequenceControls = hasSequenceControls;
const InspectorSequenceSection = ({ sequence, validatedLocation, nodePathInfo, keyframeDisplayOffset, renderSectionHeader, renderTransformControls, }) => {
    const { tree } = (0, use_timeline_expanded_tree_1.useTimelineExpandedTree)({
        sequence,
        nodePathInfo,
        includeTextContent: true,
    });
    const [collapsedKeys, setCollapsedKeys] = (0, react_1.useState)(loadInspectorCollapsedKeys);
    const { previewServerState } = (0, react_1.useContext)(client_id_1.StudioServerConnectionCtx);
    const { setSelectedModal } = (0, react_1.useContext)(modals_1.ModalsContext);
    const getIsExpanded = (0, react_1.useCallback)((candidate) => {
        return !collapsedKeys.has(getInspectorExpansionKey(candidate));
    }, [collapsedKeys]);
    const toggleTrack = (0, react_1.useCallback)((candidate) => {
        setCollapsedKeys((prev) => {
            const key = getInspectorExpansionKey(candidate);
            const next = new Set(prev);
            if (next.has(key)) {
                next.delete(key);
            }
            else {
                next.add(key);
            }
            persistInspectorCollapsedKeys(next);
            return next;
        });
    }, []);
    const { controlRows, effectRows } = (0, react_1.useMemo)(() => {
        const controlNodes = [];
        let effectsRoot = null;
        for (const node of tree) {
            if (isEffectsRoot(node)) {
                effectsRoot = node;
            }
            else {
                controlNodes.push(node);
            }
        }
        return {
            controlRows: (0, timeline_layout_1.flattenVisibleTreeNodes)({
                nodes: controlNodes,
                getIsExpanded,
            }),
            effectRows: effectsRoot === null
                ? []
                : (0, timeline_layout_1.flattenVisibleTreeNodes)({
                    nodes: effectsRoot.children,
                    getIsExpanded,
                }),
        };
    }, [getIsExpanded, tree]);
    const controlSelectableItems = (0, react_1.useMemo)(() => (0, exports.getInspectorSelectableItems)(controlRows), [controlRows]);
    const effectSelectableItems = (0, react_1.useMemo)(() => (0, exports.getInspectorSelectableItems)(effectRows), [effectRows]);
    const controlGroups = (0, react_1.useMemo)(() => getInspectorControlGroups(controlRows), [controlRows]);
    const { schema } = sequence.controls;
    const showEffectsSection = nodePathInfo.supportsEffects || effectRows.length > 0;
    const showControlsEffectsDivider = controlRows.length > 0 && showEffectsSection;
    const canAddEffect = nodePathInfo.supportsEffects &&
        previewServerState.type === 'connected' &&
        Boolean(validatedLocation.source);
    const onAddEffect = (0, react_1.useCallback)(() => {
        if (!canAddEffect || previewServerState.type !== 'connected') {
            return;
        }
        setSelectedModal({
            type: 'add-effect',
            clientId: previewServerState.clientId,
            fileName: validatedLocation.source,
            nodePath: nodePathInfo.sequenceSubscriptionKey,
        });
    }, [
        canAddEffect,
        nodePathInfo.sequenceSubscriptionKey,
        previewServerState,
        setSelectedModal,
        validatedLocation.source,
    ]);
    const renderEffectsHeader = () => {
        return renderSectionHeader(jsx_runtime_1.jsxs("div", { style: styles_1.sectionHeaderRow, children: [
                jsx_runtime_1.jsx("div", { style: effectsHeaderTitle, children: "Effects" }), jsx_runtime_1.jsx(InlineAction_1.InlineAction, { disabled: !canAddEffect, onClick: onAddEffect, title: canAddEffect ? 'Add effect' : undefined, renderAction: (color) => jsx_runtime_1.jsx(plus_1.Plus, { color: color, style: plusIcon }) })] }));
    };
    const renderRow = ({ node, depth }) => {
        return (jsx_runtime_1.jsx(TimelineExpandedRow_1.TimelineExpandedRow, { node: node, depth: depth, nestedDepth: 0, rowDepthBase: 0, getIsExpanded: getIsExpanded, toggleTrack: toggleTrack, validatedLocation: validatedLocation, nodePath: nodePathInfo.sequenceSubscriptionKey, schema: schema, keyframeDisplayOffset: keyframeDisplayOffset, keyframeControlsMode: "inspector" }, JSON.stringify(node.nodePathInfo)));
    };
    if (controlRows.length === 0 && !showEffectsSection) {
        return (jsx_runtime_1.jsxs("div", { style: container, children: [
                jsx_runtime_1.jsx("div", { style: styles_1.sequenceHeaderDivider }), jsx_runtime_1.jsx("div", { style: emptyState, children: "No schema" })
            ] }));
    }
    return (jsx_runtime_1.jsxs("div", { style: container, children: [
            jsx_runtime_1.jsx("div", { style: styles_1.sequenceHeaderDivider }), controlRows.length > 0 ? (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: controlSelectableItems, children: controlGroups.map((group, i) => (jsx_runtime_1.jsxs(react_1.default.Fragment, { children: [i === 0 ? null : jsx_runtime_1.jsx("div", { style: controlsEffectsDivider }), renderSectionHeader(group.label), group.id === 'transforms' ? renderTransformControls() : null, group.rows.map(renderRow)] }, group.id))) })) : null, showEffectsSection ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [showControlsEffectsDivider ? (jsx_runtime_1.jsx("div", { style: controlsEffectsDivider })) : null, renderEffectsHeader(), effectRows.length === 0 ? (jsx_runtime_1.jsx("div", { style: emptyState, children: "None" })) : (jsx_runtime_1.jsx(TimelineSelection_1.TimelineSelectionOrderProvider, { items: effectSelectableItems, children: effectRows.map(renderRow) }))] })) : null] }));
};
exports.InspectorSequenceSection = InspectorSequenceSection;
