
import { AtomicState, InteractiveAtomic, ModifierAtomic } from "./StateAxis.js";
import { index_d_exports } from "../../../fixtures/dist/index.js";
import { ConfigurablePropertiesName, SelectedConfigurableProperty } from "../properties.js";

//#region ../automated-config/dist/types/ComponentConfig.d.ts
//#region src/types/ComponentConfig.d.ts
/** All configurable property names, excluding button-specific and elevation properties */
type AllPossibleProperties = Exclude<keyof typeof index_d_exports, 'iconButtonSize' | 'buttonIconSvgSize' | 'buttonPalettes' | 'buttonStates'> | 'shadowVariantConfig';
/**
 * Legacy atomic state literals still in use by unmigrated configs via the
 * per-property `pseudoStates` array. These aren't part of the new `StateAxis`
 * taxonomy (so the resolver and StateBuilder don't auto-compose them) but
 * configs that still ship them must continue to typecheck and the CSS
 * generator must still resolve their selectors. Drop entries as components
 * migrate to layer-level `atomicStates`.
 */
type LegacyStateLiteral = 'disabled' | 'focused' | 'focused-keyboard' | 'selected';
/**
 * All possible state keys a property can be styled for. Encoded structure
 * matches the resolver's enumeration and the StateBuilder's depth cap: 0..3
 * modifiers followed optionally by 1 interactive (canonical form is
 * `'modifier1&modifier2&...&interactive'` — see `canonicalizeStateKey`).
 *
 * The structure-aware form catches malformed compounds at compile time —
 * `'hover&pressed'` (two interactives) and `'foo&hover'` (unknown atom)
 * both fail to typecheck.
 *
 * What the type does NOT catch:
 *   - Unsorted modifiers (`'readonly&invalid'` typechecks; canonical form is
 *     `'invalid&readonly'`, produced by `canonicalizeStateKey`).
 *   - Duplicate atoms (`'invalid&invalid'` typechecks; `canonicalizeStateKey`
 *     dedupes within a key).
 *
 * Legacy atoms (`disabled`, `focused`, `focused-keyboard`) are accepted as
 * standalone keys for unmigrated configs only — they aren't composable.
 */
type PossibleStates = AtomicState | LegacyStateLiteral | `${ModifierAtomic}&${InteractiveAtomic}` | `${ModifierAtomic}&${ModifierAtomic}` | `${ModifierAtomic}&${ModifierAtomic}&${InteractiveAtomic}` | `${ModifierAtomic}&${ModifierAtomic}&${ModifierAtomic}` | `${ModifierAtomic}&${ModifierAtomic}&${ModifierAtomic}&${InteractiveAtomic}`;
/** PossibleStates plus 'rest' for the default/inactive state */
type PossibleStatesWithRest = 'rest' | PossibleStates;
/** Configuration for a single visual layer with its properties and optional pseudo-selector */
interface LayerConfig {
  label: string;
  properties: Readonly<Record<string, SelectedConfigurableProperty<ConfigurablePropertiesName, string>>>;
  pseudoSelector?: string;
  /**
   * Atomic states this layer can style. Properties on the layer auto-react to
   * each declared atom plus every auto-generated compound up to
   * `MAX_MODIFIERS_PER_COMPOUND` modifiers (currently 3) optionally combined
   * with one interactive — i.e. M, M&M, M&M&M, M&I, M&M&I, and M&M&M&I forms,
   * minus pairs the browser suppresses (e.g. `disabled&hover`). Properties
   * opt out of specific atoms via `excludeAtomics` on
   * `createConfigurableProperty`.
   *
   * Layers without `atomicStates` fall back to the legacy per-property
   * `pseudoStates` array — this lets unmigrated configs keep their behavior
   * while components are migrated incrementally.
   */
  atomicStates?: AtomicState[];
}
/** Configuration for a specific component state with its options and layer properties */
interface ComponentStateConfig {
  label: string;
  options: readonly string[];
  /** Pseudo-states to omit for specific component state options (e.g. active/on). */
  excludePseudoStatesForOptions?: Partial<Record<string, readonly PossibleStates[]>>;
  /** Layers to omit from the configurator for specific component state options. */
  excludeLayersForOptions?: Partial<Record<string, readonly string[]>>;
  /**
   * @deprecated Per-state property overrides are now authored at the schema
   * level (Configurator UI, migrations), not in source configs. Each
   * componentState only declares its options here; CSS emission picks up
   * per-state schema entries automatically. Retained as optional so
   * pre-existing configs still typecheck during migration to the new shape.
   */
  layers?: {
    root: LayerConfig;
  } & Record<string, LayerConfig>;
}
/** Configuration for a sub-component with its own variants */
interface SubComponentConfig {
  label: string;
  description: string;
  variants: Record<string, VariantConfigWithProperties | VariantConfigWithComponentStates>;
}
/** Base variant configuration defining available options and the default */
interface VariantConfig<O extends string = string> {
  label: string;
  description: string;
  default: O;
  options: readonly O[];
}
/** Variant with layer-based property definitions for each option */
interface VariantConfigWithProperties<O extends string = string> extends VariantConfig<O> {
  layers: {
    root: LayerConfig;
  } & Record<string, LayerConfig>;
  /** Properties scoped to the variant option (e.g. size/sm/width without a layer). */
  variantProperties?: Readonly<Record<string, SelectedConfigurableProperty<ConfigurablePropertiesName, string>>>;
}
/**
 * Variant with component state definitions (hover, focus, etc.) for each option.
 *
 * **KNOWN GAP — multi-axis componentStates aren't fully supported end-to-end.**
 * The type permits `componentStates: Record<string, ComponentStateConfig>` with
 * more than one key, and the configurator's StateBuilder renders one picker
 * row per axis, but the pipeline below the picker (schema-key generator,
 * `buildConfigSchema`, the CSS-selector composition in `generateDeclaration`,
 * and the configurator's write path) all assume a single axis. Adding a
 * second axis today lets the user choose a value on it visually, but only
 * one axis's selection survives the round-trip into the stored schema —
 * compound combinations like `value=filled & disabled=true` can't be
 * addressed as their own override slot. Stick to a single componentState
 * axis per variant until this is generalized end-to-end.
 */
interface VariantConfigWithComponentStates<O extends string = string> extends VariantConfig<O> {
  componentStates: Readonly<Record<string, ComponentStateConfig>>;
  /**
   * Optional layers that apply to the variant universally, regardless of any
   * component state. Properties declared here emit CSS at single-class
   * specificity (0,1,0); per-state schema overrides (added at runtime by the
   * Configurator or by data migrations) emit at compound-class specificity
   * (0,2,0)+ and win via the cascade.
   */
  layers?: {
    root: LayerConfig;
  } & Record<string, LayerConfig>;
}
/** Top-level component configuration with variants and optional sub-components */
interface ComponentConfig {
  label: string;
  description: string;
  subComponents?: Record<string, SubComponentConfig>;
  variants?: Record<string, VariantConfigWithComponentStates | VariantConfigWithProperties | VariantConfig>;
} //#endregion
//#endregion
export { type AllPossibleProperties, type ComponentConfig, type ComponentStateConfig, type LayerConfig, type PossibleStates, type PossibleStatesWithRest, type SubComponentConfig, type VariantConfig, type VariantConfigWithComponentStates, type VariantConfigWithProperties };