////
/// @group root
/// Responsible for outputting the base :root custom properties for ulu
////

@use "sass:map";

@use "../utils";
@use "../cssvar";
@use "../layout";

/// Module Settings
/// @type Map
/// @prop {String} sticky-offset-top [cssvar.add(cssvar.use-ulu("header-height"), cssvar.use-ulu("sticky-margin"))] - Total top offset for sticky positioning. Accounts for the primary header and any required breathing room.
/// @prop {Dimension} sticky-offset-bottom [0px] - Bottom offset for sticky positioning. Useful when accounting for fixed footers or mobile navigation bars.
/// @prop {Dimension} sticky-margin [0px] - Desired visual space between a sticky element and the bottom of the header.
/// @prop {Dimension} header-height [0px] - The physical rendered height of the site's fixed/sticky header.
/// @prop {String} fullscreen-height [cssvar.subtract(100dvh, cssvar.use-ulu("header-height"))] - Utility height representing the visible viewport space below the header.
/// @prop {String} fullscreen-height-sticky [cssvar.subtract(100dvh, cssvar.use-ulu("sticky-offset-top"), cssvar.use-ulu("sticky-offset-bottom"))] - Utility height representing the safe scrollable area between all sticky layout boundaries.

$config: (
  "sticky-offset-top": cssvar.add(cssvar.use-ulu("header-height"), cssvar.use-ulu("sticky-margin")),
  "sticky-offset-bottom": 0px,
  "sticky-margin": 0px,
  "header-height": 0px,
  "fullscreen-height": cssvar.subtract(100dvh, cssvar.use-ulu("header-height")),
  "fullscreen-height-sticky": cssvar.subtract(100dvh, cssvar.use-ulu("sticky-offset-top"), cssvar.use-ulu("sticky-offset-bottom"))
) !default;

/// Change modules $config
/// @param {Map} $changes Map of changes

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

/// Get a config option
/// @param {String} $name Name of property

@function get($name) {
  @return utils.require-map-get($config, $name, "base root [config]");
}

/// Global root variables (CSS Custom Properties)
/// @type Map

$cssvars: () !default;

/// Set global root variables
/// - Supports mapping values to breakpoints. Values can be literal or a configuration map with `value` and `breakpoints` keys.
/// @example scss Example usage with breakpoints
///   @include ulu.base-root-set-cssvars((
///     "base-color": red,
///     "responsive-size": (
///       "value": 1rem,
///       "breakpoints": (
///         "medium": (
///           "direction": "up",
///           "value": 2rem
///         )
///       )
///     )
///   ));
/// @param {Map} $changes Map of changes
/// @param {String} $merge-mode Merge mode see utils.map-merge() [null|"deep"|"overwrite"]

@mixin set-cssvars($changes, $merge-mode: null) {
  $cssvars: utils.map-merge($cssvars, $changes, $merge-mode) !global;
}

/// Output custom properties in :root for base stylesheet
/// @example scss
///  @include ulu.base-root-styles();

@mixin styles {
  @include utils.file-header('base', 'root');
  // Core/default css-vars
  :root {
    @include declare();
  }
  html {
    scroll-padding-top: cssvar.use-ulu("sticky-offset-top");
  }
}

/// Declare custom properties for ulu (without selector)
/// @example scss
///  .cms-backend {
///    @include ulu.base-root-declare();
///  }

@mixin declare() {
  @include custom-properties();
  @include cssvar.declare-breakpoint();
  @include cssvar.declare-all($cssvars);
}

/// Output custom properties for ulu

@mixin custom-properties() {
  $prefix: "ulu";
  // Just looping through $config for now (since all are root properties)
  // This may need to be adjusted if config is used for something else
  @include cssvar.declare-all($config, $prefix);
  @include cssvar.declare("scrollbar-width", 0px, $prefix); // Set by JS

  @each $name, $props in layout.$widths {
    @include cssvar.declare("width-#{ $name }", $props, $prefix);
  }

  @each $name, $props in layout.$max-widths {
    @include cssvar.declare("max-width-#{ $name }", $props, $prefix);
  }
}