@use 'sass:list';
@use 'sass:map';

$-breakpoints: (
    xs: 0,
    sm: 640px,
    md: 768px,
    lg: 1024px,
    xl: 1280px
);

@function -next($breakpoint) {
    $names: map.keys($-breakpoints);
    $n: list.index($names, $breakpoint);

    @if not $n {
        @error 'Breakpoint "#{$breakpoint}" not found in "#{$names}".';
    }

    @if $n < list.length($names) {
        @return list.nth($names, $n + 1);
    }

    @return null;
}

@function -maxWidth($breakpoint) {
    $next: -next($breakpoint);

    @if $next {
        @return -minWidth($next) - .02;
    }

    @return null;
}

@function -minWidth($breakpoint) {
    $min: map.get($-breakpoints, $breakpoint);

    @if $min != 0 {
        @return $min;
    }

    @return null;
}

@mixin breakpoint-between($lower, $upper) {
    $max: -maxWidth($upper);
    $min: -minWidth($lower);

    @if $max != null and $min != null {
        @media (max-width: #{$max}) and (min-width: #{$min}) {
            @content;
        }
    } @else if $max == null {
        @include breakpoint-up($lower);
    } @else if $min == null {
        @include breakpoint-down($upper);
    }
}

@mixin breakpoint-down($breakpoint) {
    $max: -maxWidth($breakpoint);

    @if $max {
        @media (max-width: #{$max}) {
            @content;
        }
    } @else {
        @content;
    }
}

@mixin breakpoint-only($breakpoint) {
    @include breakpoint-between($breakpoint, $breakpoint);
}

@mixin breakpoint-up($breakpoint) {
    $min: -minWidth($breakpoint);

    @if $min {
        @media (min-width: #{$min}) {
            @content;
        }
    } @else {
        @content;
    }
}

@mixin container-breakpoint-down($container, $breakpoint) {
    $max: -maxWidth($breakpoint);

    @if $max {
        @container #{$container} (max-width: #{$max}) {
            @content;
        }
    } @else {
        @content;
    }
}

@mixin container-breakpoint-up($container, $breakpoint) {
    $min: -minWidth($breakpoint);

    @if $min {
        @container #{$container} (min-width: #{$min}) {
            @content;
        }
    } @else {
        @content;
    }
}

@mixin breakpoint-max-widths {
    @each $-breakpoint, $-max-width in $-breakpoints {
        @if $-breakpoint != xs {
            @include breakpoint-up($-breakpoint) {
                & {
                    max-width: #{$-max-width};
                }
            }
        }
    }
}
