@use "sass:list";
@use "sass:map";
@use "sass:meta";

@use "../utils" as *;
@use "./theme" as *;

// @in:
//   # Accents map final colors for compute
//   $accents-map:
//   # Current theme
//   $theme: Theme
//   # default accent variables for element
//   $default: map<string, any> | null
//   # callback that returns appearance variables
//   $mapper: AccentsMapper | null
// out: AccentsElementMap
@function accents-element-variables($accents-map, $theme, $default, $mapper) {
  $accents: map.get($accents-map, $theme);

  $map: (
    "default": if($default != null, $default, ()),
  );

  @if $mapper != null {
    @each $accent, $colors in $accents {
      $vars: meta.call($mapper, $theme, $accent, $colors);
      $map: map.set($map, $accent, $vars);
    }
  }

  @return $map;
}

// @in:
//   # component name in kebab-case
//   $name: string
//   # component variables by accent
//   $theme-vars-map: map<accent_name, vars_map>
// @out: explain component variables to style
@mixin accents-expand-mapped-vars($class, $theme, $properties) {
  $name: kebab-case($class);

  @each $accent, $vars in $properties {
    $flat: map-flatten($vars);

    $accent-class: if($accent != "default", "." + $accent, "");
    $class-name: if($class != "", "." + $class, "");
    $ext: $accent-class + $class-name;

    @each $item in $flat {
      $value: list.nth($item, 2);
      $keys: list.nth($item, 1);
      $key: join($keys, "-");

      $name-prop: if($name != "", "-#{$name}", "");

      --mie#{$name-prop}-#{$key}: #{$value};
    }
  }
}

// @in:
//   # element class like "button" or "row.item", etc..
//   $class: string
//   # default accent variables
//   $default: map<string, any> | null
//   # callback for mapping final colors
//   $mapper: AccentsMapper | null
//   # final computed accents map for
//   # component (its passed to cb for mapping)
//   $accents-map: AccentsMap
// @out: apply component accent styles
@mixin apply-accents-to-component(
  $class,
  $default-vars,
  $mapper,
  $default-theme,
  $accents-map: ("light": (), "dark": ())
) {
  $default-vars: if($default-vars != null, $default-vars, ());

  @each $theme in ("light", "dark") {
    $theme-default-vars: map.get($default-vars, $theme);

    $properties: accents-element-variables(
      $accents-map,
      $theme,
      $theme-default-vars,
      $mapper
    );

    @each $accent, $vars in $properties {
      $flat: map-flatten($vars);

      $accent-class: if($accent != "default", "." + $accent, "");
      $class-name: if($class != "", "." + $class, "");
      $ext: $class-name + $accent-class;

      @include with-theme($theme, $ext, $default-theme) {
        @each $item in $flat {
          $value: list.nth($item, 2);
          $keys: list.nth($item, 1);
          $key: join($keys, "-");

          $name: kebab-case($class);
          $name-prop: if($name != "", "-#{$name}", "");

          --mie#{$name-prop}-#{$key}: #{$value};
        }
      }
    }
  }
}
