// ============================================================================
// move.gl | Progress Loader Mixins
// ============================================================================
// Copyright 2025 Scape Agency BV
// Licensed under MIT License
// ============================================================================

////
/// Progress Loader Mixins
/// ===========================================================================
///
/// This module provides mixins for progress bar loading animations.
///
/// @group Loaders
/// @author Scape Agency
/// @link https://move.gl
/// @since 0.1.0
/// @access public
////

@use "../../variables" as *;


// ============================================================================
// Keyframes
// ============================================================================

///
/// Progress fill animation keyframes.
///
@mixin keyframes_progress_fill {
    @keyframes progress-fill {
        0% { width: 0%; }
        100% { width: 100%; }
    }
}

///
/// Progress indeterminate animation keyframes.
///
@mixin keyframes_progress_indeterminate {
    @keyframes progress-indeterminate {
        0% { left: 0; right: 100%; }
        50% { left: 25%; right: 0; }
        100% { left: 100%; right: 0; }
    }
}

///
/// Progress stripe animation keyframes.
///
@mixin keyframes_progress_stripe {
    @keyframes progress-stripe {
        0% { background-position: 0 0; }
        100% { background-position: 30px 0; }
    }
}

///
/// Progress pulse animation keyframes.
///
@mixin keyframes_progress_pulse {
    @keyframes progress-pulse {
        0% { transform: scaleX(0.1); transform-origin: left; }
        50% { transform: scaleX(1); transform-origin: left; }
        51% { transform: scaleX(1); transform-origin: right; }
        100% { transform: scaleX(0.1); transform-origin: right; }
    }
}

///
/// Progress split animation keyframes.
///
@mixin keyframes_progress_split {
    @keyframes progress-split {
        0% { width: 0; left: 50%; }
        50% { width: 100%; left: 0%; }
        100% { width: 0; left: 50%; }
    }
}

///
/// Progress flow animation keyframes.
///
@mixin keyframes_progress_flow {
    @keyframes progress-flow {
        0% { background-position: -200% 0, 0 0, 0 0, 0 0; }
        100% { background-position: 200% 0, 0 0, 0 0, 0 0; }
    }
}

///
/// Circle progress rotation.
///
@mixin keyframes_circle_progress {
    @keyframes circle-progress {
        0% { transform: rotate(0deg); }
        100% { transform: rotate(360deg); }
    }
}

///
/// Dot active state animation.
///
@mixin keyframes_dot_active {
    @keyframes dot-active {
        0%, 100% { background: var(--loader-inactive, rgba(255, 255, 255, 0.3)); }
        50% { background: var(--loader-color, #FFF); }
    }
}

///
/// Segment fill animation keyframes.
///
@mixin keyframes_segment_fill {
    @keyframes segment-fill {
        0%, 20% { background: var(--loader-inactive, rgba(255, 255, 255, 0.15)); }
        40%, 100% { background: var(--loader-color, #FFF); }
    }
}


// ============================================================================
// Progress Loader Mixins
// ============================================================================

///
/// Basic progress bar loader.
///
/// @param {Length} $width [240px] - Bar width.
/// @param {Length} $height [5px] - Bar height.
/// @param {Color} $bg-color [rgba(255,255,255,0.15)] - Background color.
/// @param {Color} $fill-color [#FF3D00] - Fill color.
/// @param {Time} $duration [2s] - Animation duration.
///
@mixin loader_progress_fill(
    $width: 240px,
    $height: 5px,
    $bg-color: rgba(255, 255, 255, 0.15),
    $fill-color: $loader-accent,
    $duration: 2s
) {
    width: $width;
    height: $height;
    border-radius: calc($height / 2);
    background: var(--loader-bg, $bg-color);
    position: relative;
    overflow: hidden;

    &::after {
        content: '';
        position: absolute;
        left: 0;
        top: 0;
        height: 100%;
        width: 0%;
        border-radius: inherit;
        background: var(--loader-color, $fill-color);
        animation: progress-fill $duration ease infinite;
    }
}

///
/// Indeterminate progress loader.
///
/// @param {Length} $width [240px] - Bar width.
/// @param {Length} $height [5px] - Bar height.
/// @param {Color} $bg-color [rgba(255,255,255,0.15)] - Background color.
/// @param {Color} $fill-color [#FFF] - Fill color.
/// @param {Time} $duration [1.5s] - Animation duration.
///
@mixin loader_progress_indeterminate(
    $width: 240px,
    $height: 5px,
    $bg-color: rgba(255, 255, 255, 0.15),
    $fill-color: $loader-color,
    $duration: 1.5s
) {
    width: $width;
    height: $height;
    border-radius: calc($height / 2);
    background: var(--loader-bg, $bg-color);
    position: relative;
    overflow: hidden;

    &::after {
        content: '';
        position: absolute;
        top: 0;
        height: 100%;
        border-radius: inherit;
        background: var(--loader-color, $fill-color);
        animation: progress-indeterminate $duration ease-in-out infinite;
    }
}

///
/// Striped progress loader.
///
/// @param {Length} $width [240px] - Bar width.
/// @param {Length} $height [10px] - Bar height.
/// @param {Color} $color [#FFF] - Stripe color.
/// @param {Time} $duration [1s] - Animation duration.
///
@mixin loader_progress_stripe(
    $width: 240px,
    $height: 10px,
    $color: $loader-color,
    $duration: $loader-speed
) {
    width: $width;
    height: $height;
    border-radius: calc($height / 2);
    background:
        repeating-linear-gradient(
            135deg,
            var(--loader-color, $color) 0 10px,
            var(--loader-accent, rgba($color, 0.5)) 10px 20px
        ) 0 / 200%;
    animation: progress-stripe $duration linear infinite;
}

///
/// Fill with stripe animation.
///
/// @param {Length} $width [240px] - Bar width.
/// @param {Length} $height [10px] - Bar height.
/// @param {Color} $bg-color [rgba(255,255,255,0.15)] - Background color.
/// @param {Color} $fill-color [#FFF] - Fill color.
/// @param {Time} $fill-duration [3s] - Fill duration.
/// @param {Time} $stripe-duration [0.5s] - Stripe animation duration.
///
@mixin loader_progress_stripe_fill(
    $width: 240px,
    $height: 10px,
    $bg-color: rgba(255, 255, 255, 0.15),
    $fill-color: $loader-color,
    $fill-duration: 3s,
    $stripe-duration: 0.5s
) {
    width: $width;
    height: $height;
    border-radius: calc($height / 2);
    background: var(--loader-bg, $bg-color);
    position: relative;
    overflow: hidden;

    &::after {
        content: '';
        position: absolute;
        left: 0;
        top: 0;
        height: 100%;
        width: 0%;
        border-radius: inherit;
        background:
            repeating-linear-gradient(
                135deg,
                var(--loader-color, $fill-color) 0 10px,
                rgba($fill-color, 0.5) 10px 20px
            );
        background-size: 200% 100%;
        animation:
            progress-fill $fill-duration ease infinite,
            progress-stripe $stripe-duration linear infinite;
    }
}

///
/// Pulsing progress loader.
///
/// @param {Length} $width [240px] - Bar width.
/// @param {Length} $height [8px] - Bar height.
/// @param {Color} $bg-color [rgba(255,255,255,0.15)] - Background color.
/// @param {Color} $fill-color [#FFF] - Fill color.
/// @param {Time} $duration [1s] - Animation duration.
///
@mixin loader_progress_pulse(
    $width: 240px,
    $height: 8px,
    $bg-color: rgba(255, 255, 255, 0.15),
    $fill-color: $loader-color,
    $duration: $loader-speed
) {
    width: $width;
    height: $height;
    border-radius: calc($height / 2);
    background: var(--loader-bg, $bg-color);
    position: relative;
    overflow: hidden;

    &::after {
        content: '';
        position: absolute;
        left: 0;
        top: 0;
        height: 100%;
        width: 100%;
        border-radius: inherit;
        background: var(--loader-color, $fill-color);
        animation: progress-pulse $duration ease-in-out infinite;
    }
}

///
/// Split fill progress loader.
///
/// @param {Length} $width [240px] - Bar width.
/// @param {Length} $height [5px] - Bar height.
/// @param {Color} $bg-color [rgba(255,255,255,0.15)] - Background color.
/// @param {Color} $fill-color [#FFF] - Fill color.
/// @param {Time} $duration [1.5s] - Animation duration.
///
@mixin loader_progress_split(
    $width: 240px,
    $height: 5px,
    $bg-color: rgba(255, 255, 255, 0.15),
    $fill-color: $loader-color,
    $duration: 1.5s
) {
    width: $width;
    height: $height;
    border-radius: calc($height / 2);
    background: var(--loader-bg, $bg-color);
    position: relative;
    overflow: hidden;

    &::after {
        content: '';
        position: absolute;
        top: 0;
        height: 100%;
        border-radius: inherit;
        background: var(--loader-color, $fill-color);
        animation: progress-split $duration ease-in-out infinite;
    }
}

///
/// Gradient flow progress loader.
///
/// @param {Length} $width [240px] - Bar width.
/// @param {Length} $height [8px] - Bar height.
/// @param {Color} $bg-color [rgba(255,255,255,0.15)] - Background color.
/// @param {Color} $start-color [#FF3D00] - Gradient start.
/// @param {Color} $end-color [#FFF] - Gradient end.
/// @param {Time} $duration [1.5s] - Animation duration.
///
@mixin loader_progress_gradient(
    $width: 240px,
    $height: 8px,
    $bg-color: rgba(255, 255, 255, 0.15),
    $start-color: $loader-accent,
    $end-color: $loader-color,
    $duration: 1.5s
) {
    width: $width;
    height: $height;
    border-radius: calc($height / 2);
    background:
        linear-gradient(90deg, var(--loader-start, $start-color) 50%, var(--loader-end, $end-color) 0) calc(100% - var(--_p, 0%)) / 200%,
        linear-gradient(var(--loader-bg, $bg-color) 0 0) 0% / var(--_p, 0%);
    background-repeat: no-repeat;
    animation: progress-flow $duration linear infinite;
}

///
/// Dotted progress loader.
///
/// @param {Length} $width [240px] - Container width.
/// @param {Length} $height [16px] - Dot size.
/// @param {Color} $bg-color [rgba(255,255,255,0.3)] - Dot inactive color.
/// @param {Color} $active-color [#FFF] - Dot active color.
/// @param {Time} $duration [1s] - Animation duration.
///
@mixin loader_progress_dots(
    $width: 240px,
    $height: 16px,
    $bg-color: rgba(255, 255, 255, 0.3),
    $active-color: $loader-color,
    $duration: $loader-speed
) {
    width: $width;
    height: $height;
    position: relative;
    display: flex;
    justify-content: space-between;
    align-items: center;

    span {
        width: $height;
        height: $height;
        border-radius: 50%;
        background: var(--loader-inactive, $bg-color);
        animation: dot-active $duration ease-in-out infinite;

        @for $i from 1 through 10 {
            &:nth-child(#{$i}) {
                animation-delay: calc(($i - 1) * 0.1s);
            }
        }
    }
}

///
/// Segmented progress loader.
///
/// @param {Length} $width [200px] - Bar width.
/// @param {Length} $height [20px] - Bar height.
/// @param {Number} $segments [5] - Number of segments.
/// @param {Color} $bg-color [rgba(255,255,255,0.15)] - Inactive color.
/// @param {Color} $active-color [#FFF] - Active color.
/// @param {Time} $duration [2s] - Animation duration.
///
@mixin loader_progress_segments(
    $width: 200px,
    $height: 20px,
    $segments: 5,
    $bg-color: rgba(255, 255, 255, 0.15),
    $active-color: $loader-color,
    $duration: 2s
) {
    width: $width;
    height: $height;
    display: flex;
    gap: 4px;

    span {
        flex: 1;
        height: 100%;
        background: var(--loader-inactive, $bg-color);
        border-radius: 2px;
        animation: segment-fill $duration ease infinite;

        @for $i from 1 through $segments {
            &:nth-child(#{$i}) {
                animation-delay: calc(($i - 1) * ($duration / $segments));
            }
        }
    }
}

///
/// Circular progress indicator.
///
/// @param {Length} $size [60px] - Circle size.
/// @param {Length} $stroke [4px] - Stroke width.
/// @param {Color} $bg-color [rgba(255,255,255,0.15)] - Track color.
/// @param {Color} $fill-color [#FFF] - Progress color.
/// @param {Time} $duration [1.5s] - Animation duration.
///
@mixin loader_progress_circle(
    $size: 60px,
    $stroke: 4px,
    $bg-color: rgba(255, 255, 255, 0.15),
    $fill-color: $loader-color,
    $duration: 1.5s
) {
    width: $size;
    height: $size;
    border-radius: 50%;
    border: $stroke solid var(--loader-bg, $bg-color);
    position: relative;

    &::after {
        content: '';
        position: absolute;
        top: calc(-1 * $stroke);
        left: calc(-1 * $stroke);
        width: $size;
        height: $size;
        border-radius: 50%;
        border: $stroke solid transparent;
        border-top-color: var(--loader-color, $fill-color);
        animation: circle-progress $duration ease-in-out infinite;
    }
}
