////
///
/// Base Animations Mixin Module
/// =========================================================================
///
/// Provides the foundational animation infrastructure for move.gl,
/// including the base animation mixin used by all other animation modules,
/// accessibility considerations for reduced motion preferences, and
/// utility mixins for common animation patterns.
///
/// @group Animations
/// @author Scape Agency
/// @link https://move.gl
/// @since 0.1.0 initial release
/// @access public
///
////


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

@use "sass:map";
@use "sass:list";
@use "../../dev" as *;
@use "../../variables" as *;


// ============================================================================
// Base Animation Mixin
// ============================================================================

///
/// Base Animation Mixin
/// -----------------------------------------------------------------------
/// The foundation mixin for all animations. Provides a consistent
/// structure for defining animations with customizable properties.
///
/// @name animate_base
/// @param {String} $name [none] - The animation name (keyframes reference)
/// @param {Time} $duration [$animate_base_duration] - Animation duration
/// @param {String} $timing_function [$animate_base_timing_function] - Easing
/// @param {Number|String} $iteration_count - Number of iterations
/// @param {Time} $delay [$animate_base_delay] - Delay before start
/// @param {String} $direction [$animate_base_direction] - Direction
/// @param {String} $fill_mode [both] - Styles before/after animation
/// @param {String} $play_state [running] - Running or paused
///
/// @example scss - Basic usage
///   .element {
///     @include animate_base(fadeIn, 0.5s, ease-out, 1);
///   }
///
@mixin animate_base(
    $name: none,
    $duration: $animate_base_duration,
    $timing_function: $animate_base_timing_function,
    $iteration_count: $animate_base_iteration_count,
    $delay: $animate_base_delay,
    $direction: $animate_base_direction,
    $fill_mode: both,
    $play_state: running
) {
    animation-name: $name;
    animation-duration: $duration;
    animation-timing-function: $timing_function;
    animation-iteration-count: $iteration_count;
    animation-delay: $delay;
    animation-direction: $direction;
    animation-fill-mode: $fill_mode;
    animation-play-state: $play_state;
}


///
/// Animation Shorthand Mixin
/// -----------------------------------------------------------------------
/// Applies animation using the shorthand property for concise output.
///
/// @name animate_shorthand
/// @param {String} $name - Animation name
/// @param {Time} $duration [0.5s] - Duration
/// @param {String} $timing [ease-in-out] - Timing function
/// @param {Time} $delay [0s] - Delay
/// @param {Number|String} $iterations [1] - Iteration count
/// @param {String} $direction [normal] - Direction
/// @param {String} $fill_mode [both] - Fill mode
///
@mixin animate_shorthand(
    $name,
    $duration: 0.5s,
    $timing: ease-in-out,
    $delay: 0s,
    $iterations: 1,
    $direction: normal,
    $fill_mode: both
) {
    animation: $name $duration $timing $delay $iterations $direction $fill_mode;
}


// ============================================================================
// Animation State Mixins
// ============================================================================

///
/// Paused Animation State
/// -----------------------------------------------------------------------
/// Pauses an animation. Useful for hover effects or JavaScript control.
///
@mixin animate_paused {
    animation-play-state: paused;
}

///
/// Running Animation State
/// -----------------------------------------------------------------------
/// Ensures an animation is running.
///
@mixin animate_running {
    animation-play-state: running;
}


// ============================================================================
// Animation Property Mixins
// ============================================================================

///
/// Animation Duration
/// -----------------------------------------------------------------------
/// Sets the animation duration independently.
///
/// @param {Time} $duration - The duration value
///
@mixin animate_duration($duration) {
    animation-duration: $duration;
}

///
/// Animation Delay
/// -----------------------------------------------------------------------
/// Sets the animation delay independently.
///
/// @param {Time} $delay - The delay value
///
@mixin animate_delay($delay) {
    animation-delay: $delay;
}

///
/// Animation Timing Function
/// -----------------------------------------------------------------------
/// Sets the animation timing function independently.
///
/// @param {String} $timing - The timing function
///
@mixin animate_timing($timing) {
    animation-timing-function: $timing;
}

///
/// Animation Iteration Count
/// -----------------------------------------------------------------------
/// Sets the animation iteration count independently.
///
/// @param {Number|String} $count - Number of iterations or 'infinite'
///
@mixin animate_iterations($count) {
    animation-iteration-count: $count;
}


// ============================================================================
// Animation Fill Mode Mixins
// ============================================================================

///
/// Fill Mode - Forwards
/// -----------------------------------------------------------------------
/// Retains styles from the last keyframe after animation ends.
///
@mixin animate_fill_forwards {
    animation-fill-mode: forwards;
}

///
/// Fill Mode - Backwards
/// -----------------------------------------------------------------------
/// Applies styles from the first keyframe before animation starts.
///
@mixin animate_fill_backwards {
    animation-fill-mode: backwards;
}

///
/// Fill Mode - Both
/// -----------------------------------------------------------------------
/// Combines forwards and backwards fill modes.
///
@mixin animate_fill_both {
    animation-fill-mode: both;
}

///
/// Fill Mode - None
/// -----------------------------------------------------------------------
/// No fill mode applied.
///
@mixin animate_fill_none {
    animation-fill-mode: none;
}


// ============================================================================
// Animation Direction Mixins
// ============================================================================

///
/// Direction - Alternate
/// -----------------------------------------------------------------------
/// Animation alternates direction on each iteration.
///
@mixin animate_alternate {
    animation-direction: alternate;
}

///
/// Direction - Reverse
/// -----------------------------------------------------------------------
/// Animation plays in reverse.
///
@mixin animate_reverse {
    animation-direction: reverse;
}

///
/// Direction - Alternate Reverse
/// -----------------------------------------------------------------------
/// Animation alternates, starting in reverse.
///
@mixin animate_alternate_reverse {
    animation-direction: alternate-reverse;
}


// ============================================================================
// Keyframe Generator Mixin
// ============================================================================

///
/// Dynamic Keyframe Generator
/// -----------------------------------------------------------------------
/// Generates keyframe animations from a map of percentages and properties.
///
/// @name keyframe_animation
/// @param {String} $name - The animation name
/// @param {Map} $keyframes - Map of keyframes (percentage: properties)
///
/// @example scss - Usage
///   @include keyframe_animation('slide-in', (
///     0%: (transform: translateX(-100%), opacity: 0),
///     100%: (transform: translateX(0), opacity: 1)
///   ));
///
@mixin keyframe_animation($name, $keyframes) {
    @keyframes #{$name} {
        @each $percentage, $properties in $keyframes {
            #{$percentage} {
                @each $property, $value in $properties {
                    #{$property}: #{$value};
                }
            }
        }
    }
}


// ============================================================================
// Performance Optimization
// ============================================================================

///
/// Hardware Acceleration
/// -----------------------------------------------------------------------
/// Enables hardware acceleration for smoother animations.
/// Use sparingly as it can increase memory usage.
///
@mixin animate_gpu {
    transform: translateZ(0);
    backface-visibility: hidden;
    perspective: 1000px;
}

///
/// Will Change Hint
/// -----------------------------------------------------------------------
/// Hints to the browser which properties will animate.
/// Remove after animation completes to free resources.
///
/// @param {String...} $properties - Properties that will change
///
@mixin animate_will_change($properties...) {
    will-change: $properties;
}


// ============================================================================
// Accessibility - Reduced Motion
// ============================================================================

///
/// Reduced Motion Media Query
/// -----------------------------------------------------------------------
/// Wraps content in a prefers-reduced-motion media query.
/// Use to provide alternative non-animated styles.
///
/// @content Styles to apply when reduced motion is preferred
///
@mixin prefers_reduced_motion {
    @media (prefers-reduced-motion: reduce) {
        @content;
    }
}

///
/// Respects Reduced Motion
/// -----------------------------------------------------------------------
/// Applies animation only when user hasn't requested reduced motion.
///
/// @content Animation styles
///
@mixin respects_motion {
    @media (prefers-reduced-motion: no-preference) {
        @content;
    }
}

///
/// Global Reduced Motion Reset
/// -----------------------------------------------------------------------
/// Disables all animations and transitions for users who prefer
/// reduced motion. Apply at root level for comprehensive accessibility.
///
@mixin reduced_motion_global {
    @media (prefers-reduced-motion: reduce) {
        *,
        *::before,
        *::after {
            animation-duration: 0.01ms !important;
            animation-iteration-count: 1 !important;
            transition-duration: 0.01ms !important;
            scroll-behavior: auto !important;
        }
    }
}


// ============================================================================
// Animation Composition
// ============================================================================

///
/// Staggered Animation Delay
/// -----------------------------------------------------------------------
/// Creates staggered animation delays for child elements.
///
/// @param {Number} $count - Number of children to stagger
/// @param {Time} $base_delay [0.1s] - Base delay increment
/// @param {Time} $initial_delay [0s] - Initial delay for first child
///
/// @example scss - Usage
///   .list {
///     @include animate_stagger(5, 0.1s);
///   }
///
@mixin animate_stagger($count, $base_delay: 0.1s, $initial_delay: 0s) {
    @for $i from 1 through $count {
        &:nth-child(#{$i}) {
            animation-delay: $initial_delay + ($base_delay * ($i - 1));
        }
    }
}

///
/// Multiple Animations
/// -----------------------------------------------------------------------
/// Applies multiple animations to a single element.
///
/// @param {List} $animations... - Animation shorthand values
///
/// @example scss - Usage
///   .element {
///     @include animate_multiple(
///       fadeIn 0.5s ease-out,
///       slideUp 0.5s ease-out 0.2s
///     );
///   }
///
@mixin animate_multiple($animations...) {
    animation: $animations;
}
