@use 'sass:color';
@use 'sass:list';
////
/// @group utils.shadows
////

@use 'math.scss' as *;

$umbra-y: (0px, 12px);
$umbra-blur: (0px, 15px);
$umbra-spread: (0px, -4px);
$umbra-opacity: (0.05, 0.25);

$penumbra-y: (1px, 24px);
$penumbra-blur: (0px, 38px);
$penumbra-spread: (0px, 0px);
$penumbra-opacity: (0, 0.15);

$ambient-y: (0px, 9px);
$ambient-blur: (0px, 50px);
$ambient-spread: (0px, 0px);
$ambient-opacity: (0.05, 0.1);

// ratio between the blur and y offset for a default shadow (e.g. y: 2px / blur: 5px = 0.4)
$shadow-ratio: 0.4;

// growth factor applied to the blur of shadows as they get larger (offset to grow faster than
// blur so things appear to be further off the page)
$shadow-growth: 1.25;

/// Creates the syntax for a multi-level shadow
/// @param {*} $blur
/// @param {*} $alpha
/// @param {*} $color
/// @example depth-shadow(2, 0.5, purple) // => shadow: 0 1px 2px -0.5px rgba(128, 0, 128, 0.2295), 0 3.5px 4px 0px rgba(128, 0, 128, 0.03425), 0 1px 5px 1px rgba(128, 0, 128, 0.072)

@function depth-shadow($level: 5, $alpha: 0.2, $color: black, $suppress-spread: false) {
    $level: divide($level, 20);
    $ease: false;
    $round: 2;

    $alpha: $alpha * color.alpha($color);

    $umbra-opacity: intp($level, $umbra-opacity) * (5 * $alpha);
    $penumbra-opacity: intp($level, $penumbra-opacity) * (3 * $alpha);
    $ambient-opacity: intp($level, $ambient-opacity) * (3 * $alpha);

    // prettier-ignore
    $umbra: 0
        intp($level, $umbra-y, $ease, $round) * if(sass($suppress-spread): 1.1; else: 1)
        intp($level, $umbra-blur, $ease, $round) * if(sass($suppress-spread): 0.6; else: 1)
        if(sass($suppress-spread): #{''}; else: intp($level, $umbra-spread, $ease, $round))
        rgba($color, $umbra-opacity);

    $penumbra: 0 intp($level, $penumbra-y, $ease, $round)
        intp($level, $penumbra-blur, $ease, $round)
        if(sass($suppress-spread): #{''}; else: intp($level, $penumbra-spread, $ease, $round))
        rgba($color, $penumbra-opacity * if(sass($suppress-spread): 0.75; else: 1));

    $ambient: 0 intp($level, $ambient-y, $ease, $round) intp($level, $ambient-blur, $ease, $round)
        if(sass($suppress-spread): #{''}; else: intp($level, $ambient-spread, $ease, $round))
        rgba($color, $ambient-opacity);

    @return (#{$umbra}, #{$penumbra}, #{$ambient});
}

/// Generates a depth shadow using the box-shadow property

@mixin depth-shadow($level: 5, $alpha: 0.2, $color: black) {
    box-shadow: depth-shadow($level, $alpha, $color);
}

@function depth-shadow-effect($level: 5, $alpha: 0.2, $color: black) {
    $shadow: depth-shadow($level, $alpha, $color, true);
    @return drop-shadow(list.nth($shadow, 1)) drop-shadow(list.nth($shadow, 2))
        drop-shadow(list.nth($shadow, 3));
}

/// Generates a depth shadow using the filter property

@mixin depth-shadow-effect($level: 5, $alpha: 0.2, $color: black) {
    filter: depth-shadow-effect($level, $alpha, $color);
}

/// Function that creates a standardized box shadow
///
/// @example shadow(2) // => 0 1px 2px -0.5px rgba(0, 0, 0, 0.21), 0 3.5px 4px 0px rgba(0, 0, 0, 0.015), 0 1px 5px 1px rgba(0, 0, 0, 0.06);

@function shadow($depth, $alpha: 0.15, $color: black) {
    $blur: $depth;
    $y: pow($depth * $shadow-ratio, $shadow-growth);

    @return 0 #{$y}px #{$blur}px rgba($color, $alpha);
}

/// Mixin that create a standard box-shadow
///
/// @example shadow(8, 0.1) // => box-shadow: 0 ... rgba(0, 0, 0, 0.1);

@mixin shadow($depth: 5, $alpha: 0.15, $color: black) {
    box-shadow: shadow($depth, $alpha, $color);
}

/// Create a standard drop-shadow as a css filter effect (creates
/// non-rectangular shadows on any content)
///
/// @example shadow-effect(2, gray) // => filter: drop-shadow(0 1px 2px -0.5px rgba(0, 0, 0, 0.21), 0 3.5px 4px 0px rgba(0, 0, 0, 0.015), 0 1px 5px 1px rgba(0, 0, 0, 0.06));

@mixin shadow-effect($depth: 5, $alpha: 0.15, $color: black) {
    filter: drop-shadow(shadow($depth, $alpha, $color));
}
