function _check_private_redeclaration(obj, privateCollection) {
    if (privateCollection.has(obj)) {
        throw new TypeError("Cannot initialize the same private elements twice on an object");
    }
}
function _class_apply_descriptor_get(receiver, descriptor) {
    if (descriptor.get) {
        return descriptor.get.call(receiver);
    }
    return descriptor.value;
}
function _class_apply_descriptor_set(receiver, descriptor, value) {
    if (descriptor.set) {
        descriptor.set.call(receiver, value);
    } else {
        if (!descriptor.writable) {
            throw new TypeError("attempted to set read only private field");
        }
        descriptor.value = value;
    }
}
function _class_extract_field_descriptor(receiver, privateMap, action) {
    if (!privateMap.has(receiver)) {
        throw new TypeError("attempted to " + action + " private field on non-instance");
    }
    return privateMap.get(receiver);
}
function _class_private_field_get(receiver, privateMap) {
    var descriptor = _class_extract_field_descriptor(receiver, privateMap, "get");
    return _class_apply_descriptor_get(receiver, descriptor);
}
function _class_private_field_init(obj, privateMap, value) {
    _check_private_redeclaration(obj, privateMap);
    privateMap.set(obj, value);
}
function _class_private_field_set(receiver, privateMap, value) {
    var descriptor = _class_extract_field_descriptor(receiver, privateMap, "set");
    _class_apply_descriptor_set(receiver, descriptor, value);
    return value;
}
function _class_private_method_get(receiver, privateSet, fn) {
    if (!privateSet.has(receiver)) {
        throw new TypeError("attempted to get private field on non-instance");
    }
    return fn;
}
function _class_private_method_init(obj, privateSet) {
    _check_private_redeclaration(obj, privateSet);
    privateSet.add(obj);
}
import { isObject, deepClone, deepMerge } from '../../helpers/object.mjs';
import sizing from '../static/variables/sizing.mjs';
import densitySizes from '../static/variables/density.mjs';
import { validateParams, validateDensityType, validateColorScheme } from './utils/validation.mjs';
import { warn } from '../../helpers/console.mjs';
import { throwWithCause } from '../../helpers/errors.mjs';
/**
 * Config keys that support deep merging when updating theme params.
 *
 * @type {string[]}
 */ const MERGEABLE_CONFIG_KEYS = [
    'sizing',
    'icons',
    'colors',
    'tokens'
];
/**
 * Required config keys.
 *
 * @type {string[]}
 */ const REQUIRED_CONFIG_KEYS = [
    'name',
    'icons',
    'colors',
    'tokens'
];
var /**
   * The initial theme configuration object.
   *
   * @private
   * @type {object}
   */ _initThemeConfig = /*#__PURE__*/ new WeakMap(), /**
   * Theme configuration object.
   *
   * @private
   * @type {object}
   */ _themeConfig = /*#__PURE__*/ new WeakMap(), /**
   * Registered listeners notified when the theme configuration changes.
   *
   * @private
   * @type {Set<Function>}
   */ _listeners = /*#__PURE__*/ new WeakMap(), /**
   * Current color mode ('light', 'dark', or 'auto').
   *
   * @private
   * @default 'auto'
   * @type {string}
   */ _colorScheme = /*#__PURE__*/ new WeakMap(), /**
   * Current density type ('compact', 'default', or 'comfortable').
   *
   * @private
   * @default 'default'
   * @type {string}
   */ _densityType = /*#__PURE__*/ new WeakMap(), /**
   * Notifies all listeners about a theme configuration change.
   *
   * @private
   */ _notifyChange = /*#__PURE__*/ new WeakSet(), /**
   * Applies density configuration from the params object.
   *
   * @private
   * @param {object} config The config object to modify.
   * @param {string|object} density The density value from params.
   */ _applyDensityConfig = /*#__PURE__*/ new WeakSet(), /**
   * Sets the parameters to the theme configuration.
   *
   * @private
   * @param {object} paramsObject The parameters object to set.
   */ _setParams = /*#__PURE__*/ new WeakSet();
/**
 * ThemeBuilder class provides methods to build and configure themes.
 *
 * @class ThemeBuilder
 */ class ThemeBuilder {
    /**
   * Subscribes to theme configuration changes.
   *
   * @param {Function} listener The callback invoked with the updated theme configuration.
   * @returns {Function} An unsubscribe function.
   */ subscribe(listener) {
        if (typeof listener !== 'function') {
            throwWithCause('[ThemeBuilder] listener must be a function.');
        }
        _class_private_field_get(this, _listeners).add(listener);
        return ()=>_class_private_field_get(this, _listeners).delete(listener);
    }
    /**
   * Sets theme configuration parameters.
   *
   * @param {object} paramsObject An object with theme configuration parameters.
   * @returns {ThemeBuilder} The ThemeBuilder instance for chaining.
   */ params(paramsObject) {
        validateParams(paramsObject, 'params');
        _class_private_method_get(this, _setParams, setParams).call(this, paramsObject);
        _class_private_method_get(this, _notifyChange, notifyChange).call(this);
        return this;
    }
    /**
   * Sets the color mode (light, dark, or auto).
   *
   * @param {string} mode The color mode ('light', 'dark', or 'auto').
   * @returns {ThemeBuilder} The ThemeBuilder instance for chaining.
   */ setColorScheme(mode) {
        _class_private_field_set(this, _colorScheme, validateColorScheme(mode));
        _class_private_field_get(this, _themeConfig).colorScheme = _class_private_field_get(this, _colorScheme);
        _class_private_field_get(this, _initThemeConfig).colorScheme = _class_private_field_get(this, _colorScheme);
        _class_private_method_get(this, _notifyChange, notifyChange).call(this);
        return this;
    }
    /**
   * Sets the density type (compact, default, or comfortable).
   *
   * @param {string} type The density type ('compact', 'default', or 'comfortable').
   * @returns {ThemeBuilder} The ThemeBuilder instance for chaining.
   */ setDensityType(type) {
        _class_private_field_set(this, _densityType, validateDensityType(type));
        _class_private_field_get(this, _themeConfig).density.type = _class_private_field_get(this, _densityType);
        _class_private_field_get(this, _initThemeConfig).density.type = _class_private_field_get(this, _densityType);
        _class_private_method_get(this, _notifyChange, notifyChange).call(this);
        return this;
    }
    /**
   * Gets the current theme configuration.
   *
   * @returns {ThemeConfig} The theme configuration object.
   */ getThemeConfig() {
        return _class_private_field_get(this, _themeConfig);
    }
    /**
   * The theme builder constructor.
   *
   * @param {object} themeConfig - The theme config object with `name`, `sizing`, `density`, `icons`, `colors`, `tokens`, and `colorScheme` properties.
   */ constructor(themeConfig){
        _class_private_method_init(this, _notifyChange);
        _class_private_method_init(this, _applyDensityConfig);
        _class_private_method_init(this, _setParams);
        _class_private_field_init(this, _initThemeConfig, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _themeConfig, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _listeners, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _colorScheme, {
            writable: true,
            value: void 0
        });
        _class_private_field_init(this, _densityType, {
            writable: true,
            value: void 0
        });
        _class_private_field_set(this, _listeners, new Set());
        _class_private_field_set(this, _colorScheme, 'auto');
        _class_private_field_set(this, _densityType, 'default');
        validateParams(themeConfig, 'themeConfig', {
            requiredFields: REQUIRED_CONFIG_KEYS
        });
        _class_private_field_set(this, _initThemeConfig, {
            name: undefined,
            sizing,
            density: {
                type: _class_private_field_get(this, _densityType),
                sizes: densitySizes
            },
            icons: {},
            colors: {},
            tokens: {},
            colorScheme: _class_private_field_get(this, _colorScheme)
        });
        _class_private_method_get(this, _setParams, setParams).call(this, themeConfig);
        _class_private_field_set(this, _initThemeConfig, _class_private_field_get(this, _themeConfig));
    }
}
function notifyChange() {
    const config = this.getThemeConfig();
    _class_private_field_get(this, _listeners).forEach((listener)=>listener(config));
}
function applyDensityConfig(config, density) {
    if (isObject(density)) {
        config.density = deepMerge(config.density, density);
        _class_private_field_set(this, _densityType, density.type);
        if (_class_private_field_get(this, _initThemeConfig)?.density) {
            _class_private_field_get(this, _initThemeConfig).density.type = density.type;
        }
    } else if (typeof density === 'string') {
        config.density.type = density;
        _class_private_field_set(this, _densityType, density);
        if (_class_private_field_get(this, _initThemeConfig)?.density) {
            _class_private_field_get(this, _initThemeConfig).density.type = density;
        }
    }
}
function setParams(paramsObject) {
    const config = deepClone(_class_private_field_get(this, _initThemeConfig));
    if (paramsObject.name !== undefined) {
        if (_class_private_field_get(this, _initThemeConfig).name !== undefined) {
            warn('[ThemeBuilder] The "name" property can only be set during ' + '`registerTheme()` and cannot be updated via `params()`.');
        } else {
            config.name = paramsObject.name;
        }
    }
    // Apply mergeable config keys
    MERGEABLE_CONFIG_KEYS.forEach((key)=>{
        if (paramsObject[key] !== undefined && isObject(paramsObject[key])) {
            config[key] = deepMerge(config[key], paramsObject[key]);
        }
    });
    // Apply density (special handling for string or object)
    if (paramsObject.density !== undefined) {
        _class_private_method_get(this, _applyDensityConfig, applyDensityConfig).call(this, config, paramsObject.density);
    }
    // Apply color scheme
    if (paramsObject.colorScheme !== undefined) {
        config.colorScheme = paramsObject.colorScheme;
        _class_private_field_set(this, _colorScheme, paramsObject.colorScheme);
        if (_class_private_field_get(this, _initThemeConfig)?.colorScheme) {
            _class_private_field_get(this, _initThemeConfig).colorScheme = paramsObject.colorScheme;
        }
    }
    _class_private_field_set(this, _themeConfig, config);
}
/**
 * Creates a new ThemeBuilder instance.
 *
 * @param {object} baseTheme The base theme object with theme configuration parameters.
 * @returns {ThemeBuilder} The ThemeBuilder instance.
 */ export function createTheme(baseTheme) {
    return new ThemeBuilder(baseTheme);
}
