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

////
/// @package theming
/// @group Elevations
////

$factor: var(--ig-elevation-factor, 1);

/// Checks if the passed argument is a valid box-shadow.
/// @access private
/// @param {List} $shadow - A list of shadow properties.
/// @return {Boolean} Returns a boolean depending on if the passed argument is a valid shadow.
@function _is-shadow($shadow) {
    $lastIndex: list.length($shadow);

    @if meta.type-of($shadow) != list {
        @return false;
    }

    @if $lastIndex < 2 or $lastIndex > 5 {
        @return false;
    }

    @if list.separator($shadow) != space {
        @return false;
    }

    @return true;
}

/// Transforms the passed box-shadow list according to the elevation factor value.
/// @access private
/// @param {List} $shadow - A list of shadow properties.
/// @return {List} The transformed shadow list.
@function _transform-shadow($shadow) {
    $result: ();

    @each $value in $shadow {
        @if meta.type-of($value) != color and $value != 0 and $value != inset {
            $result: list.append($result, calc($factor * $value));
        } @else {
            $result: list.append($result, $value);
        }
    }

    @return $result;
}

/// Sorts out a list of valid only box-shadows.
/// @access public
/// @param {List} $shadows - A list of shadow values.
/// @example scss
///   .my-component {
///     box-shadow: box-shadow((0 0 2px 3px black, 0 6px 9px orange));
///   }
///
///   // Output
///   .my-component {
///     box-shadow:
///         0 0 calc(--ig-elevation-factor * 2px) calc(--ig-elevation-factor * 3px) black,
///         0 calc(--ig-elevation-factor * 6px) calc(--ig-elevation-factor * 9px) orange;
///   }
/// @return {List} The transformed shadow list.
/// @requires {function} _is-shadow
/// @requires {function} _transform-shadow
@function box-shadow($shadows) {
    $result: ();
    $s: ();

    @if meta.type-of($shadows) != list {
        @error 'shadow expects a list of box-shadow values. ex.: shadow((0 2px 2px black))';
    }

    @if list.separator($shadows) == space {
        $s: list.append($s, $shadows);
    }

    @if list.separator($shadows) == comma {
        $s: $shadows;
    }

    @each $shadow in $s {
        @if _is-shadow($shadow) {
            $result: list.append($result, _transform-shadow($shadow), $separator: comma);
        }
    }

    @return $result;
}

/// Gets a CSS elevation variable by name.
/// @access public
/// @param {String} $name - The name of the shadow.
/// @example scss
///   .my-component {
///     box-shadow: elevation(5); // var(--ig-elevation-5)
///   }
/// @return {String} The CSS elevation variable
@function elevation($name) {
    @return var(--ig-elevation-#{$name});
}
