@use 'sass:math';

// Set count line-clamp for text element
@mixin line-clamp($rows: 2) {
    display: -webkit-box;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: $rows;
}

// Set width and height for element
@mixin size($width, $height: $width) {
    width: $width;
    height: $height;
}

// Set max-width and max-height for element
@mixin max-size($width, $height: $width) {
    max-width: $width;
    max-height: $height;
}

// Set min-width and min-height for element
@mixin min-size($width, $height: $width) {
    min-width: $width;
    min-height: $height;
}

// Mixin for truncating text
// @param {Integer} - $width - row max-width
@mixin truncate($width, $line-clamp: 1) {
    max-width: $width;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    -webkit-line-clamp: $line-clamp;
    line-clamp: $line-clamp;
}

// Fix object fit for IE 11 and EDGE
@mixin object-fit-video-ie() {
    // IE
    @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
        @include size(100vw, auto);
    }

    // EDGE
    @supports (object-fit: cover) and (-ms-ime-align: auto) {
        @include size(100%, auto);
    }
}

// Add styles if IE 10 and above
@mixin if-ie() {
    @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
        @content;
    }
}

// Add styles if EDGE
@mixin if-edge() {
    @supports (-ms-ime-align: auto) {
        @content;
    }
}

// FontFace mixin for inserting custom fonts
@mixin font-face($name, $file, $weight: normal, $style: normal, $display: swap) {
    @font-face {
        font-weight: $weight;
        font-family: $name;
        font-style: $style;
        font-display: $display;
        src: url(get-font('#{unquote($file)}.woff2')) format('woff2');
    }
}

// Add hover and focus styles
@mixin event {
    @include breakpoint(lg) {
        &:focus,
        &:hover {
            @content;
        }
    }
}

// Insert custom breakpoint with custom max viewport value.
@mixin media-max($breakpoint, $orientation: false) {
    @if $orientation {
        @media screen and (max-width: #{$breakpoint}px) and (orientation: $orientation) {
            @content;
        }
    } @else {
        @media screen and (max-width: #{$breakpoint}px) {
            @content;
        }
    }
}

// Insert custom breakpoint with custom min viewport value.
@mixin media-min($breakpoint, $orientation: false) {
    @if $orientation {
        @media screen and (min-width: #{$breakpoint}px) and (orientation: $orientation) {
            @content;
        }
    } @else {
        @media screen and (min-width: #{$breakpoint}px) {
            @content;
        }
    }
}

// Use this for creating scalable elements (usually images / background images) that maintain a ratio.
@mixin responsive-ratio($x, $y, $pseudo: false) {
    $padding: unquote(math.div($y, $x) * 100 + '%');

    @if $pseudo {
        &::before {
            display: block;
            width: 100%;
            padding-top: $padding;
            content: '';
        }
    } @else {
        padding-top: $padding;
    }
}

// Mixin for inserting custom breakpoints.
// @param {string} $breakpoint - breakpoint name in breakpoints map.
@mixin breakpoint($breakpoint) {
    @if type-of($breakpoint) == number {
        @media screen and (min-width: #{$breakpoint}px) {
            @content;
        }
    } @else {
        @each $size in map-keys($rocket-breakpoints) {
            @if $size == $breakpoint {
                @media screen and (min-width: #{map-get($rocket-breakpoints, $size)}px) {
                    @content;
                }
            }
        }
    }
}

// Mixin for transition style
@mixin transition(
    $prop: all,
    $duration: $rocket-transition-duration,
    $timing-function: $rocket-transition-timing-function,
    $delay: $rocket-transition-delay
) {
    transition: $prop $duration $timing-function $delay;
}

@mixin list-reset {
    margin: 0;
    padding: 0;
    list-style: none;
}

@mixin clearfix {
    &::after {
        display: table;
        clear: both;
        content: '';
    }
}

@mixin a11y-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    white-space: nowrap;
    border: 0;
    clip: rect(0 0 0 0);
    clip-path: inset(100%);
}

@mixin cover($pseudo: true) {
    @include size(100%);

    position: absolute;
    top: 0;
    left: 0;
    content: if($pseudo == true, '', null);
}

@mixin layout-stack {
    > *:first-child {
        margin-top: 0;
    }

    > *:last-child {
        margin-bottom: 0;
    }
}

@mixin theme-backdrop($use-blur: true) {
    @include size(100%);

    position: absolute;
    top: 0;
    left: 0;
    background-color: var(--rocket-color-black-a-100);
    backdrop-filter: if($use-blur == true, blur(0.625rem), null);
}

@mixin theme-focus-ring($event: true) {
    @if $event == true {
        &:focus {
            box-shadow: var(--rocket-controls-focus-ring-shadow);
        }
    } @else {
        box-shadow: var(--rocket-controls-focus-ring-shadow);
    }
}

@mixin multiline-underline($size: 1px, $color: currentColor) {
    background-image: linear-gradient(transparent calc(100% - #{$size}), $color $size);
    background-repeat: no-repeat;
    background-size: 0 100%;
}

@mixin multiline-underline-event($size: 1px, $color: currentColor) {
    @include transition;
    @include multiline-underline($size, $color);

    @include event {
        background-size: 100% 100%;
    }
}

@mixin object-fit($fit: cover, $position: center) {
    object-fit: $fit;
    object-position: $position;
}

// Configure material symbols axes
@mixin symbol-variant(
    $fill: 0,
    $weight: 400,
    $grade: 0,
    $optical-size: 24) {
    font-variation-settings: 'FILL' $fill, 'wght' $weight, 'GRAD' $grade, 'opsz' $optical-size;
}

@mixin overlay() {
    &::after {
        @include cover(true);

        z-index: -1;
        display: block;
        background: var(--rocket-color-black-a-200);
        opacity: 0;
        transition: opacity 250ms ease-out, z-index 100ms ease-out 300ms;
    }
}

// Set absolute position with settings
@mixin absolute($params...) {
    position: absolute;

    @if length($params) > 0 {
        $params: if(length($params) == 1, nth($params, 1), $params);
        $props: (top, right, bottom, left);

        @for $index from 1 through length($params) {
            #{nth($props, $index)}: nth($params, $index);
        }
    }
}

// Set fixed position with settings
@mixin fixed($params...) {
    position: fixed;

    @if length($params) > 0 {
        $params: if(length($params) == 1, nth($params, 1), $params);
        $props: (top, right, bottom, left);

        @for $index from 1 through length($params) {
            #{nth($props, $index)}: nth($params, $index);
        }
    }
}

// Set relative position with settings
@mixin relative($params...) {
    position: relative;

    @if length($params) > 0 {
        $params: if(length($params) == 1, nth($params, 1), $params);
        $props: (top, right, bottom, left);

        @for $index from 1 through length($params) {
            #{nth($props, $index)}: nth($params, $index);
        }
    }
}

// Reset position to static
@mixin reset-position {
    bottom: auto;
    left: auto;
    position: static;
    right: auto;
    top: auto;
}

@mixin skew-block($directions: 'top', $skew-size: 83px) {
    @if $directions == 'top-bottom' {
        // Bevels both top and bottom
        clip-path: polygon(
            0 0,
            100% #{$skew-size},
            100% 100%,
            0 calc(100% - #{$skew-size})
        );
    } @else if $directions == 'top' {
        // Just a bevel on top
        clip-path: polygon(
            0 0,
            100% #{$skew-size},
            100% 100%,
            0 100%
        );
    } @else if $directions == 'bottom' {
        // Just a bevel at the bottom
        clip-path: polygon(
            0 0,
            100% 0,
            100% 100%,
            0 calc(100% - #{$skew-size})
        );
    } @else {
        @warn "Invalid direction provided: #{$directions}. Please use ('top'), ('bottom'), or ('top', 'bottom').";
    }
}
