////
/// @group progress-bar
/// Groups a set of buttons
////

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

@use "../selector";
@use "../utils";
@use "../color";
@use "../typography";


// Used for function fallback
$-fallbacks: (
  "line-height" : (
    "function" : meta.get-function("get", false, "typography"),
    "property" : "line-height-dense"
  ),
  "value-font-weight" : (
    "function" : meta.get-function("get", false, "typography"),
    "property" : "font-weight-light"
  )
);

/// Module Settings
/// @type Map
/// @prop {Dimension} header-gap [0.25em] Margin/gap for the icon/value
/// @prop {List} margin [(0 0 0.5em 0)] Margin for the progress bar.
/// @prop {Boolean} line-height [true] Line height for the progress bar. If true, falls back to typography's `line-height-dense`.
/// @prop {Color} value-color ["type-tertiary"] Color of the value text.
/// @prop {Dimension} value-margin [0.5em] Margin for the value text.
/// @prop {Boolean} value-font-weight [true] Font weight for the value text. If true, falls back to typography's `font-weight-light`.
/// @prop {Dimension} value-margin-deficit [0.3em] Margin for the deficit value text.
/// @prop {Color} value-color-deficit ["danger"] Color of the deficit value text.
/// @prop {Dimension} bar-height [12px] Height of the progress bar.
/// @prop {Color} bar-color [rgb(80, 80, 171)] Color of the progress bar.
/// @prop {Color} bar-color-deficit ["danger"] Color of the deficit portion of the progress bar.
/// @prop {Color} icon-color ["type-tertiary"] Color of the icon.
/// @prop {Color} icon-color-deficit ["danger"] Color of the icon in a deficit state.
/// @prop {Color} track-color [#ccc] Color of the progress bar track.
/// @prop {List} track-margin [(0.1em 0)] Margin for the progress bar track.
/// @prop {CssValue} rounded-border-radius [100vmax] Border radius for the rounded modifier.
/// @prop {Time} animation-duration [200ms] Duration of the width transition animation.
/// @prop {CssValue} animation-timing [ease] Timing function for the width transition animation.
/// @prop {Time} animation-initial-duration [500ms] Duration of the initial fill animation.
/// @prop {CssValue} animation-initial-timing [ease-in] Timing function for the initial fill animation.
/// @prop {Time} animation-indeterminate-duration [2.5s] Duration of the indeterminate loading animation.

$config: (
  "margin" : (0 0 0.5em 0),
  "header-gap" : 0.25em,
  "line-height" : true,
  "value-color" : "type-tertiary",
  "value-margin" : 0.5em,
  "value-font-weight" : true,
  "value-margin-deficit" : 0.3em,
  "value-color-deficit" : "danger",
  "bar-height" : 12px,
  "bar-color" : "accent",
  "bar-color-deficit" : "danger",
  "icon-color" : "type-tertiary",
  "icon-color-deficit" : "danger",
  "track-color" : "placeholder-background-alt",
  "track-margin" : (0.1em 0),
  "rounded-border-radius" : 50px,
  "animation-duration" : 200ms,
  "animation-timing" : ease,
  "animation-initial-duration" : 500ms,
  "animation-initial-timing" : ease-in,
  "animation-indeterminate-duration" : 2.5s
) !default;

/// @type Map
/// This is the map of styles (variations in progress bar types)
/// - Each style becomes the modifier and accepts ("bar-color", "bar-height", "track-color")
/// - Use this to match whatever progress system(s) your creating
$styles: (
  "success" : (
    "bar-color" : "success",
    "icon-color" : "success"
  ),
  "warning" : (
    "bar-color" : "warning",
    "icon-color" : "warning"
  ),
  "danger" : (
    "bar-color" : "danger",
    "icon-color" : "danger"
  ),
  "small" : (
    "bar-height" : 8px
  ),
  "loader" : (
    "bar-height" : 4px,
    "track-color" : transparent,
  )
) !default;

/// Change modules $config
/// @param {Map} $changes Map of changes
/// @example scss
///   @include ulu.component-progress-bar-set(( "property" : value ));

@mixin set($changes) {
  $config: map.merge($config, $changes) !global;
}

/// Change modules $config
/// @param {Map} $changes Map of changes
/// @example scss
///   @include ulu.component-progress-bar-set-styles(( "small" : ( "bar-height" : 8px ) ));

@mixin set-styles($changes) {
  $styles: map.merge($styles, $changes) !global;
}

/// Get a config option
/// @param {Map} $name Name of property
/// @example scss
///   @include ulu.component-progress-bar-get("property");

@function get($name) {
  $value: utils.require-map-get($config, $name, "progress-bar [config]");
  @return utils.function-fallback($name, $value, $-fallbacks);
}

/// Prints component styles
/// @demo progress-bar
/// @example scss
///  @include ulu.component-progress-bar-styles();

@mixin styles {
  $prefix: selector.class("progress-bar");
  
  #{ $prefix } {
    line-height: get("line-height");
    margin: get("margin");
  }
  #{ $prefix }__header {
    display: flex;
    align-items: flex-end;
  }
  #{ $prefix }__value {
    font-weight: get("value-font-weight");
    color: color.get(get("value-color"));
  }
  #{ $prefix }__icon {
    color: color.get(get("icon-color"));
  }
  #{ $prefix }__icon,
  #{ $prefix }__header #{ $prefix }__value {
    margin-left: auto;
    padding-left: get("header-gap");
  }
  
  #{ $prefix }__track {
    position: relative; // For indeterminate animation
    margin: get("track-margin");
    display: flex;
    width: 100%;
    height: get("bar-height");
    overflow: hidden;
    background-color: color.get(get("track-color"));

    // Remove margins if no children (values/header)
    &:first-child {
      margin-top: 0;
    }
    &:last-child {
      margin-bottom: 0;
    }
  }
  #{ $prefix }__bar {
    display: flex;
    height: 100%;
    // This is the animation when the component is living in the page
    transition: width get("animation-duration") get("animation-timing"); 
    // This is the initial animation of the bar within itself (ie. filling up)
    &:before {
      content: '';
      display: block;
      width: 100%;
      background-color: color.get(get("bar-color"));
      transform-origin: left center;
      animation: ulu-progress-bar get("animation-initial-duration") forwards get("animation-initial-timing");
    }
  }
  #{ $prefix }--deficit {
    #{ $prefix }__icon {
      color: color.get(get("icon-color-deficit"));
    }
  }
  #{ $prefix }__bar--deficit {
    align-items: flex-end;
    margin-left: auto;
    background-color: color.get(get("bar-color-deficit"));
  }
  #{ $prefix }__values {
    display: flex;
  }
  #{ $prefix }__values #{ $prefix }__value:not(:last-child) {
    margin-right: get("value-margin");
  }
  #{ $prefix }__value--deficit {
    margin-left: auto;
    margin-right: get("value-margin-deficit");
    color: color.get(get("value-color-deficit"));
    & + #{ $prefix }__value--total {
      margin-left: 0;
    }
  }
  #{ $prefix }__value--total {
    margin-left: auto;
    margin-right: 0;
  }
  
  @each $name, $props in $styles {
    #{ $prefix }--#{ $name } {
      margin: map.get($props, "margin");
      #{ $prefix }__track {
        height: map.get($props, "bar-height");
        margin: map.get($props, "track-margin");
      }
      #{ $prefix }__bar:before {
        background-color: color.get(map.get($props, "bar-color"));
      }
      #{ $prefix }__track {
        background-color: color.get(map.get($props, "track-color"));
      }
      #{ $prefix }__icon {
        color: color.get(map.get($props, "icon-color"));
      }
    }
  }

  #{ $prefix }--rounded { 
    #{ $prefix }__track {
      border-radius: get("rounded-border-radius");
    }
  }
  // For Site Loading (Async Content, not charting/visualization)
  #{ $prefix }--indeterminate {
    #{ $prefix }__bar {
      position: absolute;
      top: 0;
      left: 0;
      width: 30%;
      animation: ulu-progress-bar-indeterminate get("animation-indeterminate-duration") linear infinite;
    }
    // &#{ $prefix }--loaded {
    //   #{ $prefix }__bar {
    //     display: none;
    //   }
    // }
  }

  @keyframes ulu-progress-bar {
    from {
      transform: scaleX(0);
    }
    to {
      transform: scaleX(1);
    }
  }

  @keyframes ulu-progress-bar-indeterminate {
    0% {
      left: -100%;
    }
    50% {
      left: 100%;
    }
    100% {
      left: -100%;
    }
  }
}
