<script setup lang="ts">
    import { computed } from 'vue';
    import { Nullable, UIColorName, UIColorValues, UISize } from '@/UI-kit/types';
    import { UILoader } from '@/index';
    import { UIColor } from '@/UI-kit/constants';

    import { IButtonType, IButtonProps } from '@/UI-kit/types/UI/ui-button.type';
    import { useI18n } from 'vue-i18n';

    const props = withDefaults(defineProps<IButtonProps>(), {
        text: '',
        isLoading: false,
        isBoxShadow: false,
        disabled: false,
        isActive: false,
        size: UISize.S,
        color: UIColor[UIColorName.White],
        bgColor: UIColor[UIColorName.GradientBlue],
        borderColor: UIColor[UIColorName.Blue100_25],
        activeColor: UIColor[UIColorName.White],
        activeBgColor: UIColor[UIColorName.GradientBlue],
        buttonType: IButtonType.BUTTON,
        loader: () => ({
            text: '',
            color: UIColor[UIColorName.Blue100_25],
            accentColor: UIColor[UIColorName.White],
        }),
    });

    const { t } = useI18n();

    const emit = defineEmits<{
        click: [void];
    }>();

    const classList = computed(() => ({
        [`--${props.size}-size`]: props.size,
        'is-box-shadow': props.isBoxShadow,
        '--is-loading': props.isLoading,
    }));

    const borderColor = computed<Nullable<UIColorValues>>(
        () => (props.borderColor as UIColorValues) || null,
    );

    const computedColor = computed(() => (props.isActive ? props.activeColor : props.color));

    const computedBgColor = computed(() => (props.isActive ? props.activeBgColor : props.bgColor));

    const loaderText = computed(() => {
        if (props.loader.text === null) {
            return '';
        }
        return props.loader.text || t('ui.loader.title');
    });

    const boxShadow = computed(() => {
        if (props.isBoxShadow && props.bgColor === UIColor[UIColorName.GradientBlue]) {
            return '0 0 10px 0 rgba(5, 121, 238, 0.50)';
        }
        return 'none';
    });

    const inline = computed(() => ({
        boxShadow: boxShadow.value,
        border: borderColor.value ? `1px solid ${borderColor.value}` : 'none',
    }));
</script>

<template>
    <button
        :type="buttonType"
        :class="classList"
        :disabled="disabled || isLoading"
        class="ui-button"
        :style="inline"
        @click="emit('click')"
    >
        <span v-if="isLoading" class="ui-button__loader-box">
            <UILoader
                :border-color="loader.color"
                :border-color-left="loader.accentColor"
                class="ui-button__loader"
            />
            <span v-if="loaderText" v-html="loaderText" />
        </span>
        <slot v-else>
            <span v-html="text" />
        </slot>
    </button>
</template>

<style scoped lang="scss">
    @use '@/UI-kit/assets/scss/mixins/index.mixin';

    .ui-button {
        @include index.text(14px, 500, 24px);

        width: 100%;
        background: v-bind(computedBgColor);
        color: v-bind(computedColor);
        border: none;
        transition: filter 0.25s;
        border-radius: 8px;
        outline: none;
        cursor: pointer;
        -webkit-tap-highlight-color: transparent;

        &.is-box-shadow {
            box-shadow: 0 4px 29px rgb(0 0 0 / 10%);
        }

        &:disabled {
            &:not(.--is-loading) {
                background: var(--gray-100);
                color: var(--gray-900);
            }
        }

        &__loader {
            &-box {
                @include index.flex(row, 10px, center, center);

                margin: 0 auto;
                font-weight: 500;
            }
        }

        // button size
        &.--xs-size {
            min-height: 32px;
        }

        &.--s-size {
            min-height: 44px;
        }

        &.--m-size {
            min-height: 48px;
        }

        &.--l-size {
            min-height: 54px;
        }

        &.--xl-size {
            min-height: 64px;
        }

        &.--custom-size {
            min-height: inherit;
        }
    }
</style>
