/* stylelint-disable selector-no-vendor-prefix */
@use 'sass:math';
@use 'sass:list';
@use 'sass:map';
@use 'sass:meta';
@use 'colors';

@function negative($cssValue) {
  @return calc(-1 * #{$cssValue});
}

@mixin def($var, $value) {
  --#{$var}: #{$value};
}

@function use($var, $default: initial) {
  @return var(--#{$var}, $default);
}

@function color($name, $luminance: 'pure', $alpha: 1) {
  @if $luminance == 'pure' {
    @return rgba(var(--color-#{$name}), #{$alpha});
  }

  @return rgba(var(--color-#{$name}-#{$luminance}), #{$alpha});
}

@function offset($size: 'normal') {
  @return var(--offset-#{$size});
}

@function q($multiplier: 1) {
  @if meta.type-of($multiplier) == 'number' and math.unit($multiplier) == 'px' {
    @return calc(var(--quant) * (#{$multiplier} / var(--quant)));
  }

  @if $multiplier == 1 {
    @return var(--quant);
  }

  @return calc(var(--quant) * #{$multiplier});
}

$controlHeightsMap: (
  'xxsmall': q(1.5),
  'xsmall': q(3),
  'small': q(4),
  'normal': q(6),
  'large': q(7),
  'xlarge': q(10),
  'xxlarge': q(12.5),
);

@function control-height($size: 'normal') {
  @return var(--control-height-#{$size});
}

@function font-size($size: 'small') {
  @return var(--font-size-#{$size});
}

@mixin font-size($size: 'small') {
  font-size: var(--font-size-#{$size});
}

@function font-weight($weight: 'small') {
  @return var(--font-weight-#{$weight});
}

@mixin font-weight($weight: 'small') {
  font-weight: var(--font-weight-#{$weight});
}

@mixin font-family($family: 'primary') {
  font-family: var(--font-family-#{$family});
}

@mixin font-color($colorToken) {
  color: color-token($colorToken);
}

@mixin letter-spacing($size: 'small') {
  letter-spacing: var(--letter-spacing-#{$size});
}

@function letter-spacing($size: 'small') {
  @return var(--letter-spacing-#{$size});
}

@mixin line-height($size: 'small') {
  line-height: var(--line-height-#{$size});
}

$borderRadiusMap: (
  'none': 0px,
  'xsmall': q(0.25),
  'small': q(0.5),
  'medium': q(0.75),
  'large': q(1),
  'xlarge': q(1.25),
  'pill': 9999px,
);

@function border-radius($size: 'small') {
  @return var(--border-radius-#{$size});
}

@mixin border-radius($size: 'small') {
  border-radius: var(--border-radius-#{$size});
}

@function viewport-width($multiplier: 1) {
  @return calc((var(--width) - var(--offset-safezone) * 2) * #{$multiplier});
}

@function viewport-height($multiplier: 1) {
  @return calc((var(--height) - var(--offset-safezone) * 2) * #{$multiplier});
}

$cfxuiColorLuminance: ('pure', 950, 900, 800, 700, 600, 500, 400, 300, 200, 100, 50);
$cfxuiColorAlpha: (
  '100': 1,
  '90': 0.9,
  '80': 0.8,
  '70': 0.7,
  '60': 0.6,
  '50': 0.5,
  '40': 0.4,
  '30': 0.3,
  '20': 0.2,
  '10': 0.1,
);

@mixin define-color($name, $color, $bg, $fg) {
  .cfx-color-#{$name} {
    color: $color;
  }

  --color-#{$name}: #{colors.color-triplet($color)};
  --color-#{$name}-50: #{colors.color-triplet(colors.lab-gradient-step($bg, $color, 1, 7))};
  --color-#{$name}-100: #{colors.color-triplet(colors.lab-gradient-step($bg, $color, 2, 7))};
  --color-#{$name}-200: #{colors.color-triplet(colors.lab-gradient-step($bg, $color, 3, 7))};
  --color-#{$name}-300: #{colors.color-triplet(colors.lab-gradient-step($bg, $color, 4, 7))};
  --color-#{$name}-400: #{colors.color-triplet(colors.lab-gradient-step($bg, $color, 5, 7))};
  --color-#{$name}-500: #{colors.color-triplet($color)};
  --color-#{$name}-600: #{colors.color-triplet(colors.lab-gradient-step($color, $fg, 1, 7))};
  --color-#{$name}-700: #{colors.color-triplet(colors.lab-gradient-step($color, $fg, 2, 7))};
  --color-#{$name}-800: #{colors.color-triplet(colors.lab-gradient-step($color, $fg, 3, 7))};
  --color-#{$name}-900: #{colors.color-triplet(colors.lab-gradient-step($color, $fg, 4, 7))};
  --color-#{$name}-950: #{colors.color-triplet(colors.lab-gradient-step($color, $fg, 5, 7))};
}

@mixin define-main-color($bg, $fg) {
  --color-main: #{colors.color-triplet($bg)};
  --color-main-50: #{colors.color-triplet(colors.lab-gradient-step($bg, $fg, 1, 12))};
  --color-main-100: #{colors.color-triplet(colors.lab-gradient-step($bg, $fg, 2, 12))};
  --color-main-200: #{colors.color-triplet(colors.lab-gradient-step($bg, $fg, 3, 12))};
  --color-main-300: #{colors.color-triplet(colors.lab-gradient-step($bg, $fg, 4, 12))};
  --color-main-400: #{colors.color-triplet(colors.lab-gradient-step($bg, $fg, 5, 12))};
  --color-main-500: #{colors.color-triplet(colors.lab-gradient-step($bg, $fg, 6, 12))};
  --color-main-600: #{colors.color-triplet(colors.lab-gradient-step($bg, $fg, 7, 12))};
  --color-main-700: #{colors.color-triplet(colors.lab-gradient-step($bg, $fg, 8, 12))};
  --color-main-800: #{colors.color-triplet(colors.lab-gradient-step($bg, $fg, 9, 12))};
  --color-main-900: #{colors.color-triplet(colors.lab-gradient-step($bg, $fg, 10, 12))};
  --color-main-950: #{colors.color-triplet(colors.lab-gradient-step($bg, $fg, 11, 12))};
}

@mixin define-main-colors($bg, $fg, $overrides: ()) {
  $colors: map.merge(
    (
      'primary': #f50551,
      'success': #01a370,
      'warning': #ffae00,
      'error': #ff2600,
      'teal': #007892,
      'aurum': #aa6f0d,
      'silver': #a5a5a5,
    ),
    $overrides
  );

  @include define-main-color($bg, $fg);

  @each $colorName, $colorValue in $colors {
    @include define-color($colorName, $colorValue, $bg, $fg);
  }
}

@mixin define-theme($bg, $fg, $overrides: ()) {
  $colors: map.merge(
    (
      'accent': #f40552,
      'primary': #f1f1e4,
      'secondary': #9ea4bd,
      'tertiary': #ff75ac,
      'green': #22bf4e,
      'yellow': #fda640,
      'red': #e33131,
      'blue': #3868a6,
      'argentum': #a3a3a3,
      'aurum': #bfa45e,
      'platinum': #f1f1f1,
      'bg': #11131c,
      'bg-light': #1c202e,
      'bg-dark': #1c202e,
      'bg-dark-grey': #1a1a1a,
      'bg-black': #000,
    ),
    $overrides
  );

  @each $colorName, $colorValue in $colors {
    @include define-color($colorName, $colorValue, $bg, $fg);
  }
}

@mixin define-color-token($name, $color) {
  --color-#{$name}: #{$color};
}

@function color-token($name) {
  @return var(--color-#{$name});
}

@mixin animated($props: 'all', $subClass: '&') {
  @if meta.type-of($props) == 'list' {
    $transition: ();

    @each $property in $props {
      $transition: list.append($transition, ($property 0.25s ease), $separator: comma);
    }
    #{$subClass} {
      transition:
        $transition,
        outline-offset 0s,
        outline 0s;
    }
  } @else {
    #{$subClass} {
      transition:
        #{$props} 0.25s ease,
        outline-offset 0s,
        outline 0s;
    }
  }
}

@mixin fake-backdrop-blur($topLayer: false, $topLayerBlend: false, $topLayerSize: false, $topLayerAttachement: false) {
  --over-backdrop-color: var(--backdrop-color, transparent);
  --over-backdrop-image-blur: var(--backdrop-image-blur, url('assets/images/bg2-blur.png'));

  @if not $topLayer {
    $topLayer: linear-gradient(use('over-backdrop-color'), use('over-backdrop-color'));
  }

  @if not $topLayerBlend {
    $topLayerBlend: normal;
  }

  @if not $topLayerSize {
    $topLayerSize: cover;
  }

  @if not $topLayerAttachement {
    $topLayerAttachement: scroll;
  }

  background-color: use('over-backdrop-color');
  background-image:
    $topLayer, linear-gradient(color-token('backdrop-shader'), color-token('backdrop-shader')),
    use('over-backdrop-image-blur'), use('over-backdrop-image-blur');
  background-blend-mode: $topLayerBlend, normal, overlay;
  background-size: $topLayerSize, cover, cover, cover;
  background-attachment: $topLayerAttachement, scroll, fixed, fixed;
}

$offsets: (
  'none': 0px,
  'hairthin': 1px,
  'thin': 2px,
  'xxsmall': q(0.25),
  'xsmall': q(0.5),
  'small': q(1),
  'normal': q(2),
  'medium': q(2.5),
  'large': q(4),
  'xlarge': q(6),
  'safezone': q(8),
);

@mixin offset-classes($prefix: 'offset', $property: 'gap') {
  @each $name, $value in $offsets {
    &.#{$prefix}-#{$name} {
      #{$property}: offset('#{$name}');
    }
  }
}

$globalScaleMap: (
  0: q(0),
  10: q(0.125),
  15: q(0.25),
  33: q(0.375),
  45: q(0.5),
  50: q(0.625),
  60: q(0.75),
  100: q(1),
  110: q(1.25),
  120: q(1.5),
  140: q(1.75),
  150: q(1.875),
  160: q(2),
  180: q(2.25),
  200: q(2.5),
  240: q(3),
  250: q(3.125),
  300: q(3.75),
  350: q(4),
  400: q(5),
  450: q(6),
  500: q(6.25),
  550: q(7),
  600: q(7.5),
  700: q(9),
  800: q(10),
  900: q(11.25),
  1000: q(12.5),
  1100: q(13.75),
  1200: q(15),
  1400: q(17.5),
  1500: q(18.75),
  1600: q(20),
  1800: q(22.5),
  2000: q(25),
  2400: q(30),
  3000: q(37.5),
  3300: q(41.25),
);

@function gs($scale) {
  @return map.get($globalScaleMap, $scale);
}

$spacingMap: (
  25: gs(45),
  100: gs(100),
  110: gs(110),
  150: gs(120),
  175: gs(160),
  200: gs(200),
  250: gs(240),
  300: gs(300),
  400: gs(400),
  450: gs(450),
  600: gs(600),
  700: gs(700),
  800: gs(800),
  900: gs(900),
  1000: gs(1000),
  1200: gs(1200),
  1600: gs(1600),
  2400: gs(2400),
);

@function spacing($num) {
  @return map.get($spacingMap, $num);
}

@function spacer($name) {
  @return var(--spacer-#{$name});
}

@function control-size($name) {
  @return var(--control-size-#{$name});
}

@mixin webkit-scrollbar() {
  ::-webkit-scrollbar {
    width: use('scrollable-thumb-size');
  }

  ::-webkit-scrollbar:horizontal {
    height: use('scrollable-thumb-size');
  }

  ::-webkit-scrollbar-track {
    background-color: color-token('scrollbar-track-background');
  }

  ::-webkit-scrollbar-thumb {
    @include border-radius('pill');

    background-color: color-token('scrollbar');

    &:hover {
      background-color: color-token('scrollbar-hover');
    }

    &:active {
      background-color: color-token('scrollbar-active');
    }
  }

  ::-webkit-scrollbar-corner {
    display: none;
  }
}

@mixin placeholder-color($color) {
  &::placeholder {
    color: $color;
  }

  &::-webkit-input-placeholder {
    color: $color;
  }

  &::-moz-placeholder {
    color: $color;
  }

  &:-ms-input-placeholder {
    color: $color;
  }
}

@mixin placeholder-animated($props: 'all', $subClass: '&') {
  &::placeholder {
    @include animated($props, $subClass);
  }

  &::-webkit-input-placeholder {
    @include animated($props, $subClass);
  }

  &::-moz-placeholder {
    @include animated($props, $subClass);
  }

  &:-ms-input-placeholder {
    @include animated($props, $subClass);
  }
}

$zindexMap: (
  'zero': 0,
  'first': 1,
  'second': 2,
  'flyout': 1000,
  'max': 9000,
  // Select's content should be above everything except Title
  'select': 9099,
  // Titles must be above everything
  'title': 9100,
);

@function zindex($index) {
  @return map.get($zindexMap, $index);
}

$mediaMap: (
  'initial': 0px,
  // depricated naming
  'small': 360px,
  'small-medium': 640px,
  'medium': 1024px,
  'medium-large': 1280px,
  'large': 1920px,
  'xlarge': 2560px,
  // updated naming with sone new breakpoints
  'bp320': 320px,
  'bp393': 393px,
  'bp500': 500px,
  'bp768': 768px,
  'bp1024': 1024px,
  'bp1280': 1280px,
  'bp1440': 1440px,
  'bp1920': 1920px,
  'bp2560': 2560px,
);

@mixin media-max($size: 'medium', $fix: 'empty') {
  @if $fix == 'empty' {
    @if $size == 'initial' {
      @content;
    } @else {
      $mediaSize: map.get($mediaMap, $size);

      @media (width < $mediaSize) {
        @content;
      }
    }
  } @else {
    @media (width < $fix) {
      @content;
    }
  }
}

@mixin media-min($size: 'medium', $fix: 'empty') {
  @if $fix == 'empty' {
    @if $size == 'initial' {
      @content;
    } @else {
      @media (min-width: map.get($mediaMap, $size)) {
        @content;
      }
    }
  } @else {
    @media (min-width: $fix) {
      @content;
    }
  }
}

$mpMap: (
  m: margin,
  mt: margin-top,
  mr: margin-right,
  mb: margin-bottom,
  ml: margin-left,
  p: padding,
  pt: padding-top,
  pr: padding-right,
  pb: padding-bottom,
  pl: padding-left,
);

@mixin define-vars-from-map($prefix: '', $spacerMap, $media: 'initial') {
  @each $name, $value in $spacerMap {
    $fullName: '#{$name}-#{$media}';
    $prefixedName: $name;
    $prefixedFullName: $fullName;

    @if $prefix != '' {
      $prefixedName: '#{$prefix}-#{$name}';
      $prefixedFullName: '#{$prefix}-#{$fullName}';
    }

    @include def('#{$prefixedFullName}', $value);
  }

  @include media-min($media) {
    @each $name, $value in $spacerMap {
      $fullName: '#{$name}-#{$media}';
      $prefixedName: $name;
      $prefixedFullName: $fullName;

      @if $prefix != '' {
        $prefixedName: '#{$prefix}-#{$name}';
        $prefixedFullName: '#{$prefix}-#{$fullName}';
      }

      @include def('#{$prefixedName}', use('#{$prefixedFullName}'));
    }
  }
}

@mixin define-font-size($name, $size, $line-height: 1.3, $paragraph-spacing: 0) {
  @include def('font-size-#{$name}', $size);
  @include def('line-height-#{$name}', $line-height);
  @include def('paragraph-spacing-#{$name}', $paragraph-spacing);
}

@mixin define-font-sizes($sizesMap, $media: 'initial') {
  @each $name, $values in $sizesMap {
    $fullName: '#{$name}-#{$media}';

    @include def('font-size-#{$fullName}', list.nth($values, 1));
    @include def('line-height-#{$fullName}', list.nth($values, 2));
    @include def('paragraph-spacing-#{$fullName}', list.nth($values, 3));
  }

  @include media-min($media) {
    @each $name, $values in $sizesMap {
      $fullName: '#{$name}-#{$media}';

      @include def('font-size-#{$name}', use('font-size-#{$fullName}'));
      @include def('line-height-#{$name}', use('line-height-#{$fullName}'));
      @include def('paragraph-spacing-#{$name}', use('paragraph-spacing-#{$fullName}'));
    }
  }
}

// Return a list of values: (font-size, line-height, paragraph-spacing)
@function get-font-size($size, $line-height: 1.3, $paragraph-spacing: 0) {
  @return ($size, $line-height, $paragraph-spacing);
}

$fontSizeMapInitial: (
  'xxxsmall': get-font-size(gs(140), 1.3, gs(100)),
  'xxsmall': get-font-size(gs(120), 1.5, gs(110)),
  'xsmall': get-font-size(gs(140), 1.5, gs(110)),
  'small': get-font-size(gs(160), 1.5, gs(150)),
  'medium': get-font-size(gs(200), 1.3, gs(100)),
  'large': get-font-size(gs(240), 1.2, gs(110)),
  'xlarge': get-font-size(gs(250), 1.2, gs(110)),
  'xxlarge': get-font-size(gs(350), 1.2, gs(120)),
  'xxxlarge': get-font-size(gs(400), 1.1, gs(140)),
  'xxxxlarge': get-font-size(gs(450), 1.1, gs(200)),
);
$fontSizeMapTablet: (
  'xxxsmall': get-font-size(gs(140), 1.3, gs(100)),
  'xxsmall': get-font-size(gs(120), 1.5, gs(110)),
  'xsmall': get-font-size(gs(140), 1.5, gs(110)),
  'small': get-font-size(gs(160), 1.5, gs(150)),
  'medium': get-font-size(gs(200), 1.3, gs(100)),
  'large': get-font-size(gs(240), 1.2, gs(110)),
  'xlarge': get-font-size(gs(300), 1.2, gs(140)),
  'xxlarge': get-font-size(gs(400), 1.2, gs(150)),
  'xxxlarge': get-font-size(gs(700), 1.1, gs(300)),
  'xxxxlarge': get-font-size(gs(800), 1.1, gs(350)),
);
$fontSizeMapDesktop: (
  'xxxsmall': get-font-size(gs(140), 1.3, gs(100)),
  'xxsmall': get-font-size(gs(140), 1.5, gs(110)),
  'xsmall': get-font-size(gs(160), 1.5, gs(120)),
  'small': get-font-size(gs(180), 1.5, gs(160)),
  'medium': get-font-size(gs(240), 1.3, gs(110)),
  'large': get-font-size(gs(300), 1.2, gs(200)),
  'xlarge': get-font-size(gs(400), 1.2, gs(180)),
  'xxlarge': get-font-size(gs(500), 1.2, gs(200)),
  'xxxlarge': get-font-size(gs(1000), 1.1, gs(400)),
  'xxxxlarge': get-font-size(gs(1200), 1.1, gs(500)),
);
$fontSizeMapLargeDesktop: (
  'xxxsmall': get-font-size(gs(140), 1.3, gs(100)),
  'xxsmall': get-font-size(gs(140), 1.5, gs(110)),
  'xsmall': get-font-size(gs(160), 1.5, gs(120)),
  'small': get-font-size(gs(180), 1.5, gs(160)),
  'medium': get-font-size(gs(240), 1.3, gs(110)),
  'large': get-font-size(gs(300), 1.2, gs(200)),
  'xlarge': get-font-size(gs(400), 1.2, gs(180)),
  'xxlarge': get-font-size(gs(500), 1.2, gs(200)),
  'xxxlarge': get-font-size(gs(1000), 1.1, gs(400)),
  'xxxxlarge': get-font-size(gs(1200), 1.1, gs(500)),
);

// Spacer tokens
$spacerMapInitial: (
  'xxsmall': gs(100),
  'xsmall': gs(180),
  'small': gs(200),
  'medium': gs(300),
  'large': gs(400),
  'xlarge': gs(600),
  'xxlarge': gs(700),
  'xxxlarge': gs(800),
  'xxxxlarge': gs(1000),
  'xxxxxlarge': gs(1200),
);
$spacerMapTablet: (
  'xxsmall': gs(100),
  'xsmall': gs(180),
  'small': gs(200),
  'medium': gs(300),
  'large': gs(400),
  'xlarge': gs(600),
  'xxlarge': gs(700),
  'xxxlarge': gs(800),
  'xxxxlarge': gs(1000),
  'xxxxxlarge': gs(1200),
);
$spacerMapDesktop: (
  'xxsmall': gs(120),
  'xsmall': gs(200),
  'small': gs(300),
  'medium': gs(400),
  'large': gs(600),
  'xlarge': gs(800),
  'xxlarge': gs(1000),
  'xxxlarge': gs(1200),
  'xxxxlarge': gs(1800),
  'xxxxxlarge': gs(2400),
);
$spacerMapLargeDesktop: (
  'xxsmall': gs(120),
  'xsmall': gs(200),
  'small': gs(300),
  'medium': gs(400),
  'large': gs(600),
  'xlarge': gs(800),
  'xxlarge': gs(1000),
  'xxxlarge': gs(1200),
  'xxxxlarge': gs(1800),
  'xxxxxlarge': gs(2400),
);

// Controls size tokens
$controlSizeMapInitial: (
  'button-height': q(5.75),
  'button-padding-sides': spacing(200),
  'main-nav-height': q(7.5),
  'sub-nav-height': gs(7),
);
$controlSizeMapTablet: (
  'button-height': q(5.75),
  'button-padding-sides': spacing(200),
  'main-nav-height': q(7.5),
  'sub-nav-height': gs(7),
);
$controlSizeMapDesktop: (
  'button-height': q(7),
  'button-padding-sides': spacing(400),
  'main-nav-height': q(10),
  'sub-nav-height': gs(9),
);
$controlSizeMapLargeDesktop: (
  'button-height': q(7),
  'button-padding-sides': spacing(400),
  'main-nav-height': q(10),
  'sub-nav-height': gs(9),
);
