////
///
/// Math Functions
/// ===========================================================================
///
/// Utility functions for mathematical calculations.
///
/// @group Functions
/// @author Scape Agency
/// @link https://scape.style
/// @since 0.1.0 initial release
/// @access public
///
////

// ============================================================================
// Use
// ============================================================================

@use "sass:math";
@use "sass:list";
@use "sass:meta";

// ============================================================================
// Functions
// ============================================================================

/// Clamp a value between min and max
/// @param {Number} $value - Value to clamp
/// @param {Number} $min - Minimum value
/// @param {Number} $max - Maximum value
/// @return {Number} - Clamped value
@function clamp-value($value, $min, $max) {
    @return math.min(math.max($value, $min), $max);
}

/// Strip unit from a number
/// @param {Number} $number - Number with unit
/// @return {Number} - Unitless number
@function strip-unit($number) {
    @if meta.type-of($number) == "number" and not math.is-unitless($number) {
        @return math.div($number, $number * 0 + 1);
    }
    @return $number;
}

/// Convert pixels to rem
/// @param {Number} $px - Pixel value
/// @param {Number} $base [16] - Base font size in pixels
/// @return {Number} - Rem value
@function px-to-rem($px, $base: 16) {
    @return math.div(strip-unit($px), $base) * 1rem;
}

/// Convert rem to pixels
/// @param {Number} $rem - Rem value
/// @param {Number} $base [16] - Base font size in pixels
/// @return {Number} - Pixel value
@function rem-to-px($rem, $base: 16) {
    @return strip-unit($rem) * $base * 1px;
}

/// Convert pixels to em
/// @param {Number} $px - Pixel value
/// @param {Number} $context [16] - Context font size in pixels
/// @return {Number} - Em value
@function px-to-em($px, $context: 16) {
    @return math.div(strip-unit($px), $context) * 1em;
}

/// Calculate modular scale value
/// @param {Number} $step - Step in the scale (can be negative)
/// @param {Number} $base [1rem] - Base size
/// @param {Number} $ratio [1.25] - Scale ratio (e.g., 1.25 = major third)
/// @return {Number} - Scaled value
@function modular-scale($step, $base: 1rem, $ratio: 1.25) {
    @return $base * math.pow($ratio, $step);
}

/// Calculate fluid value between two breakpoints
/// @param {Number} $min-value - Minimum value
/// @param {Number} $max-value - Maximum value
/// @param {Number} $min-viewport - Minimum viewport width
/// @param {Number} $max-viewport - Maximum viewport width
/// @return {String} - CSS clamp() function
@function fluid-value(
    $min-value,
    $max-value,
    $min-viewport: 320px,
    $max-viewport: 1200px
) {
    $slope: math.div(
        strip-unit($max-value) - strip-unit($min-value),
        strip-unit($max-viewport) - strip-unit($min-viewport)
    );
    $intercept: strip-unit($min-value) - $slope * strip-unit($min-viewport);

    @return clamp(
        #{$min-value},
        #{$intercept}px + #{$slope * 100}vw,
        #{$max-value}
    );
}

/// Calculate percentage
/// @param {Number} $part - The part
/// @param {Number} $whole - The whole
/// @return {Number} - Percentage
@function percentage($part, $whole) {
    @return math.div($part, $whole) * 100%;
}

/// Round to specified decimal places
/// @param {Number} $number - Number to round
/// @param {Number} $decimals [2] - Number of decimal places
/// @return {Number} - Rounded number
@function round-to($number, $decimals: 2) {
    $factor: math.pow(10, $decimals);
    @return math.div(math.round($number * $factor), $factor);
}
