@use "sass:list";
@use "sass:meta";
@use "sass:string";
@use "../settings/animations";

$_allowed-transitions: (
    border-color,
    background-color,
    background-position,
    box-shadow,
    color,
    opacity,
    transform,
    visibility,
);

$_reduced-motion-disallowed-transitions: (transform);

@function _validate-transitions($properties) {
    @each $property in $properties {
        $is-allowed: list.index($_allowed-transitions, $property);

        @if not $is-allowed {
            @return false;
        }
    }

    @return true;
}

@function _reduce-motion-transitions($properties) {
    $reduced-properties: ();
    $separator: list.separator($properties);

    @each $property in $properties {
        @if not list.index($_reduced-motion-disallowed-transitions, $property) {
            $reduced-properties: list.append($reduced-properties, $property, $separator: $separator);
        }
    }

    @return $reduced-properties;
}

@mixin add($properties, $duration: 150ms) {
    $property-list: ();

    @if meta.type-of($properties) != "string" and meta.type-of($properties) != "list" {
        @error "Transition properties must be a string or a Sass list, `#{$properties}` given.";
    }

    $property-list: list.join($property-list, $properties);

    @if not _validate-transitions($property-list) {
        @error "Only [#{$_allowed-transitions}] transitions are allowed, [#{$properties}] given.";
    } @else {
        $reduced-property-list: _reduce-motion-transitions($property-list);

        transition-property: $property-list;
        transition-duration: $duration;
        transition-timing-function: animations.$standard-timing-function;

        @if list.length($reduced-property-list) > 0 {
            @media (prefers-reduced-motion: reduce) {
                transition-property: $reduced-property-list;
            }
        }
    }
}
