<template>
	<div class="range-container">
		<div
			class="label label-start"
			:class="{ disabled }"
			@click="setValue('valueA', min)"
		>
			<slot name="start" />
		</div>

		<div
			class="range"
			:class="{ disabled }"
			:style="{ background: `linear-gradient(90deg, var(--slider-track) ${minPercentage}%, var(--slider-range) ${minPercentage}%, var(--slider-range) ${maxPercentage}%, var(--slider-track) ${maxPercentage}%)` }"
		>
			<input
				v-model="valueA"
				:min="min"
				:max="max"
				:data-value="valueA"
				:disabled="disabled"
				type="range"
				class="slider"
				@change="emit"
			>

			<input
				v-model="valueB"
				:min="min"
				:max="max"
				:data-value="valueB"
				:disabled="disabled"
				type="range"
				class="slider"
				@change="emit"
			>
		</div>

		<div
			class="label label-end"
			:class="{ disabled }"
			@click="setValue('valueB', max)"
		>
			<slot name="end" />
		</div>
	</div>
</template>

<script>
function minValue() {
	return Math.min(this.valueA, this.valueB);
}

function maxValue() {
	return Math.max(this.valueA, this.valueB);
}

function minPercentage() {
	return (this.minValue / this.max) * 100;
}

function maxPercentage() {
	return (this.maxValue / this.max) * 100;
}

function emit() {
	this.$emit('change', [this.minValue, this.maxValue]);
}

function setValue(prop, value) {
	if (!this.disabled) {
		this[prop] = value;
		this.emit();
	}
}

export default {
	props: {
		min: {
			type: Number,
			default: 0,
		},
		max: {
			type: Number,
			default: 10,
		},
		value: {
			type: Array,
			default: () => [3, 7],
		},
		disabled: {
			type: Boolean,
			default: false,
		},
	},
	emits: ['change'],
	data() {
		return {
			valueA: this.value[0],
			valueB: this.value[1],
		};
	},
	computed: {
		minValue,
		maxValue,
		minPercentage,
		maxPercentage,
	},
	methods: {
		emit,
		setValue,
	},
};
</script>

<style lang="scss" scoped>
@mixin thumb {
	appearance: none;
	display: block;
	width: 1.25rem;
	height: 1.25rem;
	border: none;
	border-radius: 50%;
	background: var(--slider-thumb);
	pointer-events: visible;
	cursor: pointer;
	box-shadow: 0 0 3px var(--shadow-weak);
}

.range-container {
	display: flex;
	justify-content: space-between;
}

.range {
	--slider-track: var(--shadow-hint);
	--slider-range: var(--primary-faded);
	--slider-thumb: var(--primary);

	position: relative;
	height: 1.25rem;
	flex-grow: 1;
	border-radius: .625rem;

	&.disabled {
		--slider-range: var(--shadow-weak);
		--slider-thumb: var(--disabled-handle);
	}
}

.slider {
	width: 100%;
	top: 0;
	margin: 0;
	appearance: none;
	position: absolute;
	background: none;
	outline: none;
	pointer-events: none;
}

.slider::-webkit-slider-thumb {
	@include thumb;
}

.slider::-moz-range-thumb {
	@include thumb;
	transform: translateY(2px);
}

.label {
	padding: 0 .5rem;

	&:hover:not(.disabled) {
		cursor: pointer;

		::v-deep(.icon) {
			fill: var(--primary);
		}
	}
}

::v-deep(.icon) {
	width: 1.5rem;
	height: 1.5rem;
	flex-shrink: 0;
	fill: var(--shadow);
}
</style>
