@use "../config/feature-flags" as config-flags;
@use "../config/breakpoints" as config-breakpoint;
@use "../config/spacing" as config-spacing;
@use "../functions/feature-flags" as fn-flags;
@use "../functions/units" as fn-units;

// @component Position
// @description Controls element positioning and placement within the document flow
// @example
// <!-- Basic positioning -->
// <div class="relative">
//   <div class="absolute top-0 right-0">
//     Positioned in top-right corner
//   </div>
// </div>
// <!-- Sticky header -->
// <header class="sticky top-0">
//   This header sticks to the top when scrolling
// </header>
// <!-- Responsive positioning -->
// <div class="relative@md">
//   <div class="absolute@md top-2 left-2">
//     Only positioned on medium screens and up
//   </div>
// </div>
//  @classes
// Position Types:
//  - static: Default position, follows document flow
//  - relative: Positioned relative to normal position
//  - absolute: Positioned relative to nearest positioned ancestor
//  - fixed: Positioned relative to viewport
//  - sticky: Positioned based on scroll position
// Placement:
//  - top-{value}: Sets top position
//  - right-{value}: Sets right position
//  - bottom-{value}: Sets bottom position
//  - left-{value}: Sets left position
// Common values: 0, 1, 2, 3, 4, 5, 10, etc. (based on spacing scale)
//  @responsive
// All position classes support responsive variants using @breakpoint suffix:
//  - relative@md: Relative positioning on medium screens and up
//  - top-0@lg: Zero top position on large screens
//  @see z-index, transform

// -----------------------------------------------
// MIXINS
// -----------------------------------------------

// @mixin static
// @description Sets position to static (default document flow)
// @example
// .element {
//   @include static;
// }
@mixin static {
    position: static;
}

// @mixin relative
// @description Sets position to relative, creating a positioning context
// @example
// .container {
//   @include relative;
// }
@mixin relative {
    position: relative;
}

// @mixin absolute
// @description Sets position to absolute, removing from normal document flow
// @example
// .popup {
//   @include absolute;
//   top: 0;
//   left: 0;
// }
@mixin absolute {
    position: absolute;
}

// @mixin fixed
// @description Sets position to fixed, removing from normal document flow and fixing relative to viewport
// @example
// .popup {
//   @include fixed;
//   top: 0;
//   left: 0;
// }
@mixin fixed {
    position: fixed;
}

// @mixin sticky
// @description Creates a sticky element that remains in view during scrolling
// @example
// .nav {
//   @include sticky;
// }
@mixin sticky {
    position: sticky;
    z-index: 999;
    top: 0;
}

// @mixin top
// @description Sets the top position of an element
// @param {Number|Length} $value - Position value (in px, rem, etc.)
// @example
// .toast {
//   @include absolute;
//   @include top(1rem);
// }
@mixin top($value) {
    top: fn-units.fix-units($value);
}

// @mixin right
// @description Sets the right position of an element
// @param {Number|Length} $value - Position value (in px, rem, etc.)
// @example
// .badge {
//   @include absolute;
//   @include right(0);
// }
@mixin right($value) {
    right: fn-units.fix-units($value);
}

// @mixin bottom
// @description Sets the bottom position of an element
// @param {Number|Length} $value - Position value (in px, rem, etc.)
// @example
// .footer {
//  @include fixed;
//  @include bottom(0);
// }
@mixin bottom($value) {
    bottom: fn-units.fix-units($value);
}

// @mixin left
// @description Sets the left position of an element
// @param {Number|Length} $value - Position value (in px, rem, etc.)
// @example
// .sidebar {
//  @include fixed;
//  @include left(0);
// }
@mixin left($value) {
    left: fn-units.fix-units($value);
}

// @mixin absolute-center
// @description Centers an element absolutely within its positioned parent
// @example
// .modal {
//   @include absolute-center;
// }
@mixin absolute-center {
    position: absolute;
    left: 50%;
    top: 50%;

    --translate-x: -50%;
    --translate-y: -50%;

    transform: translateX(var(--translate-x)) translateY(var(--translate-y)) translateZ(var(--translate-z, 0)) rotate(var(--rotate, 0)) skewX(var(--skew-x, 0)) skewY(var(--skew-y, 0)) scaleX(var(--scale-x, 1)) scaleY(var(--scale-y, 1));
}

// @variable $position-fractions
// @description Common percentage values for positioning elements
// @note These values are used to generate position utility classes like .top-25p, .left-50p, etc.
// @example
// .sidebar {
//   @include absolute;
//   @include top(map.get($position-fractions, "25p")); // top: 25%
// }
$position-fractions: (
    "25p": 25%,
    "33p": 33.333%,
    "50p": 50%,
    "66p": 66.667%,
    "75p": 75%,
    "100p": 100%,
);

// -----------------------------------------------
// UTILITY CLASSES
// -----------------------------------------------
@if fn-flags.feature-enabled("position") {
    // Position Classes
    #{config-flags.$parent-selector} .static {
        @include static;
    }

    #{config-flags.$parent-selector} .relative {
        @include relative;
    }

    #{config-flags.$parent-selector} .absolute {
        @include absolute;
    }

    #{config-flags.$parent-selector} .fixed {
        @include fixed;
    }

    #{config-flags.$parent-selector} .sticky {
        @include sticky;
    }

    #{config-flags.$parent-selector} .absolute-center {
        @include absolute-center;
    }

    @each $key, $value in $position-fractions {
        #{config-flags.$parent-selector} .top-#{$key} {
            @include top($value);
        }
        #{config-flags.$parent-selector} .right-#{$key} {
            @include right($value);
        }
        #{config-flags.$parent-selector} .bottom-#{$key} {
            @include bottom($value);
        }
        #{config-flags.$parent-selector} .left-#{$key} {
            @include left($value);
        }
    }

    // Placement Classes
    @each $key, $value in config-spacing.$spacings {
        #{config-flags.$parent-selector} .top-#{$key} {
            @include top($value);
        }
        #{config-flags.$parent-selector} .right-#{$key} {
            @include right($value);
        }
        #{config-flags.$parent-selector} .bottom-#{$key} {
            @include bottom($value);
        }
        #{config-flags.$parent-selector} .left-#{$key} {
            @include left($value);
        }
    }

    // -----------------------------------------------
    // RESPONSIVE CLASSES
    // -----------------------------------------------

    // Responsive Position Classes
    @each $breakpoint, $width in config-breakpoint.$breakpoints {
        @media (min-width: #{$width}) {
            #{config-flags.$parent-selector} .static\@#{$breakpoint} {
                @include static;
            }
            #{config-flags.$parent-selector} .relative\@#{$breakpoint} {
                @include relative;
            }
            #{config-flags.$parent-selector} .absolute\@#{$breakpoint} {
                @include absolute;
            }
            #{config-flags.$parent-selector} .fixed\@#{$breakpoint} {
                @include fixed;
            }
            #{config-flags.$parent-selector} .sticky\@#{$breakpoint} {
                @include sticky;
            }
            #{config-flags.$parent-selector} .absolute-center\@#{$breakpoint} {
                @include absolute-center;
            }

            // Fractional responsive placements
            @each $key, $value in $position-fractions {
                #{config-flags.$parent-selector} .top-#{$key}\@#{$breakpoint} {
                    @include top($value);
                }
                #{config-flags.$parent-selector} .right-#{$key}\@#{$breakpoint} {
                    @include right($value);
                }
                #{config-flags.$parent-selector} .bottom-#{$key}\@#{$breakpoint} {
                    @include bottom($value);
                }
                #{config-flags.$parent-selector} .left-#{$key}\@#{$breakpoint} {
                    @include left($value);
                }
            }

            @each $key, $value in config-spacing.$spacings {
                #{config-flags.$parent-selector} .top-#{$key}\@#{$breakpoint} {
                    @include top($value);
                }
                #{config-flags.$parent-selector} .right-#{$key}\@#{$breakpoint} {
                    @include right($value);
                }
                #{config-flags.$parent-selector} .bottom-#{$key}\@#{$breakpoint} {
                    @include bottom($value);
                }
                #{config-flags.$parent-selector} .left-#{$key}\@#{$breakpoint} {
                    @include left($value);
                }
            }
        }
    }
}
