// #region Imports
import { ContextProvider } from '@lit/context';
import { ControllerBase } from './Abstracts/ControllerBase';
/**
 * Controller for parent components that provide inherited properties to child consumers.
 *
 * This controller wraps `@lit/context`'s `ContextProvider` and automatically updates
 * the context when any of the watched properties change. The controller hooks into
 * Lit's update lifecycle and compares property values to detect changes.
 *
 * @example
 * ```typescript
 * class ButtonGroupElement extends CustomElement {
 *     private readonly _provider = addInheritanceProviderController(this, {
 *         context: BUTTON_GROUP_INHERITANCE_CONTEXT,
 *         values: () => ({
 *             disabled: this.disabled,
 *             appearance: this.appearance,
 *             variant: this.variant
 *         })
 *     });
 *     // No @Watch handlers needed - the controller automatically
 *     // detects changes to disabled, appearance, and variant!
 * }
 * ```
 *
 * @public
 */
export class InheritanceProviderController extends ControllerBase {
    // #region Fields
    _provider;
    _getValues;
    _watchedProperties;
    _previousValues;
    // #endregion
    // #region Ctor
    /**
     * Creates a new InheritanceProviderController.
     *
     * @public
     * @param host The host element.
     * @param config The controller configuration.
     */
    constructor(host, config) {
        super(host);
        this._getValues = config.values;
        // Determine which properties to watch
        // Either use explicit properties or extract from the values function
        const initialValues = this._getValues();
        this._watchedProperties = config.properties
            ? config.properties.map(String)
            : Object.keys(initialValues);
        // Store initial values from _getValues() for comparison
        // This allows computed properties (like viewLayout -> layout) to work correctly
        this._previousValues = new Map();
        for (const key of this._watchedProperties) {
            this._previousValues.set(key, initialValues[key]);
        }
        this._provider = new ContextProvider(this.host, {
            context: config.context,
            initialValue: initialValues
        });
    }
    // #endregion
    // #region Properties
    /**
     * Gets the current inherited values.
     *
     * @public
     * @readonly
     */
    get values() {
        return this._provider.value;
    }
    /**
     * Gets the underlying context provider.
     *
     * @protected
     * @readonly
     */
    get provider() {
        return this._provider;
    }
    // #endregion
    // #region Methods
    /**
     * Called before the host element updates.
     * Automatically detects changes to watched properties and updates the context.
     *
     * @public
     * @override
     */
    hostUpdate() {
        super.hostUpdate();
        let hasChanges = false;
        const currentValues = this._getValues();
        for (const key of this._watchedProperties) {
            const currentValue = currentValues[key];
            const previousValue = this._previousValues.get(key);
            if (currentValue !== previousValue) {
                hasChanges = true;
                this._previousValues.set(key, currentValue);
            }
        }
        if (hasChanges) {
            this._provider.setValue(this._getValues());
        }
    }
    /**
     * Updates the provided context value.
     * Call this method when any of the inherited properties change.
     * All subscribed consumers will be automatically notified.
     *
     * @remarks
     * In most cases, you don't need to call this method manually.
     * The controller automatically detects property changes during Lit's update cycle.
     *
     * @public
     */
    update() {
        this._provider.setValue(this._getValues());
    }
    /**
     * Forces an update to all consumers, even if the value hasn't changed.
     * Useful when you need to ensure all consumers re-read the context.
     *
     * @public
     */
    forceUpdate() {
        this._provider.setValue(this._getValues(), true);
    }
}
/**
 * Adds an inheritance provider controller to the given host.
 *
 * @public
 * @param host The host element.
 * @param config The configuration options.
 * @returns The inheritance provider controller instance.
 */
export function addInheritanceProviderController(host, config) {
    return new InheritanceProviderController(host, config);
}
//# sourceMappingURL=InheritanceProviderController.js.map