////
/// @group modules.atoms
////

@use '../utils' as *;

// ----------------------------------------------------------------------------
// flex-box
// ----------------------------------------------------------------------------

/// Generate atomic classes for flexbox. Full list of classes:
///
/// | Class | Equivalent Css |
/// | ----- | -------------- |
/// | .flex | display: flex; |
/// | .flex-inline | display: inline-flex; |
/// | .flex-row | flex-direction: row; |
/// | .flex-row-reverse | flex-direction: row-reverse; |
/// | .flex-column | flex-direction: column; |
/// | .flex-column-reverse | flex-direction: column-reverse; |
/// | .flex-wrap | flex-wrap: wrap; |
/// | .flex-wrap-column | flex-wrap: wrap; flex-direction: column; |
/// | .flex-wrap-reverse | flex-wrap: wrap-reverse; |
/// | .flex-nowrap | flex-wrap: nowrap; |
/// | .flex-auto | flex: 1 1 auto; |
/// | .flex-none | flex: none; |
/// | .flex-grow-[0...4] | flex-grow: [0...4] |
/// | .flex-shrink-[0...4] | flex-shrink: [0...4]; |
/// | .items-start | align-items: flex-start; |
/// | .items-end | align-items: flex-end; |
/// | .items-center | align-items: center; |
/// | .items-baseline | align-items: baseline; |
/// | .items-stretch | align-items: stretch; |
/// | .justify-start | justify-content: flex-start; |
/// | .justify-end | justify-content: flex-end; |
/// | .justify-center | justify-content: center; |
/// | .justify-between | justify-content: space-between; |
/// | .justify-around | justify-content: space-around; |
/// | .justify-stretch | justify-content: stretch; |
/// | .self-start | align-self: flex-start; |
/// | .self-end | align-self: flex-end; |
/// | .self-center | align-self: center; |
/// | .self-baseline | align-self: baseline; |
/// | .self-stretch | align-self: stretch; |
/// | .order-[0...9] | order: [0...9]; |
/// | .order-first | order: -99999; |
/// | .order-last | order: 99999; |
/// | .flex-center | display: flex; align-items: center; |
///
/// @param {*} $prefix [''] A prefix that can be applied to each of the classes
/// generated by the mixin.

@mixin atoms-flex($prefix: '') {
    // Display

    .#{$prefix}flex {
        display: flex;
    }

    .#{$prefix}flex-inline {
        display: inline-flex;
    }

    // Direction

    .#{$prefix}flex-row {
        flex-direction: row;
        &:not(.#{$prefix}inline-flex) {
            display: flex;
        }
    }
    .#{$prefix}flex-row-reverse {
        flex-direction: row-reverse;
        &:not(.#{$prefix}inline-flex) {
            display: flex;
        }
    }
    .#{$prefix}flex-column {
        flex-direction: column;
        &:not(.#{$prefix}inline-flex) {
            display: flex;
        }
    }
    .#{$prefix}flex-column-reverse {
        flex-direction: column-reverse;
        &:not(.#{$prefix}inline-flex) {
            display: flex;
        }
    }

    // Wrapping

    .#{$prefix}flex-wrap {
        flex-wrap: wrap;
        flex-direction: row;
    }
    .#{$prefix}flex-wrap-column {
        flex-wrap: wrap;
        flex-direction: column;
    }
    .#{$prefix}flex-wrap-reverse {
        flex-wrap: wrap-reverse;
    }
    .#{$prefix}flex-nowrap {
        flex-wrap: nowrap;
    }

    // Grow / Shrink

    .#{$prefix}flex-auto {
        flex: 1 1 auto;
    }

    .#{$prefix}flex-none {
        flex: none;
    }

    // Generate flex-basis classes (disabled because never used)
    // @for $b from 0 to 10 {
    //     .#{$prefix}flex-basisc-#{($b * 10)} {
    //         flex-basis: $b * 10%;
    //     }
    // }

    @for $f from 0 to 4 {
        .#{$prefix}flex-grow-#{$f} {
            flex-grow: $f;
        }
        .#{$prefix}flex-shrink-#{$f} {
            flex-shrink: $f;
        }
    }

    @for $g from 0 to 4 {
        @for $s from 0 to 4 {
            .#{$prefix}flex-#{$g}-#{$s} {
                flex-grow: $g;
                flex-shrink: $s;
            }
        }
    }

    // Align items

    .#{$prefix}items-start {
        align-items: flex-start;
    }

    .#{$prefix}items-end {
        align-items: flex-end;
    }

    .#{$prefix}items-center {
        align-items: center;
    }

    .#{$prefix}items-baseline {
        align-items: baseline;
    }

    .#{$prefix}items-stretch {
        align-items: stretch;
    }

    // Justify items

    .#{$prefix}justify-start {
        justify-content: flex-start;
    }

    .#{$prefix}justify-end {
        justify-content: flex-end;
    }

    .#{$prefix}justify-center {
        justify-content: center;
    }

    .#{$prefix}justify-between {
        justify-content: space-between;
    }

    .#{$prefix}justify-around {
        justify-content: space-around;
    }

    .#{$prefix}justify-stretch {
        justify-content: stretch;
    }

    // Align self

    .#{$prefix}self-start {
        align-self: flex-start;
    }

    .#{$prefix}self-end {
        align-self: flex-end;
    }

    .#{$prefix}self-center {
        align-self: center;
    }

    .#{$prefix}self-baseline {
        align-self: baseline;
    }

    .#{$prefix}self-stretch {
        align-self: stretch;
    }

    // Order

    .#{$prefix}order-0 {
        order: 0;
    }

    .#{$prefix}order-1 {
        order: 1;
    }

    .#{$prefix}order-2 {
        order: 2;
    }

    .#{$prefix}order-3 {
        order: 3;
    }

    .#{$prefix}order-4 {
        order: 4;
    }

    .#{$prefix}order-5 {
        order: 5;
    }

    .#{$prefix}order-6 {
        order: 6;
    }

    .#{$prefix}order-7 {
        order: 7;
    }

    .#{$prefix}order-8 {
        order: 8;
    }

    .#{$prefix}order-first {
        order: -99999;
    }

    .#{$prefix}order-last {
        order: 99999;
    }

    // Combos

    .#{$prefix}flex-center {
        display: flex;
        align-items: center;
    }
}

// ----------------------------------------------------------------------------
// spacers
// ----------------------------------------------------------------------------

// TODO: move to config?
// prettier-ignore
$-spacer-props: ( p: padding, m: margin);

// TODO: move to config?
// prettier-ignore
$-spacer-variants: (
    all: ( top, bottom, left, right ),
    v: ( top, bottom ),
    h: ( left, right ),
    t: ( top ),
    b: ( bottom ),
    l: ( left ),
    r: ( right ),
);

// TODO: move to config?
// prettier-ignore
$-spacer-vals: (0, 0.25, 0.5, 1, 2, 3, 4);

@mixin atoms-spacers(
    $space,
    $vals: $-spacer-vals,
    $props: $-spacer-props,
    $variants: $-spacer-variants,
    $coolnames: true,
    $prefix: ''
) {
    $vals: if-null($vals, get('atoms:spacers'));

    @each $base, $prop in $props {
        @each $variant, $variant-list in $variants {
            @each $val in $vals {
                @include -atoms-spacer($space, $base, $variant, $val, $coolnames, $prefix);
            }
        }
    }

    @each $val in $vals {
        // convert value to as string for classname
        $valstr: -spacer-class-str($val, $coolnames);

        // convert numerical values to the output value using sp() function
        $val: -spacer-val($val, $space);

        .items-mbr-#{$valstr} > * {
            &:not(:last-child) {
                margin-right: $val;
                margin-bottom: $val;
            }
        }

        .items-mr-#{$valstr} > * {
            &:not(:last-child) {
                margin-right: $val;
            }
        }

        .items-mb-#{$valstr} > * {
            &:not(:last-child) {
                margin-bottom: $val;
            }
        }

        .items-mh-#{$valstr} > * {
            margin-left: $val * 0.5;
            margin-right: $val * 0.5;
            &:last-child {
                margin-right: 0;
            }
            &:first-child {
                margin-left: 0;
            }
        }

        .items-mv-#{$valstr} > * {
            margin-top: $val * 0.5;
            margin-bottom: $val * 0.5;
            &:first-child {
                margin-top: 0;
            }
            &:last-child {
                margin-bottom: 0;
            }
        }

        .items-m-#{$valstr} > * {
            margin: $val * 0.5;
        }
    }

    // // create margin spacers for items
    // @each $val in $-spacer-vals() {

    //     // convert value to as string for classname
    //     $valstr: #{$val};
    //     $valstr: str-replace($valstr, '-', 'neg');
    //     $valstr: if($coolnames, str-replace($valstr, '.', '\\.'), str-replace($valstr, '.', '_'));

    //     // convert numerical values to the output value using sp() function
    //     $val: if(type-of($val) == 'number', $val * $space, $val);

    //     .items-mr-#{valstr} {
    //         &:not(:last-child) {
    //             margin-right: $val;
    //         }
    //     }
    // }
}

@function -spacer-class-str($val, $coolnames) {
    // convert value to as string for classname
    $valstr: #{$val};
    $valstr: str-replace($valstr, '-', 'neg');
    $valstr: if($coolnames, str-replace($valstr, '.', '\\.'), str-replace($valstr, '.', '_'));
    @return $valstr;
}

@function -spacer-val($val, $space) {
    @return if(type-of($val) == 'number', $val * $space, $val);
}

@mixin -atoms-spacer(
    $space,
    $base,
    $variant,
    $val,
    $coolnames,
    $prefix: '',
    $parent-sel: '',
    $child-sel: ''
) {
    // lookup the property name
    $prop-base: map-get($-spacer-props, $base);

    // lookup the variants
    $prop-variants: map-get($-spacer-variants, $variant);

    // change all to empty string now that the lookup is done
    $variant: if($variant == 'all', '', $variant);

    // convert value to as string for classname
    $valstr: -spacer-class-str($val, $coolnames);

    // convert numerical values to the output value using sp() function
    $val: -spacer-val($val, $space);

    // create the class
    #{$parent-sel} .#{$prefix}#{$base}#{$variant}-#{$valstr} #{$child-sel} {
        @each $variant in $prop-variants {
            #{$prop-base}-#{$variant}: $val;
        }
    }
}
