<template>
    <div class="range-slider">
        <div class="slider-container" ref="sliderContainer">
            <!-- Track -->
            <div class="slider-track">
                <!-- Progress (filled portion) -->
                <div 
                    class="slider-progress" 
                    :style="{ width: progressWidth + '%' }"
                ></div>
            </div>
            
            <!-- Thumb -->
            <div 
                class="slider-thumb"
                :style="{ left: progressWidth + '%' }"
                @mousedown="startDrag"
                @touchstart="startDrag"
            ></div>
            
            <!-- Hidden input for form submission -->
            <input 
                type="range" 
                :min="min" 
                :max="max" 
                :step="step"
                :value="modelValue"
                @input="updateValue"
                class="slider-input"
                ref="hiddenInput"
            />
        </div>
        
        <!-- Labels -->
        <div v-if="labels && labels.length" class="slider-labels">
            <span 
                v-for="(label, index) in labels" 
                :key="index"
                class="slider-label"
                :style="{ left: (index / (labels.length - 1)) * 100 + '%' }"
            >
                {{ label }}
            </span>
        </div>
    </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'

const props = defineProps({
    modelValue: {
        type: [Number, String],
        required: true
    },
    min: {
        type: [Number, String],
        default: 0
    },
    max: {
        type: [Number, String],
        default: 100
    },
    step: {
        type: [Number, String],
        default: 1
    },
    labels: {
        type: Array,
        default: () => []
    },
    color: {
        type: String,
        default: 'blue'
    }
})

const emit = defineEmits(['update:modelValue'])

const sliderContainer = ref(null)
const hiddenInput = ref(null)
const isDragging = ref(false)

// Convert string values to numbers
const minValue = computed(() => parseFloat(props.min))
const maxValue = computed(() => parseFloat(props.max))
const stepValue = computed(() => parseFloat(props.step))
const currentValue = computed(() => parseFloat(props.modelValue))

// Calculate progress percentage
const progressWidth = computed(() => {
    const range = maxValue.value - minValue.value
    const progress = currentValue.value - minValue.value
    return Math.max(0, Math.min(100, (progress / range) * 100))
})

// Color classes based on prop
const colorClasses = computed(() => {
    const colors = {
        blue: 'bg-blue-600',
        purple: 'bg-purple-600',
        green: 'bg-green-600',
        red: 'bg-red-600',
        gray: 'bg-gray-600'
    }
    return colors[props.color] || colors.blue
})

const updateValue = (event) => {
    const newValue = parseFloat(event.target.value)
    emit('update:modelValue', newValue)
}

const startDrag = (event) => {
    isDragging.value = true
    document.addEventListener('mousemove', onDrag)
    document.addEventListener('mouseup', stopDrag)
    document.addEventListener('touchmove', onDrag)
    document.addEventListener('touchend', stopDrag)
    
    // Prevent text selection
    event.preventDefault()
}

const onDrag = (event) => {
    if (!isDragging.value || !sliderContainer.value) return
    
    const rect = sliderContainer.value.getBoundingClientRect()
    const clientX = event.touches ? event.touches[0].clientX : event.clientX
    const x = clientX - rect.left
    const percentage = Math.max(0, Math.min(100, (x / rect.width) * 100))
    
    const range = maxValue.value - minValue.value
    const rawValue = minValue.value + (percentage / 100) * range
    
    // Round to nearest step
    const steppedValue = Math.round(rawValue / stepValue.value) * stepValue.value
    const clampedValue = Math.max(minValue.value, Math.min(maxValue.value, steppedValue))
    
    emit('update:modelValue', clampedValue)
}

const stopDrag = () => {
    isDragging.value = false
    document.removeEventListener('mousemove', onDrag)
    document.removeEventListener('mouseup', stopDrag)
    document.removeEventListener('touchmove', onDrag)
    document.removeEventListener('touchend', stopDrag)
}

onUnmounted(() => {
    // Cleanup event listeners
    document.removeEventListener('mousemove', onDrag)
    document.removeEventListener('mouseup', stopDrag)
    document.removeEventListener('touchmove', onDrag)
    document.removeEventListener('touchend', stopDrag)
})
</script>

<style lang="scss" scoped>
.range-slider {
    @apply w-full;
}

.slider-container {
    @apply relative w-full h-6 flex items-center cursor-pointer;
}

.slider-track {
    @apply w-full h-2 bg-gray-200 rounded-full relative;
}

.slider-progress {
    @apply h-full bg-blue-600 rounded-full transition-all duration-150 ease-out;
}

.slider-thumb {
    @apply absolute w-5 h-5 bg-white border-2 border-blue-600 rounded-full shadow-md cursor-grab transform -translate-x-1/2 transition-all duration-150 ease-out;
    
    &:hover {
        @apply scale-110 shadow-lg;
    }
    
    &:active {
        @apply cursor-grabbing scale-105;
    }
}

.slider-input {
    @apply absolute inset-0 w-full h-full opacity-0 cursor-pointer;
}

.slider-labels {
    @apply relative w-full mt-2;
}

.slider-label {
    @apply absolute text-xs text-gray-500 transform -translate-x-1/2;
}

// Color variants
.range-slider.purple {
    .slider-progress {
        @apply bg-purple-600;
    }
    
    .slider-thumb {
        @apply border-purple-600;
    }
}

.range-slider.green {
    .slider-progress {
        @apply bg-green-600;
    }
    
    .slider-thumb {
        @apply border-green-600;
    }
}

.range-slider.red {
    .slider-progress {
        @apply bg-red-600;
    }
    
    .slider-thumb {
        @apply border-red-600;
    }
}

.range-slider.gray {
    .slider-progress {
        @apply bg-gray-600;
    }
    
    .slider-thumb {
        @apply border-gray-600;
    }
}

// Focus styles for accessibility
.slider-input:focus + .slider-container .slider-thumb {
    @apply ring-2 ring-blue-500 ring-offset-2;
}

// Disabled state
.range-slider.disabled {
    @apply opacity-50 pointer-events-none;
}
</style>
