////
/// @group button-verbose
/// A button that has additional markup (ie. page with description for example). Used on things like linear pagination (up next).
////

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

@use "../utils";
@use "../color";
@use "../element";
@use "../selector";
@use "../button";

// Used for function fallback
$-fallbacks: (
  "border-radius" : (
    "function" : meta.get-function("get", false, "element"),
    "property" : "border-radius"
  ),
  "box-shadow" : (
    "function" : meta.get-function("get", false, "element"),
    "property" : "box-shadow"
  ),
  "box-shadow-hover" : (
    "function" : meta.get-function("get", false, "element"),
    "property" : "box-shadow-hover"
  ),
  "border-color" : (
    "function" : meta.get-function("get", false, "button"),
    "property" : "border-color"
  ),
  "border-width" : (
    "function" : meta.get-function("get", false, "button"),
    "property" : "border-width"
  )
);

/// Module Settings
/// @type Map
/// @prop {Color} background-color [white] Background color for the button.
/// @prop {Color} background-color-hover [link] Background color for the button when hovered or focused.
/// @prop {String} border-radius [border-radius] Border radius of the button.
/// @prop {String} border-width [null] Border width (or set to true to inherit button border width default)
/// @prop {String} border-color [null] Border color (or set to true to inherit button border width default)
/// @prop {CssValue} box-shadow [true] Box shadow for the button. If set to true, uses default box-shadow.
/// @prop {CssValue} box-shadow-hover [true] Box shadow for the button when hovered or focused. If set to true, uses default box-shadow-hover.
/// @prop {String} color [type] Text color for the button.
/// @prop {String} color-hover [type] Text color for the button when hovered or focused.
/// @prop {Color} icon-color [gray] Color for button icons.
/// @prop {Color} icon-color-hover [null] Optional color for icon when hovered
/// @prop {Dimension} icon-font-size [1.25rem] Font size for the button.
/// @prop {Number} line-height [1.2] Line height for button text.
/// @prop {Dimension} margin [1em] Margin for the button.
/// @prop {Dimension} margin-inline [0.75em] Margin for the button when using the inline modifier.
/// @prop {Dimension} min-width [20rem] Min-width of the button.
/// @prop {Dimension} padding-x [0.65em] Horizontal padding of the button.
/// @prop {Dimension} padding-y [1em] Vertical padding of the button.
/// @prop {String} title-color [link] Color of the title of the button.
/// @prop {String} title-color-hover [link-hover] Color of the title of the button when hovered or focused.
/// @prop {Dimension} title-margin [0.5em] Margin for the button's title.
/// @prop {Boolean} cap [false] Enable left cap style 
/// @prop {Color} cap-side ["left"] The side that gets the cap
/// @prop {Number} cap-match-radius [true] The cap should have be rounded to match the parent's border radius
/// @prop {Map} cap-options The options for cap (see element.cap for options)
/// @prop {Map} cap-options-hover The options for cap when hovered

$config: (
  "background-color" : white,
  "background-color-hover" : #F7F8F7,
  "border-radius" : true,
  "border-color" : null,
  "border-width" : null,
  "box-shadow" : true,
  "box-shadow-hover" : true,
  "color" : "type",
  "color-hover" : "type",
  "icon-color": gray,
  "icon-color-hover": null,
  "icon-font-size" : 1.25rem,
  "line-height" : 1.2,
  "margin" : 1em,
  "margin-inline" : 0.75em,
  "min-width": 20rem,
  "padding-x": 0.75em,
  "padding-y": 1em,
  "title-color": "link",
  "title-margin" : 0.5em,
  "title-color-hover" : "link-hover",
  "cap" : false,
  "cap-side" : "left",
  "cap-match-radius" : true,
  "cap-options" : (
    "color" : "link",
    "size" : 0.5rem,
  ),
  "cap-options-hover" : (
    "color" : "link-hover"
  ),
) !default;

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

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

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

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

/// Prints component styles
/// @example scss
///   @include ulu.component-button-verbose-styles();
/// @example html {preview} - Basic Example
///   <a href="#" class="button-verbose">
///     <strong class="button-verbose__title">Example Link</strong>
///     <span class="button-verbose__body">This is the body</span>
///     <span class="button-verbose__icon fas fa-arrow-right" aria-hidden="true"></span>
///   </a>

@mixin styles {
  $prefix: selector.class("button-verbose");
  $padding-x: get("padding-x");
  $padding-y: get("padding-y");
  $padding-right: ($padding-x * 2) + 1em;
  $cap-side: get("cap-side");
  $cap-defaults: (
    "offset" : utils.if-type("number", get("border-width"), 0),
    "border-radius" : utils.when(get("cap-match-radius"), get("border-radius"), 0),
    "padding-adjust" : utils.when(utils.is-side($cap-side), $padding-x, $padding-y)
  );
  
  #{ $prefix } {
    position: relative; // For cap and icon
    display: block;
    text-decoration: none;
    border-radius: get("border-radius");
    @if (get("border-width")) {
      border: get("border-width") solid color.get(get("border-color"));
    }
    box-shadow: get("box-shadow");
    line-height: get("line-height");
    margin-bottom: get("margin");
    max-width: 100%;
    width: get("min-width");
    background-color: color.get(get("background-color"));
    padding: $padding-y $padding-right $padding-y $padding-x;
    color: color.get(get("color"));
    text-align: left;

    &:hover,
    &:focus {
      color: color.get(get("color-hover"));
      background-color: color.get(get("background-color-hover"));
      box-shadow: get("box-shadow-hover");
      @if get("title-color-hover") {
        #{ $prefix }__title  {
          color: color.get(get("title-color-hover"));
        }
      }
      @if get("icon-color-hover") {
        #{ $prefix }__icon  {
          color: color.get(get("icon-color-hover"));
        }
      }
    }
    @if get("cap") {
      @include element.cap(
        $side: $cap-side,
        $options: map.merge($cap-defaults, get("cap-options"))
      );
      @if get("cap-options-hover") {
        &:hover,
        &:focus {
          @include element.cap-appearance(
            $side: $cap-side,
            $options: get("cap-options-hover")
          );
        }
      }
    }
  }
  #{ $prefix }__title,
  #{ $prefix }__body {
    display: block;
    &:first-child {
      margin-bottom: get("title-margin");
    }
  }
  #{ $prefix }__title {
    color: color.get(get("title-color"));
  }
  #{ $prefix }__icon {
    position: absolute;
    top: 50%;
    right: $padding-x;
    transform: translateY(-50%);
    font-size: get("icon-font-size");
    color: color.get(get("icon-color"));
  }
  #{ $prefix }--inline {
    display: inline-block;
    margin-right: get("margin-inline");
    &:last-child {
      margin-right: 0;
    }
  }
  #{ $prefix }--full-width {
    width: 100%;
  }
}