<template>
  <div class="zoom-control glass--button">
    <button class="zoom-control__btn" @click="$emit('zoomIn')">
      <q-icon name="add" size="18px" />
    </button>
    <div class="zoom-control__track" ref="trackRef" @pointerdown="onTrackDown">
      <div class="zoom-control__fill" :style="{ height: fillPercent + '%' }" />
      <div class="zoom-control__thumb" :style="{ bottom: fillPercent + '%' }" />
    </div>
    <button class="zoom-control__btn" @click="$emit('zoomOut')">
      <q-icon name="remove" size="18px" />
    </button>
  </div>
</template>

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

const props = defineProps({
  zoom: { type: Number, default: 1 },
  min: { type: Number, default: 0.4 },
  max: { type: Number, default: 3.0 }
})

const emit = defineEmits(['zoomIn', 'zoomOut', 'zoomTo'])
const trackRef = ref(null)

const fillPercent = computed(() => {
  return ((props.zoom - props.min) / (props.max - props.min)) * 100
})

function onTrackDown(e) {
  if (!trackRef.value) return
  updateFromPointer(e)

  const onMove = (ev) => updateFromPointer(ev)
  const onUp = () => {
    window.removeEventListener('pointermove', onMove)
    window.removeEventListener('pointerup', onUp)
  }
  window.addEventListener('pointermove', onMove)
  window.addEventListener('pointerup', onUp)
}

function updateFromPointer(e) {
  if (!trackRef.value) return
  const rect = trackRef.value.getBoundingClientRect()
  // Bottom = min, top = max → invert Y
  const ratio = 1 - Math.max(0, Math.min(1, (e.clientY - rect.top) / rect.height))
  const newZoom = props.min + ratio * (props.max - props.min)
  emit('zoomTo', newZoom)
}
</script>

<style scoped>
.zoom-control {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 6px 4px;
  border-radius: 22px;
  width: 36px;
}

.zoom-control__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: none;
  background: none;
  color: inherit;
  cursor: pointer;
  border-radius: 50%;
  padding: 0;
  transition: background 0.15s ease;
}

.zoom-control__btn:active {
  background: rgba(255, 255, 255, 0.12);
}

.zoom-control__track {
  position: relative;
  width: 3px;
  height: 80px;
  background: rgba(255, 255, 255, 0.12);
  border-radius: 2px;
  cursor: pointer;
  touch-action: none;
}

.zoom-control__fill {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.35);
  pointer-events: none;
}

.zoom-control__thumb {
  position: absolute;
  left: 50%;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #fff;
  transform: translate(-50%, 50%);
  pointer-events: none;
  box-shadow: 0 0 6px rgba(255, 255, 255, 0.4);
}

/* Light mode adjustments */
.body--light .zoom-control__track {
  background: rgba(0, 0, 0, 0.1);
}

.body--light .zoom-control__fill {
  background: rgba(0, 0, 0, 0.25);
}

.body--light .zoom-control__thumb {
  background: #333;
  box-shadow: 0 0 6px rgba(0, 0, 0, 0.2);
}

.body--light .zoom-control__btn:active {
  background: rgba(0, 0, 0, 0.08);
}
</style>
