/*---------------------------------------------------------------------------------------------
 * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
 * See LICENSE.md in the project root for license terms and full copyright notice.
 *--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Utilities
 */
import * as React from "react";
import { create } from "zustand";
import { Logger } from "@itwin/core-bentley";
import { UiFramework } from "../UiFramework.js";
/** Object used trim to only known features at runtime.
 * @internal
 */
const knownFeaturesObject = {
    contentAlwaysMaxSize: undefined,
    enableMaximizedFloatingWidget: undefined,
    enableMaximizedPanelWidget: undefined,
    horizontalPanelAlignment: undefined,
    widgetActionDropdown: undefined,
    allowBearingLettersInAccuDrawInputFields: undefined,
    reparentPopoutWidgets: undefined,
    controlWidgetVisibility: undefined,
    toolSettingsNewEditors: undefined,
    toolSettingsLockButton: undefined,
    toolSettingsKeyPressCommit: undefined,
};
/** Trim an object to only contain known feature keys.
 * @param previewFeatures object potentially containing unknown features
 * @returns object containing only known features
 * @internal
 */
function trimToKnownFeaturesOnly(previewFeatures) {
    const knownFeatureKeys = Object.keys(knownFeaturesObject);
    const [knownFeatures, unknownFeatures] = Object.entries(previewFeatures).reduce(([known, unknown], [key, value]) => {
        if (knownFeatureKeys.includes(key)) {
            known[key] = value;
        }
        else {
            unknown.push(key);
        }
        return [known, unknown];
    }, [{}, []]);
    if (Object.keys(unknownFeatures).length > 0) {
        Logger.logWarning(UiFramework.loggerCategory("trimToKnownFeaturesOnly"), `Features used in "setPreviewFeatures" are unknown or no longer in preview`, {
            unknownFeatures,
        });
    }
    return knownFeatures;
}
/** Preview features store used by `UiFramework.previewFeatures` and `UiFramework.setPreviewFeatures()` APIs to manage the preview features.
 * Use `usePreviewFeatures` hook to access the preview features set from a react component.
 * Use `usePreviewFeaturesStore.getState().previewFeatures` to access the preview features set from a non-react component.
 * Use `usePreviewFeaturesStore.subscribe()` to subscribe to changes to the preview features set from a non-react component.
 * @internal
 */
const usePreviewFeaturesStore = create((set) => {
    return {
        previewFeatures: {},
        setPreviewFeatures: (newPreviewFeatures) => {
            const previewFeatures = trimToKnownFeaturesOnly(newPreviewFeatures);
            set({ previewFeatures });
        },
    };
});
/** Hook to access the preview features set.
 * @internal
 */
export function usePreviewFeatures() {
    return usePreviewFeaturesStore((state) => state.previewFeatures);
}
/** Set which preview features are enabled. These features are not yet ready for production use nor have
 * a proper API defined yet.
 * The available set of features are defined in the [[PreviewFeatures]] interface.
 *
 * This component should wrap the Provider component.
 *
 * ```tsx
 * <PreviewFeaturesProvider features={{ enableMaximizedFloatingWidget: true }}>
 *   <Provider store={UiFramework.store}>
 *    [...]
 *     <ConfigurableUIContent />
 *    [/...]
 *   </Provider>
 * </PreviewFeaturesProvider>
 * ```
 * @beta
 */
export function PreviewFeaturesProvider({ children, features, }) {
    const setPreviewFeatures = usePreviewFeaturesStore((state) => state.setPreviewFeatures);
    React.useEffect(() => {
        setPreviewFeatures(features ?? {});
    }, [features, setPreviewFeatures]);
    // Clear preview features when unmounting.
    React.useEffect(() => () => {
        setPreviewFeatures({});
    }, [setPreviewFeatures]);
    return React.createElement(React.Fragment, null, children);
}
//# sourceMappingURL=PreviewFeatures.js.map