////
/// @group data-table
/// For tabular data in native HTML tables. Note, this component can be used with the Vue sticky table plugin.
////

@use "sass:map";
@use "sass:math";
@use "sass:meta";
@use "sass:selector" as sassSelector;

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

// Used for function fallback
$-fallbacks: (
  // // Example mapping fallback to another modules config value
  "line-height" : (
    "function" : meta.get-function("get", false, "typography"),
    "property" : "line-height-dense"
  ),
);

/// Module Settings
/// @type Map
/// @prop {Dimension} cell-padding [(0.5em,)] Padding of the th and td elements.
/// @prop {CssValue} text-align [left] Text align of the table.
/// @prop {String} type-size ["small"] Font size of the table.
/// @prop {Color} background-color [white] Background color of table container.
/// @prop {Color} header-background-color [#f5f4f4] Background color of the the table header.
/// @prop {Color} body-background-color [white] Background color of table body.
/// @prop {Color} footer-background-color [#f3f3f3] Background color of table footer.
/// @prop {Color} color ["type-secondary"] Font color of the table.
/// @prop {Color} header-color ["headline"] Font color for the table header.
/// @prop {Color} footer-color [null] Font color for the table footer.
/// @prop {Number} line-height [true] Line height for the table.
/// @prop {Dimension} column-min-width [6em] Min-width of the th element.
/// @prop {Dimension} first-column-large-min-width [15em] When using "--large-first" style, the min width of the first th element.
/// @prop {Dimension} border-width [1px] Border width of the table.
/// @prop {Color} border-color [#dddddd] Border color for the table.
/// @prop {Color} striped-row-background-color [#eeeeee] Background color for even rows if using "--striped" styling.
/// @prop {Color} muted-row-background-color [#ccc] Background color for odd rows if using "--striped" styling.
/// @prop {Color} muted-row-border-color [null] Border color for odd rows if using "--striped" styling.
/// @prop {Color} highlighted-row-background-color [#ccc] Background color row if using "__row-highlighted" styling.
/// @prop {Color} highlighted-row-border-color [null]  Border color row if using "__row-highlighted" styling.
/// @prop {Dimension} large-header-cell-padding-y [1em]  Vertical padding of header if using "--large-header" styling.
/// @prop {String} caption-type-size ["large"] Type size of table caption.
/// @prop {Color} caption-background-color [null] Background color of table caption.
/// @prop {CssValue} caption-font-weight [bold] Font weight of caption.
/// @prop {CssBalue} caption-border-bottom [null] Bottom border of the caption.
/// @prop {Dimension} caption-margin [(0,)] Margin of the caption.
/// @prop {Dimension} caption-padding [(0.65em 0)] Padding of the caption.
/// @prop {CssValue} caption-text-align [left] Text align of the caption.
/// @prop {String} extra-selector [".wysiwyg table"] Additional selectors to include table styling.

$config: (
  "cell-padding" : (0.5em,),
  "text-align" : left,
  "type-size" : "small",
  "background-color" : white,
  "header-background-color" : #f5f4f4,
  "body-background-color" : white,
  "footer-background-color" : #f3f3f3,
  "color" : "type-secondary",
  "header-color" : "headline",
  "footer-color" : null,
  "line-height" : true,
  "column-min-width" : 6em,
  "first-column-large-min-width" : 15em,
  "border-width" : 1px,
  "border-color" : #dddddd,
  "striped-row-background-color" : #eeeeee,
  "muted-row-background-color" : #ccc,
  "muted-row-border-color" : null,
  "highlighted-row-background-color" : #ccc,
  "highlighted-row-border-color" : null,
  "large-header-cell-padding-y" : 1em,
  "caption-type-size" : "large",
  "caption-background-color" : null,
  "caption-font-weight" : bold,
  "caption-border-bottom" : null,
  "caption-margin" : (0,),
  "caption-padding" : (0.65em 0),
  "caption-text-align" : left,
  "extra-selector" : ".wysiwyg table"
) !default;

/// Change modules $config
/// @param {Map} $changes Map of changes
/// @example scss
///   @include ulu.component-data-table-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-data-table-get("property");

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

/// Output component stylesheet
/// @example scss
///  @include ulu.component-data-table-styles();

@mixin styles {
  $prefix: selector.class("data-table");
  $border: get("border-width") solid color.get(get("border-color"));
  
  $selector-table: sassSelector.parse("#{ $prefix } table, table#{ $prefix }");
  $selector-inner: sassSelector.parse($prefix);
  $extra-selector: get("extra-selector");

  // Allow this to work with wysiwyg class, or as "table" for editor stylesheet
  @if ($extra-selector) {
    $selector-table: sassSelector.parse("#{ $selector-table }, #{ $extra-selector }");
    $selector-inner: sassSelector.parse("#{ $selector-inner }, #{ $extra-selector }");
  }

  // Selector can be on table or wrapping table for convenience
  #{ $selector-table } {
    background-color: color.get(get("background-color"));
    border-collapse: collapse;
    border: $border;
    color: color.get(get("color"));
  }
  #{ $selector-inner } {
    @if (get("type-size") and typography.has-size(get("type-size"))) {
      @include typography.size(get("type-size"), $only-font-size: true);
    }
    line-height: get("line-height");

    caption {
      @if (get("caption-type-size") and typography.has-size(get("caption-type-size"))) {
        @include typography.size(get("caption-type-size"));
      }
      font-weight: get("caption-font-weight");
      text-align: get("caption-text-align");
      margin: get("caption-margin");
      padding: get("caption-padding");
      background-color: get("caption-background-color");
      border-bottom: get("caption-border-bottom");
    }
    th,
    tr,
    td {
      text-align: get("text-align");
    }
    th {
      min-width: get("column-min-width");
    }
    td:not(:last-child), 
    th:not(:last-child) {
      border-right: $border;
    }
    // This makes it work for nested headers last child that aren't the last in the table
    th:not(:first-child) {
      border-left: $border;
    }
    tr + tr {
      border-top: $border;
    }
    thead tr {
      background-color: color.get(get("header-background-color"));
    }
    thead th {
      color: color.get(get("header-color"));
    }
    tbody tr {
      background-color: color.get(get("body-background-color"));
    }
    tfoot tr {
      background-color: color.get(get("footer-background-color"));
      color: color.get(get("footer-color"));
    }
    th,
    td {
      padding: get("cell-padding");
    }
  }
  #{ $prefix }__row-muted {
    background-color: color.get(get("muted-row-background-color"));
    td {
      border-color: color.get(get("muted-row-border-color"));
    }
  }
  #{ $prefix }__row-highlighted {
    background-color: color.get(get("highlighted-row-background-color"));
    td {
      border-color: color.get(get("highlighted-row-border-color"));
    }
  }
  #{ $prefix }--striped {
    tbody tr:nth-child(even) {
      background-color: color.get(get("striped-row-background-color"));
    }
  }
  #{ $prefix }--large-first {
    thead tr:first-child th:first-child,
    tbody td:first-child {
      min-width: get("first-column-large-min-width");
    }
  }
  #{ $prefix }--large-header {
    thead th {
      padding-top: get("large-header-cell-padding-y");
      padding-bottom: get("large-header-cell-padding-y");
    }
  }
  #{ $prefix }--no-border table,
  table#{ $prefix }--no-border  {
    border: none;
  }
}