@use "sass:map";

@mixin atomicClassesNoBreakpoint ($attr, $cname, $cpost, $mod, $styles){
  @each $style in $styles {
    // if there is no breakpoint or container query length should be 1
    @if length($style) == 1 {
      @if(length(nth($style, 1)) == 1) {
        @warn Problem with formatting of $attr
      }

      $vals: map.get($style, "vals");
      @each $val in $vals {
        @include atomicClass($cname, $cpost, $attr, $mod, $val);
      }
    }
  }
}

@mixin atomicClassesWithBreakpoint ($attr, $cname, $cpost, $mod, $styles, $cbp) {
  @each $style in $styles {

    // if there is a breakpoint
    $bp: map.get($style, "bp");
    @if $bp {

      @if(length(nth($style, 1))==1) {
        @warn Problem with formatting of $attr
      }

      $vals: map.get($style, "vals");
      $bp-name: map.get($bp, "name");
      $bp-cond: map.get($bp, "cond");
      $cbp-name: map.get($cbp, "name"); // current breakpoint name
      $post: $cpost+$bp-name;

      // @warn #{$bp-name};
      @if $cbp-name==$bp-name {
        @media #{$bp-cond} {
          @each $val in $vals {
            @include atomicClass($cname, $post, $attr, $mod, $val);
          }
        }
      }
    }
  }
}

@mixin atomicClassesWithContainer ($attr, $cname, $cpost, $mod, $styles, $ccont) {
  @each $style in $styles {

    // if there is a container
    $cont: map.get($style, "cont");
    @if $cont {

      @if(length(nth($style, 1))==1) {
        @warn Problem with formatting of $attr
      }

      $vals: map.get($style, "vals");
      $cont-name: map.get($cont, "name");
      $cont-cond: map.get($cont, "cond");
      $ccont-name: map.get($ccont, "name"); // current container name
      $post: $cpost+$cont-name;

      // @warn #{$bp-name};
      @if $ccont-name==$cont-name {
        @container #{$cont-cond} {
          @each $val in $vals {
            @include atomicClass($cname, $post, $attr, $mod, $val);
          }
        }
      }
    }
  }
}

@mixin atomicClass($className, $postfix, $attribute, $modifier, $val) {
  $apiValue: nth($val, 1);
  $value   : nth($val, 2);
  .#{$className}#{$apiValue}#{$postfix}#{$modifier} {
    #{$attribute}: #{$value};
  }
}

@mixin cssCustomProperty($name, $value) {
  #{$name}: #{$value};
}

$css-custom-properties: false !default;
$atomic-config: false !default;
$breakpoint-order: false !default;
$container-order: false !default;

@if not $atomic-config {
  @warn '$atomic-config is not defined';
}

@if not $css-custom-properties {
  @warn '$css-custom-properties is not defined';
}

@if not $breakpoint-order {
  @warn '$breakpoint-order is not defined';
}

@if not $container-order {
  @warn '$container-order is not defined';
}

@if $css-custom-properties {
  // set variables up in root
  :root {
    @each $variableName, $cname, $cpost, $mod, $initialValue, $styles in $css-custom-properties {
      @include cssCustomProperty($variableName, $initialValue);
    } 
  }

  // generate classes for setting variables
  @each $variableName, $cname, $cpost, $mod, $initialValue, $styles in $css-custom-properties {
    @include atomicClassesNoBreakpoint($variableName, $cname, $cpost, $mod, $styles);
  } 

  @if $breakpoint-order {
    // generate classes for setting variables with breakpoints
    @each $bp in $breakpoint-order {
      @each $variableName, $cname, $cpost, $mod, $initialValue, $styles in $css-custom-properties {
        @include atomicClassesWithBreakpoint($variableName, $cname, $cpost, $mod, $styles, $bp);
      }
    }
  }
}

@if $atomic-config {
  // generate atomic classes
  @each $attr, $cname, $cpost, $mod, $styles in $atomic-config {
    @include atomicClassesNoBreakpoint($attr, $cname, $cpost, $mod, $styles);
  }

  @if $breakpoint-order {
    // generate atomic classes with breakpoints
    @each $bp in $breakpoint-order {
      @each $attr, $cname, $cpost, $mod, $styles in $atomic-config {
        @include atomicClassesWithBreakpoint($attr, $cname, $cpost, $mod, $styles, $bp);
      }
    }
  }

  @if $container-order {
    // generate container classes
    @each $cont in $container-order {
      @each $attr, $cname, $cpost, $mod, $styles in $atomic-config {
        @include atomicClassesWithContainer($attr, $cname, $cpost, $mod, $styles, $cont);
      }
    }
  }
}
