@use "sass:math";

// The suggestions list (dropdown) is appended to the document's body so the CSS variables should be defined at root-level
:root {

    --tagify-dd-color-primary: rgb(53,149,246); // should be same as "$tags-focus-border-color"
    --tagify-dd-text-color: black;
    --tagify-dd-bg-color: white;
    --tagify-dd-item-pad: .3em .5em; // should be same as $tag-pad (below)
    --tagify-dd-max-height: 300px;
}

.tagify{
    // SCSS "default" allows overriding variables BEFORE they are set in the below lines of code
    $self: &;
    $tags-border-color       : #DDD !default;
    $tags-hover-border-color : #CCC !default;
    $tags-focus-border-color : #3595f6 !default;
    $tagMargin               : 5px !default;
    $tag-pad                 : .3em .5em !default;
    $tag-min-width           : 1ch !default;
    $tag-max-width           : 100% !default;
    $tag-text-color          : black !default;
    $tag-text-color--edit    : black !default;
    $tag-bg                  : #E5E5E5 !default;
    $tag-hover               : #D3E2E2 !default;
    $tag-remove              : #D39494 !default;
    $tag-remove-btn-color    : $tag-text-color !default;
    $tag-remove-btn-bg       : none !default;
    $tag-remove-btn-bg--hover: darken($tag-remove, 8) !default;
    $tag-invalid-color       : $tag-remove !default;
    $tag-invalid-bg          : rgba($tag-remove, .5) !default;
    $tag-inset-shadow-size   : 1.2em !default;
    $tag-hide-transition     : .3s !default;
    $placeholder-color       : rgba($tag-text-color, .4) !default;
    $placeholder-color-focus : rgba($tag-text-color, .25) !default;
    $input-color             : inherit !default;
    $tagify-dd-bg-color      : white !default;
    $tagify-dd-color-primary : rgb(53,149,246) !default;

    // CSS variables
    --tags-disabled-bg         : #F1F1F1;
    --tags-border-color        : #{$tags-border-color};
    --tags-hover-border-color  : #{$tags-hover-border-color};
    --tags-focus-border-color  : #{$tags-focus-border-color};

    --tag-border-radius        : 3px;
    --tag-bg                   : #{$tag-bg};
    --tag-hover                : #{$tag-hover};
    --tag-text-color           : #{$tag-text-color};
    --tag-text-color--edit     : #{$tag-text-color--edit};
    --tag-pad                  : #{$tag-pad};
    --tag-inset-shadow-size    : #{$tag-inset-shadow-size};
    --tag-invalid-color        : #{$tag-invalid-color};
    --tag-invalid-bg           : #{$tag-invalid-bg};
    --tag--min-width           : #{$tag-min-width};
    --tag--max-width           : #{$tag-max-width};
    --tag-hide-transition      : #{$tag-hide-transition};

    --tag-remove-bg            : #{rgba($tag-remove, .3)};
    --tag-remove-btn-color     : #{$tag-remove-btn-color};
    --tag-remove-btn-bg        : #{$tag-remove-btn-bg};
    --tag-remove-btn-bg--hover : #{$tag-remove-btn-bg--hover};

    --input-color              : #{$input-color};
    --placeholder-color        : #{$placeholder-color};
    --placeholder-color-focus  : #{$placeholder-color-focus};
    --loader-size              : .8em;
    --readonly-striped         : 1;

    @mixin firefox {
        @at-root {
            @-moz-document url-prefix() {
                & { @content; }
            }
        }
    }

    @mixin placeholder( $show:true ){
        transition: .2s ease-out;

        @if $show == true {
            opacity: 1;
            transform: none;
        }
        @else {
            opacity: 0;
            transform: translateX(6px);
        }
    }

    @mixin loader(){
        content: '';
        vertical-align: middle;
        opacity: 1;
        width: .7em;
        height: .7em;
        width: var(--loader-size);
        height: var(--loader-size);
        min-width: 0;
        border: 3px solid;
        border-color: #EEE #BBB #888 transparent;
        border-radius: 50%;
        animation: rotateLoader .4s infinite linear;
    }

    @mixin tagReadonlyBG($size:5px){
        animation: readonlyStyles 1s calc(-1s * (var(--readonly-striped) - 1)) paused;

        @keyframes readonlyStyles {
            0% {
                background: linear-gradient(45deg, var(--tag-bg)  25%,
                                           transparent    25%,
                                           transparent    50%,
                                           var(--tag-bg)  50%,
                                           var(--tag-bg)  75%,
                                           transparent    75%,
                                           transparent)   0/#{$size} #{$size};
                box-shadow: none;
                filter: brightness(.95);
            }
        }
    }

    @keyframes tags--bump{
        30% { transform: scale(1.2); }
    }

    @keyframes rotateLoader {
        to{ transform: rotate(1turn) }
    }

    display       : inline-flex;
    align-items   : flex-start;
    align-content : baseline;
    flex-wrap     : wrap;
    border        : 1px solid var(--tags-border-color);
    padding       : 0;
    line-height   : 0;
    outline       : none;
    position      : relative;
    box-sizing    : border-box;
    transition    : .1s;

    &:has([contenteditable='true']) {
        cursor: text;
    }

    &:hover:not(.tagify--focus):not(.tagify--invalid){
        --tags-border-color : var(--tags-hover-border-color);
    }

    &[disabled]{
        background: var(--tags-disabled-bg);
        filter: saturate(0);
        opacity: .5;
        pointer-events: none;

        &#{$self}--empty{
            > #{$self}__input{
                &::before{
                    position: relative;
                }
            }
        }
    }

    // Global "read-only" mode (no input button)
    &[readonly], &[disabled]{
        &#{$self}--select{
            pointer-events: none;
        }

        &:not(#{$self}--mix):not(#{$self}--select):not(#{$self}--empty){
            cursor: default;
            > #{$self}__input{
                visibility: hidden;
                width: 0;
                margin: $tagMargin 0;
            }

            #{$self}__tag > div{
                padding: var(--tag-pad);
                &::before{
                    @include tagReadonlyBG;
                }
            }
        }

        #{ $self }__tag__removeBtn{ display:none; }
    }

    &--loading{
        #{ $self }__input{
            > br:last-child{ display:none; }
            &::before{ content:none; }
            &::after{
                @include loader;
                content: '' !important;
                margin: -2px 0 -2px .5em;
            }
            &:empty{
                &::after{
                    margin-left:0;
                }
            }
        }
    }

    ///////////////////////////////////////////
    // Hides originals
    + input,
    + textarea{
        position: absolute !important;
        left: -9999em !important;
        transform: scale(0) !important;
    }

    &__tag{
        display      : inline-flex;
        align-items  : center;
        max-width    : var(--tag--max-width);
        margin-inline: $tagMargin 0;
        margin-block : $tagMargin;
        position     : relative;
        z-index      : 1;
        outline      : none;
        line-height  : normal;
        cursor       : default;
        transition   : .13s ease-out;

        // needed when "allowCaretBetweenTags" an the input has been moved (by the user) so it's not the last element
        &:last-child {
            margin-right: $tagMargin;
        }

        > div{  // :not([contenteditable])
            display        : flex;
            flex           : 1;
            vertical-align : top;
            box-sizing     : border-box;
            max-width      : 100%;
            padding        : var(--tag-pad);
            color          : var(--tag-text-color);
            line-height    : inherit;
            border-radius  : var(--tag-border-radius);
         // user-select    : none;  // should allow selecting text if the user wishes to copy something
            white-space    : nowrap;
            transition     : .13s ease-out;

            > *{
                white-space    : pre-wrap;
                overflow       : hidden;
                text-overflow  : ellipsis;
                display        : inline-block;
                vertical-align : top;
                min-width      : var(--tag--min-width);
                max-width      : var(--tag--max-width);
                transition     : .8s ease, .1s color;


                &[contenteditable]{
                    display: block; // solves similar issue to this: https://stackoverflow.com/q/34354085/104380 (but with <span> because of its default `inline-block` display)
                    outline: none;
                    user-select: text;
                    cursor: text;
                    // fix: sometimes the caret after the last character wasn't visible (when setting {backspace:"edit"})
                    margin: -2px;
                    padding: 2px;
                    max-width: 350px;
                }

                &:only-child{
                    width: 100%;
                }
            }

            &::before{
                content: '';
                position: absolute;
                border-radius: inherit;
                inset: var(--tag-bg-inset, 0);
                z-index: -1;
                pointer-events:none;
                transition: 120ms ease;
                animation : tags--bump .3s ease-out 1;
                box-shadow: 0 0 0 var(--tag-inset-shadow-size) var(--tag-bg) inset;
            }
        }

        &:hover:not([readonly]),
        &:focus{
            div{  // :not([contenteditable])
                &::before{
                    --tag-bg-inset: #{math.div(-$tagMargin, 2)};
                    --tag-bg: var(--tag-hover);
                }
            }
        }

        &--loading{
            pointer-events: none;

            .tagify__tag__removeBtn{
                display: none;
            }

            &::after{
                --loader-size:  .4em;
                @include loader;
                margin: 0 .5em 0 -.1em;
            }
        }

        &--flash{
            div::before{ animation:none; }
        }

        &--hide{
            width          : 0 !important;
            padding-left   : 0;
            padding-right  : 0;
            margin-left    : 0;
            margin-right   : 0;
            opacity        : 0;
            transform      : scale(0);
            transition     : var(--tag-hide-transition);
            pointer-events : none;

            > div > *{
                white-space: nowrap;
            }
        }

        &#{ $self }{
            &--noAnim{
              > div::before{
                animation:none;
              }
            }

            &--notAllowed:not(.tagify__tag--editable){
                div{
                    > span{ opacity:.5; } // filter:blur(.2px);
                    &::before{
                        --tag-bg: var(--tag-invalid-bg);
                        transition: .2s;
                    }
                }
            }
        }

        &[readonly]{
            #{ $self }__tag__removeBtn{ display:none; }
            > div{// padding: $tag-pad;
                &::before{
                    @include tagReadonlyBG;
                }
            }
        }

        &--editable{
            > div{
                color : var(--tag-text-color--edit);

                &::before{
                    box-shadow: 0 0 0 2px var(--tag-hover) inset !important;
                }
            }

            > #{$self}__tag__removeBtn{
                pointer-events: none;
                opacity: 0;
                transform: translateX(100%) translateX(5px);
            }

            &.tagify--invalid{
                > div{
                    &::before{
                        box-shadow: 0 0 0 2px var(--tag-invalid-color) inset !important;
                    }
                }
            }
        }

        &__removeBtn{
            $size: 14px;

            order          : 5;
            display        : inline-flex;
            align-items    : center;
            justify-content: center;
            border-radius  : 50px;
            cursor         : pointer;
            font           : #{$size}/1 Arial;
            background     : var(--tag-remove-btn-bg);
            color          : var(--tag-remove-btn-color);

            width          : $size;
            height         : $size;
            margin-inline  : auto math.div($size,3);

            overflow       : hidden;
            transition     : .2s ease-out;

            &::after{
                content: "\00D7";
                transition: .3s, color 0s;
            }

            &:hover{
                color: white;
                background: var(--tag-remove-btn-bg--hover);
                // + span{ box-shadow: 0 0 0 2px $tag-remove inset; transition:.2s; }
                + div{
                    > span{ opacity:.5; } // filter:blur(.2px);
                    &::before{
                        box-shadow: 0 0 0 var(--tag-inset-shadow-size) var(--tag-remove-bg, rgba($tag-remove, .3)) inset !important;
                        transition: box-shadow .2s;
                    }
                }
            }
        }
    }


    &:not(#{$self}--mix){
        #{ $self }__input{
            // https://stackoverflow.com/a/13470210/104380
            br { display:none; }
            * { display:inline; white-space:nowrap; }
        }
    }

    ///////////////////////////////////////////
    // Holds the placeholder & the tags input
    &__input{
        $placeholder-width : 110px;

        display: inline-block;
        margin: $tagMargin;
        padding: var(--tag-pad);
        line-height: normal;
        min-width: fit-content;
        min-height: 1.5lh;
        position: relative;
        white-space: pre-wrap; // #160 Line break (\n) as delimeter
        color: var(--input-color);
        box-sizing: inherit;
        overflow: hidden;

        &:focus{
            outline:none;
        }

        &:last-child {
            flex-grow: 1;
            min-width: $placeholder-width;

            &:focus{
                &::before{
                    @include placeholder(false);

                    /* ALL MS BROWSERS: hide placeholder (on focus) otherwise the caret is placed after it, which is weird */
                    /* IE Edge 12+ CSS styles go here */
                    @supports ( -ms-ime-align:auto ) {
                        display: none;
                    }
                }

                &:empty{
                    &::before{
                        @include placeholder(true);

                        // Seems to be fixed! no need for the below hack
                        // @include firefox {
                        //     // remove ":after" pseudo element: https://bugzilla.mozilla.org/show_bug.cgi?id=904846#c45
                        //     content: unset;
                        //     // display:inline-block;
                        // }

                        color: $placeholder-color-focus;
                        color: var(--placeholder-color-focus);
                    }

                     &::after{
                        @include firefox {
                            display: none;
                        }
                    }
                }
            }

            &::before{
                content: attr(data-placeholder);
            }
        }

        &:empty{
            @include firefox {
              // clicking twice on the input (not fast) disallows typing (bug) only when the input has "display:flex".
              // disabled the below rule for the above reason:
              //  display: flex; // https://bugzilla.mozilla.org/show_bug.cgi?id=904846#c45
            }
        }

        &::before{
            width: 100%;
            height: 100%;
            margin: auto 0;
            z-index: 1;
            color: var(--placeholder-color);
            white-space: nowrap;
            text-overflow: ellipsis;
            overflow: hidden;
            pointer-events: none;
            opacity: 0;
            position: absolute;

        }
        /* Seems firefox newer versions don't need this any more
        @supports ( -moz-appearance:none ){
            &::before{
                line-height: inherit;
                position:relative;
            }
        }
        */
        // tries to suggest the rest of the value from the first item in the whitelist which matches it
        &::after{
            content: attr(data-suggest);
            display: inline-block;
            vertical-align: middle;

            position: absolute;
            min-width: calc(100% - 1.5em);
            text-overflow: ellipsis;
            overflow: hidden;

            white-space: pre; /* allows spaces at the beginning */
            color: var(--tag-text-color);
            opacity: .3;
            pointer-events:none;
            max-width: 100px;
        }

        // &--invalid{
        //     // color: $invalid-input-color;
        // }

        // in "mix mode" the tags might be next to plain text, so spread things a bit
        #{ $self }__tag{
            margin: 0 1px;
        }
    }

    &--mix {
        display: block; // display:flex makes Chrome generates <div><br></div> when pressing ENTER key

        #{ $self }__input{
            padding: $tagMargin;
            margin: 0;
            width: 100%;
            height: 100%;
            line-height: 1.5;
            display: block; // needed to resolve this bug: https://bugs.chromium.org/p/chromium/issues/detail?id=1182621

            &::before{
                height:auto;
                display: none;
                line-height: inherit;
            }

            // no suggested-complete are shown in mix-mode while higilighting dropdown options
            &::after{ content:none; }
        }
    }

    &--select{
        cursor: default;

        &::after{
            $size: 16px;

            content: '>';
            opacity: .5;
            position: absolute;
            top: 50%;
            right: 0;
            bottom: 0;
            font: $size monospace;
            line-height: math.div($size,2);
            height: math.div($size,2);
            pointer-events: none;
            transform: translate(-150%, -50%) scaleX(1.2) rotate(90deg);
            transition: .2s ease-in-out;
        }

        &[aria-expanded=true]{
            &::after{
                transform: translate(-150%, -50%) rotate(270deg) scaleY(1.2);
            }

            #{$self}__tag__removeBtn{
                pointer-events: none;
                opacity: 0;
                transform: translateX(100%) translateX(5px);
            }
        }

        #{$self}__tag{
            flex: 1;
            max-width: none;
            margin-inline-end: 2em;
            margin-block: 0;
            padding-block: $tagMargin;
            cursor: text;

            div{
                &::before {
                    display: none;
                }
            }

            + #{$self}__input{
                display: none;
            }
        }
    }

    &--empty{
        #{ $self }__input{
            &::before{
                @include placeholder;
                // position: static;
                display: inline-block;
                width: auto;

                #{ $self }--mix &{
                    display: inline-block;
                }
            }
        }
    }

    &--focus{
        --tags-border-color: var(--tags-focus-border-color);
        transition: 0s;
    }

    &--invalid{
        --tags-border-color : #{$tag-invalid-color};
    }

    // Since the dropdown is an external element, which is positioned directly on the body element
    // it cannot inherit the CSS variables applied on the ".Tagify" element
    &__dropdown{
        $dropdown: &;
        $trans: .3s;
        $trans-curve: cubic-bezier(.5, 0, .3, 1);

        position: absolute;
        z-index: 9999;
        transform: translateY(-1px);
        border-top: 1px solid var(--tagify-dd-color-primary);
        overflow: hidden;

        &[dir='rtl'] {
            transform: translate(-100%, -1px);
        }

        &[placement="top"]{
            margin-top: 0;
            transform: translateY(-100%);

            #{$dropdown}__wrapper{
                border-top-width: 1.1px; // fixes - https://bugs.chromium.org/p/chromium/issues/detail?id=1147523
                border-bottom-width: 0;
            }
        }

        // when the dropdown is shown next to the caret while typing
        &[position="text"]{
            box-shadow: 0 0 0 3px rgba(var(--tagify-dd-color-primary), .1);
            font-size: .9em;

            #{$dropdown}__wrapper{
                border-width: 1px;
            }
        }

        &__wrapper{
            scroll-behavior: auto; // keep up/down arrow pressed to see the effect without this
            max-height: var(--tagify-dd-max-height);
            overflow: hidden;
            overflow-x: hidden;
            color: var(--tagify-dd-text-color);
            background: var(--tagify-dd-bg-color);
            border: 1px solid;
            border-color: var(--tagify-dd-color-primary);
            border-bottom-width: 1.5px; // fixes - https://bugs.chromium.org/p/chromium/issues/detail?id=1147523
            border-top-width: 0;
            box-shadow: 0 2px 4px -2px rgba(black,.2);
            transition: $trans $trans-curve, transform math.div($trans, 2);
            animation: dd-wrapper-show 0s $trans forwards;
        }

        @keyframes dd-wrapper-show {
            to { overflow-y: auto; }
        }

        &__header{
            &:empty{ display: none; }
        }

        &__footer{
            display: inline-block;
            margin-top: .5em;
            padding: var(--tagify-dd-item-pad);
            font-size: 0.7em;
            font-style: italic;
            opacity: .5;

            &:empty{ display: none; }
        }

        // intial state, pre-rendered
        &--initial{
            #{$dropdown}__wrapper{
                max-height: 20px;
                transform: translateY(-1em);
            }

            &[placement="top"]{
                #{$dropdown}__wrapper{
                    transform: translateY(2em);
                }
            }
        }

        &__item{
            box-sizing: border-box;
            padding: var(--tagify-dd-item-pad);
            margin: 1px;
            white-space: pre-wrap;
            cursor: pointer;
            border-radius: 2px;
            position: relative;
            outline: none;
            max-height: 60px;
            max-width: 100%;
            line-height: normal;
            position: relative;

            &--active{
                background: var(--tagify-dd-color-primary);
                color: white;
            }

            &:active{
                filter: brightness(105%);
            }

            /* custom hidden transition effect is needed for horizontal-layout suggestions */
            &--hidden{
                padding-top: 0;
                padding-bottom: 0;
                margin: 0 1px;
                pointer-events: none;
                overflow: hidden;
                max-height: 0;
                transition: var(--tagify-dd-item--hidden-duration, .3s) !important;

                > * {
                    transform: translateY(-100%);
                    opacity: 0;
                    transition: inherit;
                }
            }

            &--selected{
                &::before{
                    content: "✓"; // checkmark
                    font-family: monospace;
                    position: absolute;
                    inset-inline-start: 6px;
                    text-indent: 0;
                    line-height: 1.1;
                }
            }
        }

        &:has(.tagify__dropdown__item--selected) .tagify__dropdown__item {
            text-indent: 1em;
        }
    }
}
