import { jsx as _jsx } from "@emotion/react/jsx-runtime";
import { useState, useMemo, useCallback, useEffect, createContext, } from 'react';
import { useStore } from '../../../../../../../../hooks';
import { includesArray } from '../../../../../../../../../utils/includes-array';
import { getEntityType } from './get-entity-type';
import { getParentState } from './get-parent-state';
export const AnimationEditorContext = createContext({
    path: [],
    inspectEntity: () => { },
    selectEntities: () => { },
    entitySelection: { paths: [] },
});
export const AnimationEditorProvider = ({ path: rootPath, children, }) => {
    const store = useStore();
    const [inspectedEntity, setInspectedEntity] = useState();
    const [entitySelection, setEntitySelection] = useState(() => ({
        paths: [],
    }));
    useEffect(() => {
        const unsubscribe = store.subscribe((updatedPath) => {
            const newSelection = entitySelection.paths.filter((path) => {
                if (!includesArray(path, updatedPath)) {
                    return true;
                }
                return store.get(path) !== undefined;
            });
            if (entitySelection.paths.length !== newSelection.length) {
                setEntitySelection({ paths: newSelection });
            }
            // Try to pick parent state/substate if new selection is empty
            // Otherwise update selection only if size has been changed
            if (!newSelection.length && entitySelection.paths.length) {
                const newEntityPath = getParentState(inspectedEntity === null || inspectedEntity === void 0 ? void 0 : inspectedEntity.path);
                if (newEntityPath) {
                    newSelection.push(newEntityPath);
                    setEntitySelection({ paths: newSelection });
                }
            }
            const path = inspectedEntity === null || inspectedEntity === void 0 ? void 0 : inspectedEntity.path;
            if (!path || !includesArray(path, updatedPath)) {
                return;
            }
            if (store.get(path) === undefined) {
                const newPath = newSelection.at(-1);
                const newType = getEntityType(newPath);
                setInspectedEntity(newPath && newType
                    ? { path: newPath, type: newType }
                    : undefined);
            }
        });
        return () => {
            unsubscribe();
        };
    }, [store, entitySelection, inspectedEntity]);
    const inspectEntity = useCallback((entityPath) => {
        // Try to pick parent state/substate if new path is undefined
        if (!entityPath) {
            const newEntityPath = getParentState(inspectedEntity === null || inspectedEntity === void 0 ? void 0 : inspectedEntity.path);
            if (newEntityPath) {
                setEntitySelection({ paths: [newEntityPath] });
                setInspectedEntity({
                    path: newEntityPath,
                    type: getEntityType(newEntityPath),
                });
                return;
            }
        }
        const type = getEntityType(entityPath);
        setInspectedEntity(type && entityPath ? { path: entityPath, type } : undefined);
    }, [inspectedEntity]);
    const selectEntities = useCallback((paths) => {
        setEntitySelection({ paths });
    }, []);
    const entityData = useMemo(() => ({
        path: rootPath,
        inspectedEntity,
        inspectEntity,
        selectEntities,
        entitySelection,
    }), [rootPath, inspectedEntity, inspectEntity, selectEntities, entitySelection]);
    return (_jsx(AnimationEditorContext.Provider, { value: entityData, children: children }));
};
