/**
 * Copyright IBM Corp. 2016, 2023
 *
 * This source code is licensed under the Apache-2.0 license found in the
 * LICENSE file in the root directory of this source tree.
 */

@use '@carbon/styles/scss/spacing' as *;
@use '@carbon/styles/scss/type' as *;
@use '@carbon/styles/scss/utilities/convert' as *;
@use '@carbon/styles/scss/theme' as *;

/// Carbon core original size tokens.
/// Used to theme-zone from expressive back to productive, and thus defines only items that expressive version defines.
/// @type Map
/// @access public
/// @group carbon-expressive
$carbon-productive-size-tokens: (
  container-01: $carbon--container-01,
  container-02: $carbon--container-02,
  $spacing-09: $carbon--$spacing-09,
  container-04: $carbon--container-04,
  container-05: $carbon--container-05,
  icon-size-01: $carbon--icon-size-01,
);

/// C4D version of size tokens.
/// @type Map
/// @access public
/// @group carbon-expressive
$carbon-expressive-size-tokens: (
  container-01: $spacing-07,
  container-02: $spacing-08,
  $spacing-09: $spacing-09,
  container-04: $spacing-09,
  container-05: 4.5rem,
  icon-size-01: 1.25rem,
);

/// Carbon core original type tokens.
/// Used to theme-zone from expressive back to productive, and thus defines only items that expressive version defines.
/// From: carbon-components/scss/globals/scss/vendor/@carbon/elements/scss/type/_inlined/_styles.scss
/// @type Map
/// @access public
/// @group carbon-expressive
$carbon-productive-type-tokens: (
  body-compact-01: (
    font-size: carbon--type-scale(2),
    font-weight: carbon--font-weight('regular'),
    line-height: to-rem(18px),
    letter-spacing: 0.16px,
  ),
  body-01: (
    font-size: carbon--type-scale(2),
    font-weight: carbon--font-weight('regular'),
    line-height: to-rem(20px),
    letter-spacing: 0.16px,
  ),
  label-01: (
    font-size: carbon--type-scale(1),
    font-weight: carbon--font-weight('regular'),
    line-height: $spacing-05,
    letter-spacing: 0.32px,
  ),
  caption-01: (
    font-size: carbon--type-scale(1),
    font-weight: carbon--font-weight('regular'),
    line-height: $spacing-05,
    letter-spacing: 0.32px,
  ),
  code-01: (
    font-family: font-family('mono'),
    font-size: carbon--type-scale(1),
    font-weight: carbon--font-weight('regular'),
    line-height: $spacing-05,
    letter-spacing: 0.32px,
  ),
  code-02: (
    font-family: font-family('mono'),
    font-size: carbon--type-scale(2),
    font-weight: carbon--font-weight('regular'),
    line-height: to-rem(20px),
    letter-spacing: 0.32px,
  ),
  helper-text-01: (
    font-size: carbon--type-scale(1),
    line-height: $spacing-05,
    letter-spacing: 0.32px,
  ),
  heading-01: (
    font-size: carbon--type-scale(2),
    font-weight: carbon--font-weight('semibold'),
    line-height: to-rem(18px),
    letter-spacing: 0.16px,
  ),
  heading-compact-01: (
    font-size: carbon--type-scale(2),
    font-weight: carbon--font-weight('semibold'),
    line-height: to-rem(18px),
    letter-spacing: 0.16px,
  ),
  heading-01: (
    font-size: carbon--type-scale(2),
    font-weight: carbon--font-weight('semibold'),
    line-height: to-rem(20px),
    letter-spacing: 0.16px,
  ),
);

/// C4D version of type tokens.
/// @type Map
/// @access public
/// @group carbon-expressive
$carbon-expressive-type-tokens: (
  body-compact-01: (
    font-size: carbon--type-scale(3),
    font-weight: carbon--font-weight('regular'),
    line-height: to-rem(22px),
    letter-spacing: 0,
  ),
  body-01: (
    font-size: carbon--type-scale(3),
    font-weight: carbon--font-weight('regular'),
    line-height: $spacing-06,
    letter-spacing: 0,
  ),
  label-01: (
    font-size: carbon--type-scale(2),
    font-weight: carbon--font-weight('regular'),
    line-height: to-rem(18px),
    letter-spacing: 0.16px,
  ),
  caption-01: (
    font-size: carbon--type-scale(2),
    font-weight: carbon--font-weight('regular'),
    line-height: to-rem(18px),
    letter-spacing: 0.16px,
  ),
  code-01: (
    font-family: font-family('mono'),
    font-size: carbon--type-scale(2),
    font-weight: carbon--font-weight('regular'),
    line-height: to-rem(20px),
    letter-spacing: 0,
  ),
  code-02: (
    font-family: font-family('mono'),
    font-size: carbon--type-scale(3),
    font-weight: carbon--font-weight('regular'),
    line-height: $spacing-06,
    letter-spacing: 0,
  ),
  helper-text-01: (
    font-size: carbon--type-scale(2),
    font-weight: carbon--font-weight('regular'),
    line-height: to-rem(18px),
    letter-spacing: 0.16px,
  ),
  heading-01: (
    font-size: carbon--type-scale(3),
    font-weight: carbon--font-weight('semibold'),
    line-height: to-rem(22px),
    letter-spacing: 0,
  ),
  heading-compact-01: (
    font-size: carbon--type-scale(3),
    font-weight: carbon--font-weight('semibold'),
    line-height: to-rem(22px),
    letter-spacing: 0,
  ),
  heading-01: (
    font-size: carbon--type-scale(2),
    font-weight: carbon--font-weight('semibold'),
    line-height: to-rem(20px),
    letter-spacing: 0.16px,
  ),
) !default;

/// Carbon core original component tokens.
/// Used to theme-zone from expressive back to productive, and thus defines only items that expressive version defines.
/// @type Map
/// @access public
/// @group carbon-expressive
$carbon-productive-component-tokens: (
  button-md-height:
    var(
      --#{$custom-property-prefix}-container-04,
      map-get($carbon-productive-size-tokens, 'container-04')
    ),
  button-sm-height:
    var(
      --#{$custom-property-prefix}-container-02,
      map-get($carbon-productive-size-tokens, 'container-02')
    ),
  button-field-height:
    var(
      --#{$custom-property-prefix}-$spacing-09,
      map-get($carbon-productive-size-tokens, '$spacing-09')
    ),
  input-height:
    var(
      --#{$custom-property-prefix}-$spacing-09,
      map-get($carbon-productive-size-tokens, '$spacing-09')
    ),
  tab-height:
    var(
      --#{$custom-property-prefix}-$spacing-09,
      map-get($carbon-productive-size-tokens, '$spacing-09')
    ),
  tab-container-height:
    var(
      --#{$custom-property-prefix}-container-04,
      map-get($carbon-productive-size-tokens, 'container-04')
    ),
) !default;

/// C4D version of component tokens.
/// @type Map
/// @access public
/// @group carbon-expressive
$carbon-expressive-component-tokens: (
  button-md-height:
    var(
      --#{$custom-property-prefix}-container-04,
      map-get($carbon-expressive-size-tokens, 'container-04')
    ),
  button-sm-height:
    var(
      --#{$custom-property-prefix}-container-02,
      map-get($carbon-expressive-size-tokens, 'container-02')
    ),
  button-field-height:
    var(
      --#{$custom-property-prefix}-$spacing-09,
      map-get($carbon-expressive-size-tokens, '$spacing-09')
    ),
  input-height:
    var(
      --#{$custom-property-prefix}-$spacing-09,
      map-get($carbon-expressive-size-tokens, '$spacing-09')
    ),
  tab-height:
    var(
      --#{$custom-property-prefix}-$spacing-09,
      map-get($carbon-expressive-size-tokens, '$spacing-09')
    ),
  tab-container-height:
    var(
      --#{$custom-property-prefix}-container-04,
      map-get($carbon-expressive-size-tokens, 'container-04')
    ),
) !default;

/// Sets size/type tokens as custom properties.
/// @access public
/// @param {Map} $size-tokens [$carbon-productive-size-tokens] - The size tokens.
/// @param {Map} $type-tokens [$carbon-productive-type-tokens] - The type tokens.
/// @param {Map} $component-tokens [$carbon-productive-component-tokens] - The component tokens.
/// @group carbon-expressive
@mixin use-carbon-productive-tokens(
  $size-tokens: $carbon-productive-size-tokens,
  $type-tokens: $carbon-productive-type-tokens,
  $component-tokens: $carbon-productive-component-tokens
) {
  @each $key, $value in $size-tokens {
    --#{$custom-property-prefix}-#{$key}: #{$value};
  }
  @each $key, $value in $type-tokens {
    @each $subkey, $subvalue in $value {
      --#{$custom-property-prefix}-#{$key}-#{$subkey}: #{$subvalue};
    }
  }
  @each $key, $value in $component-tokens {
    --#{$custom-property-prefix}-#{$key}: #{$value};
  }
}

/// Sets size/type tokens as custom properties.
/// @access public
/// @param {Map} $size-tokens [$carbon-expressive-size-tokens] - The size tokens.
/// @param {Map} $type-tokens [$carbon-expressive-type-tokens] - The type tokens.
/// @param {Map} $component-tokens [$carbon-expressive-component-tokens] - The component tokens.
/// @group carbon-expressive
@mixin use-carbon-expressive-tokens(
  $size-tokens: $carbon-expressive-size-tokens,
  $type-tokens: $carbon-expressive-type-tokens,
  $component-tokens: $carbon-expressive-component-tokens
) {
  @each $key, $value in $size-tokens {
    --#{$custom-property-prefix}-#{$key}: #{$value};
  }
  @each $key, $value in $type-tokens {
    @each $subkey, $subvalue in $value {
      --#{$custom-property-prefix}-#{$key}-#{$subkey}: #{$subvalue};
    }
  }
  @each $key, $value in $component-tokens {
    --#{$custom-property-prefix}-#{$key}: #{$value};
  }
}

/// Global token theme.
/// @access private
/// @group carbon-expressive
@mixin carbon-expressive-tokens {
  // Container tokens
  $container-01: var(
    --#{$custom-property-prefix}-container-01,
    map-get($carbon-expressive-size-tokens, 'container-01')
  ) !global;
  $container-02: var(
    --#{$custom-property-prefix}-container-02,
    map-get($carbon-expressive-size-tokens, 'container-02')
  ) !global;
  $spacing-09: var(
    --#{$custom-property-prefix}-$spacing-09,
    map-get($carbon-expressive-size-tokens, '$spacing-09')
  ) !global;
  $spacing-09: var(
    --#{$custom-property-prefix}-container-04,
    map-get($carbon-expressive-size-tokens, 'container-04')
  ) !global;
  $container-05: var(
    --#{$custom-property-prefix}-container-05,
    map-get($carbon-expressive-size-tokens, 'container-05')
  ) !global;

  // Icon size tokens
  $icon-size-01: var(
    --#{$custom-property-prefix}-icon-size-01,
    map-get($carbon-expressive-size-tokens, 'icon-size-01')
  ) !global;

  // Type tokens
  // For type tokens, Carbon emits CSS custom properties via `@mixin type-style`
  // Ref: https://github.com/carbon-design-system/carbon/blob/v10.15.0/packages/type/scss/_styles.scss#L705
  $body-compact-01: map-get(
    $carbon-expressive-type-tokens,
    'body-compact-01'
  ) !global;
  $body-01: map-get($carbon-expressive-type-tokens, 'body-01') !global;
  $label-01: map-get($carbon-expressive-type-tokens, 'label-01') !global;
  $caption-01: map-get($carbon-expressive-type-tokens, 'caption-01') !global;
  $code-01: map-get($carbon-expressive-type-tokens, 'code-01') !global;
  $code-02: map-get($carbon-expressive-type-tokens, 'code-02') !global;
  $helper-text-01: map-get(
    $carbon-expressive-type-tokens,
    'helper-text-01'
  ) !global;
  $heading-01: map-get($carbon-expressive-type-tokens, 'heading-01') !global;
  $heading-compact-01: map-get(
    $carbon-expressive-type-tokens,
    'heading-compact-01'
  ) !global;
  $heading-01: map-get($carbon-expressive-type-tokens, 'heading-01') !global;

  // Ensures `$carbon--theme` and `$carbon--theme--themename` are in sync to:
  // 1) Ensure `@include theme()` call in `_theme-tokens.scss` picks up correct type token values.
  //    Ref: https://unpkg.com/browse/@carbon/themes@10.12.0/scss/generated/_mixins.scss
  // 2) Ensure the comparison in `@function get-token-value` works.
  //    Ref: https://github.com/carbon-design-system/carbon/blob/v10.11.0/packages/components/src/globals/scss/_component-tokens.scss#L28
  $carbon--theme: map-merge(
    $carbon--theme,
    (
      caption-01: $caption-01,
      label-01: $label-01,
      helper-text-01: $helper-text-01,
      body-compact-01: $body-compact-01,
      body-01: $body-01,
      code-01: $code-01,
      code-02: $code-02,
      heading-01: $heading-01,
      heading-compact-01: $heading-compact-01,
      heading-01: $heading-01,
      container-01: $container-01,
      container-02: $container-02,
      $spacing-09: $spacing-09,
      container-04: $spacing-09,
      container-05: $container-05,
      icon-size-01: $icon-size-01,
    )
  ) !global;

  $white: map-merge(
    $white,
    (
      caption-01: $caption-01,
      label-01: $label-01,
      helper-text-01: $helper-text-01,
      body-compact-01: $body-compact-01,
      body-01: $body-01,
      code-01: $code-01,
      code-02: $code-02,
      heading-01: $heading-01,
      heading-compact-01: $heading-compact-01,
      heading-01: $heading-01,
      container-01: $container-01,
      container-02: $container-02,
      $spacing-09: $spacing-09,
      container-04: $spacing-09,
      container-05: $container-05,
      icon-size-01: $icon-size-01,
    )
  ) !global;

  $g10: map-merge(
    $g10,
    (
      caption-01: $caption-01,
      label-01: $label-01,
      helper-text-01: $helper-text-01,
      body-compact-01: $body-compact-01,
      body-01: $body-01,
      code-01: $code-01,
      code-02: $code-02,
      heading-01: $heading-01,
      heading-compact-01: $heading-compact-01,
      heading-01: $heading-01,
      container-01: $container-01,
      container-02: $container-02,
      $spacing-09: $spacing-09,
      container-04: $spacing-09,
      container-05: $container-05,
      icon-size-01: $icon-size-01,
    )
  ) !global;

  $g90: map-merge(
    $g90,
    (
      caption-01: $caption-01,
      label-01: $label-01,
      helper-text-01: $helper-text-01,
      body-compact-01: $body-compact-01,
      body-01: $body-01,
      code-01: $code-01,
      code-02: $code-02,
      heading-01: $heading-01,
      heading-compact-01: $heading-compact-01,
      heading-01: $heading-01,
      container-01: $container-01,
      container-02: $container-02,
      $spacing-09: $spacing-09,
      container-04: $spacing-09,
      container-05: $container-05,
      icon-size-01: $icon-size-01,
    )
  ) !global;

  $g100: map-merge(
    $g100,
    (
      caption-01: $caption-01,
      label-01: $label-01,
      helper-text-01: $helper-text-01,
      body-compact-01: $body-compact-01,
      body-01: $body-01,
      code-01: $code-01,
      code-02: $code-02,
      heading-01: $heading-01,
      heading-compact-01: $heading-compact-01,
      heading-01: $heading-01,
      container-01: $container-01,
      container-02: $container-02,
      $spacing-09: $spacing-09,
      container-04: $spacing-09,
      container-05: $container-05,
      icon-size-01: $icon-size-01,
    )
  ) !global;

  :root {
    @include use-carbon-expressive-tokens($component-tokens: ());
  }
}

/// Defines additional component tokens to enable expressive theme support.
/// @access private
/// @group carbon-expressive
@mixin carbon-expressive-component-tokens {
  /// @type Number
  /// @access public
  /// @group button
  $button-md-height: var(
    --#{$custom-property-prefix}-button-md-height,
    map-get($carbon-expressive-component-tokens, 'button-md-height')
  ) !global;

  /// @type Number
  /// @access private
  /// @group button
  $button-sm-height: var(
    --#{$custom-property-prefix}-button-sm-height,
    map-get($carbon-expressive-component-tokens, 'button-sm-height')
  ) !global;

  /// @type Number
  /// @access private
  /// @group button
  $button-field-height: var(
    --#{$custom-property-prefix}-button-field-height,
    map-get($carbon-expressive-component-tokens, 'button-field-height')
  ) !global;

  /// @type Number
  /// @access private
  /// @group form
  $input-height: var(
    --#{$custom-property-prefix}-input-height,
    map-get($carbon-expressive-component-tokens, 'input-height')
  ) !global;

  /// @type Number
  /// @access private
  /// @group form
  $tab-height: var(
    --#{$custom-property-prefix}-tab-height,
    map-get($carbon-expressive-component-tokens, 'tab-height')
  ) !global;

  /// @type Number
  /// @access private
  /// @group tabs
  $tab-container-height: var(
    --#{$custom-property-prefix}-tab-container-height,
    map-get($carbon-expressive-component-tokens, 'tab-container-height')
  ) !global;

  :root {
    @include use-carbon-expressive-tokens($size-tokens: (), $type-tokens: ());
  }
}
