// This file contains functions used to define Angular Material theme objects.

@use 'sass:map';
@use '../style/sass-utils';
@use './palettes';
@use '../tokens/m3-tokens';
@use './config-validation';
@use '../tokens/m3';

// Prefix used for component token fallback variables, e.g.
// `color: var(--mat-text-button-label-text-color, var(--mat-sys-primary));`
$system-fallback-prefix: mat-sys;

// Default system level prefix to use when directly calling the `system-level-*` mixins.
// Prefix used for component token fallback variables, e.g.
// `color: var(--mat-text-button-label-text-color, var(--mat-sys-primary));`
// TODO: Remove this variable after internal clients are migrated from "sys"
$system-level-prefix: mat-sys;

/// Map key used to store internals of theme config.
$internals: _mat-theming-internals-do-not-access;

/// The theme version of generated themes.
$theme-version: 1;

/// Defines an Angular Material theme object with color, typography, and density settings.
/// @param {Map} $config The theme configuration
/// @return {Map} A theme object
@function define-theme($config: ()) {
  $err: config-validation.validate-theme-config($config);
  @if $err {
    @error $err;
  }

  $color-config: map.get($config, color) or ();
  $typography-config: map.get($config, typography) or ();
  $density-config: map.get($config, density) or ();

  // colors
  $type: map.get($color-config, theme-type) or light;
  $primary: map.get($color-config, primary) or palettes.$violet-palette;
  $tertiary: map.get($color-config, tertiary) or $primary;
  $color-system-variables-prefix:
    map.get($color-config, system-variables-prefix) or $system-level-prefix;
  sass-utils.$use-system-color-variables: map.get($color-config, use-system-variables) or false;

  $palettes: (
    primary: map.remove($primary, neutral, neutral-variant, secondary),
    secondary: map.get($primary, secondary),
    tertiary: map.remove($tertiary, neutral, neutral-variant, secondary, error),
    neutral: map.get($primary, neutral),
    neutral-variant: map.get($primary, neutral-variant),
    error: map.get($primary, error),
  );

  // typography
  $default-plain: (Roboto, sans-serif);
  $default-brand: $default-plain;
  $plain: map.get($typography-config, plain-family) or $default-plain;
  $brand: map.get($typography-config, brand-family) or $default-brand;
  $bold: map.get($typography-config, bold-weight) or 700;
  $medium: map.get($typography-config, medium-weight) or 500;
  $regular: map.get($typography-config, regular-weight) or 400;
  $typography-system-variables-prefix: map.get($typography-config, system-variables-prefix) or
    $system-level-prefix;
  sass-utils.$use-system-typography-variables:
    map.get($typography-config, use-system-variables) or false;
  $typography: (
    plain: $plain,
    brand: $brand,
    bold: $bold,
    medium: $medium,
    regular: $regular,
  );

  // density
  $density-scale: map.get($density-config, scale) or 0;

  $system-maps: (
    m3-tokens.get-sys-color($type, $palettes, $color-system-variables-prefix),
    m3.md-sys-elevation-values(),
    m3.md-sys-motion-values(),
    m3.md-sys-shape-values(),
    m3.md-sys-state-values(),
    (
      // Form field native select option text color
      neutral10: map.get($palettes, neutral, 10),
      // Sidenav scrim (container background shadow when opened),
      neutral-variant20: map.get($palettes, neutral-variant, 20),
    ),
    m3-tokens.get-sys-typeface($typography, $typography-system-variables-prefix),
  );
  $system: (
    density-scale: $density-scale,
  );
  @each $sys-map in $system-maps {
    $system: map.merge($system, $sys-map);
  }

  @return (
    _mat-system: $system,
    $internals: (
      base-tokens: m3-tokens.generate-base-tokens(),
      color-system-variables-prefix: $color-system-variables-prefix,
      color-tokens:
        m3-tokens.generate-color-tokens($type, $palettes, $color-system-variables-prefix),
      density-scale: $density-scale,
      font-definition: $typography,
      palettes: $palettes,
      theme-type: $type,
      theme-version: $theme-version,
      typography-system-variables-prefix: $typography-system-variables-prefix,
      typography-tokens:
          m3-tokens.generate-typography-tokens($typography, $typography-system-variables-prefix),
    )
  );
}

/// Defines an Angular Material theme object with color settings.
/// @param {Map} $config The color configuration
/// @return {Map} A theme object
/// @deprecated Use define-theme with a map using the "color" key
@function define-colors($config: ()) {
  @return define-theme((color: $config));
}

/// Defines an Angular Material theme object with typography settings.
/// @param {Map} $config The typography configuration
/// @return {Map} A theme object
/// @deprecated Use define-theme with a map using the "typography" key
@function define-typography($config: ()) {
  @return define-theme((typography: $config));
}

/// Defines an Angular Material theme object with density settings.
/// @param {Map} $config The density configuration
/// @return {Map} A theme object
/// @deprecated Use define-theme with a map using the "density" key
@function define-density($config: ()) {
  @return define-theme((density: $config));
}
