<template>
    <button
        :class="[
            bem({ checked: checkedValue, reverse: reverse, ...variantsMap }),
            checkedClass && checkedValue ? checkedClass : null,
        ]"
        role="switch"
        :aria-checked="checkedValue"
        @click="toggleChecked"
        :type="buttonType"
    >
        <span
            :class="[bem('track'), trackClass]"
            :style="{ backgroundColor: checkedValue ? checkedColor : uncheckedColor }"
        >
            <span :class="bem('spacer')"></span>
            <transition name="px-toggle-icon">
                <span v-if="$slots['icon-on'] && checkedValue" :class="bem('icon', { on: true })">
                    <slot name="icon-on" />
                </span>
            </transition>
            <transition name="px-toggle-icon">
                <span
                    v-if="$slots['icon-off'] && !checkedValue"
                    :class="bem('icon', { off: true })"
                >
                    <slot name="icon-off" />
                </span>
            </transition>
            <span
                :class="[bem('thumb'), trackClass]"
                :style="{ backroundColor: thumbColor }"
            ></span>
        </span>
        <slot name="on-label" v-if="!$slots.default && checkedValue">
            <span v-if="label" :class="[bem('label'), labelClass]">
                {{ label }}
            </span>
        </slot>
        <slot name="off-label" v-if="!$slots.default && !checkedValue">
            <span v-if="uncheckedLabel || label" :class="[bem('label'), labelClass]">
                {{ uncheckedLabel || label }}
            </span>
        </slot>
        <slot name="default" :checked="checkedValue"></slot>
    </button>
</template>

<script>
import PxBaseToggle from '../bases/PxBaseToggle.vue';
import PxBaseVariants from '../bases/PxBaseVariants.vue';
export default {
    name: 'px-toggle',
    // components: { Component },
    mixins: [PxBaseToggle, PxBaseVariants],
    props: {
        /** Label text to be displayed in on state (override with #on-label slot) */
        label: { type: String, default: null },

        /** Label text to be displayed in off state (override with #off-label slot) */
        uncheckedLabel: { type: String, default: '' },

        /** Class that will be applied to the track element */
        trackClass: { type: String, default: null },

        /** Class that will be applied to the thumb element */
        thumbClass: { type: String, default: null },

        /** Class that will be applied to the default on/off label element */
        labelClass: { type: String, default: null },

        /** Color that will be set on track in the on state  (use trackClass for further styling) */
        checkedColor: { type: String, default: null },

        /** Color that will optionally be set on track in the off state (use trackClass for further styling) */
        uncheckedColor: { type: String, default: null },

        /** Thumb color that will optionally be set on the thumb (use thumbClass for further styling) */
        thumbColor: { type: String, default: null },

        /** Toggle the label/toggle order */
        reverse: { type: Boolean, default: false },

        // 'submit' (default for <button> if not set), 'reset' (resets form) or 'button' (no action)
        buttonType: { type: String, default: 'button' },
    },
};
</script>

<style lang="scss">
@use '../styles/px.scss' as *;
@use '@thinkpixellab-public/px-styles/src/modules/controls' as *;

.px-toggle {
    @at-root {
        @include vue-transition-fade(px-toggle-icon);

        :root {
            --px-toggle-size: 1em;
            --px-toggle-unchecked: #{gray(-8, 0.33)};
            --px-toggle-checked: #{accent()};
            --px-toggle-thumb: white;
            --px-toggle-track-shadow: inset 0 1px 1px 0 rgba(0, 0, 0, 0.2);
            --px-toggle-thumb-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.4);
        }
    }

    @include toggle-switch(
        (
            '--thumb.background-color': var(--px-toggle-thumb),
            '--thumb.font-size': var(--px-toggle-size),
            '--track.background-color': var(--px-toggle-unchecked),
            '--track.font-size': var(--px-toggle-size),
            '--track.box-shadow': var(--px-toggle-track-shadow),
            '--thumb.box-shadow': var(--px-toggle-thumb-shadow),
            'checked.--track.background-color': var(--px-toggle-checked),
        ),
        '.px-toggle__track',
        '.px-toggle__thumb',
        '.px-toggle__spacer'
    );

    &__icon {
        position: absolute;
        top: 0;
        height: 100%;
        aspect-ratio: 1;
        border-radius: 50%;

        display: flex;
        align-items: center;
        justify-content: center;

        &--on {
            left: 0;
        }

        &--off {
            right: 0;
        }
    }

    &--reverse {
        flex-direction: row-reverse;
    }

    // VARIANTS

    // sm - resizes just the toggle (not the label) to fs(sm)

    &--sm & {
        &__track,
        &__thumb {
            font-size: fs(sm);
        }
    }

    // xs - resizes just the toggle (not the label) to fs(xs)

    &--xs & {
        &__track,
        &__thumb {
            font-size: fs(xs);
        }
    }
}
</style>
