<template>
    <div>
        <div class="bs-range-title">
            {{ title }}
            <BsInfoTooltip :text="infoText" v-if="infoText"></BsInfoTooltip>
        </div>
        <div class="bs-range-controls">
            <QInput
                class="bs-input-field"
                type="number"
                debounce="2000"
                :model-value="clampedLocalMin"
                @update:model-value="updateMin"
                outlined
                dense
                padding="0"
                :size="clampedLocalMin.toString().length"
                :step="step"
                :min="min"
                :max="localMax"
            />
            <BsRange
                v-model="rangeValues"
                :min="min"
                :max="max"
                :step="step"
                :style="{ 'max-width': '100%' }"
                inner-track-color="slider-inner-track"
                color="primary"
            />
            <QInput
                class="bs-input-field"
                type="number"
                debounce="2000"
                :model-value="clampedLocalMax"
                @update:model-value="updateMax"
                outlined
                dense
                padding="0"
                :size="clampedLocalMax.toString().length"
                :step="step"
                :min="localMin"
                :max="max"
            />
            <slot></slot>
        </div>
    </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { BsRange } from "quasar-ui-bs";
import BsInfoTooltip from "./BsInfoTooltip.vue";
import { QInput } from "quasar";
export default defineComponent({
    name: "BsInputRange",
    components: {
        BsRange,
        BsInfoTooltip,
        QInput,
    },
    props: {
        title: { type: String, required: true },
        min: { type: Number, required: true },
        max: { type: Number, required: true },
        modelValue: { type: Object, required: true },
        infoText: String,
    },
    data() {
        return {
            localMin: Math.min(this.modelValue.min || this.min, this.max),
            localMax: Math.max(this.modelValue.max || this.max, this.min),
            rangeValues: { min: 0, max: 0 },
        };
    },
    computed: {
        clampedLocalMin(): number {
            return Math.min(this.max, Math.max(this.min, this.localMin));
        },
        clampedLocalMax(): number {
            return Math.min(this.max, Math.max(this.min, this.localMax));
        },
        step() {
            const minSplit = this.min.toString().split(".");
            const maxSplit = this.max.toString().split(".");
            return (
                10 **
                -Math.max(
                    0,
                    minSplit.length > 1 ? minSplit[1].length : 0,
                    maxSplit.length > 1 ? maxSplit[1].length : 0
                )
            );
        },
    },
    mounted() {
        this.setRangeValues();
    },
    methods: {
        updateMin(newVal: number | string | null) {
            if (!newVal) return;
            this.localMin = Number(newVal);
            this.rangeValues.min = this.clampedLocalMin;
            this.emitValues();
        },
        updateMax(newVal: number | string | null) {
            if (!newVal) return;
            this.localMax = Number(newVal);
            this.rangeValues.max = this.clampedLocalMax;
            this.emitValues();
        },
        emitValues() {
            this.$emit("update:modelValue", {
                min: this.clampedLocalMin,
                max: this.clampedLocalMax,
            });
        },
        setRangeValues() {
            this.rangeValues = {
                min: Math.min(this.modelValue.min || this.min, this.max),
                max: Math.max(this.modelValue.max || this.max, this.min),
            };
        },
    },

    watch: {
        modelValue(newVal: any) {
            this.localMin = newVal.min;
            this.localMax = newVal.max;
            this.rangeValues = newVal;
        },
        "rangeValues.min"(newVal) {
            this.localMin = newVal;
            this.emitValues();
        },
        "rangeValues.max"(newVal) {
            this.localMax = newVal;
            this.emitValues();
        },
        min(newMin) {
            this.localMin = newMin;
            this.setRangeValues();
        },
        max(newMax) {
            this.localMax = newMax;
            this.setRangeValues();
        },
    },
});
</script>

<style scoped>
.bs-range-title {
    font-weight: normal;
    margin-bottom: 10px;
}

.bs-range-controls {
    display: flex;
    align-items: center;
    gap: 20px;
    justify-content: space-between;
}

.bs-input-field {
    /* min-width: 40px; */
    width: 100%;
    max-width: 80px;
}
:deep(.q-field--outlined .q-field__control) {
    padding: 0 8px !important;
    height: 28px;
    font-size: 12px;
}
</style>
