<template>
  <Action
    :color="enabled ? 'blue-lighten-1' : 'white'"
    icon="zoom_in"
    :text="t('labels.zoom')"
    :variant="variant"
    @click="toggleZoom"
  />
</template>

<script setup lang="ts">
import { MovementData, ScanView } from '@3cr/types-ts';
import { ref, toRefs } from 'vue';
import { useViewer3cr } from '@/composables/useViewer3cr';
import { useI18n } from 'vue-i18n';
import { useEventListener } from '@vueuse/core';
import { storeToRefs } from 'pinia';
import { useViewerStore } from '@/stores/viewer.store';

const SENSITIVITY = 0.25;

interface Props {
  view: ScanView;
  target?: EventTarget;
  variant?: 'button' | 'menu-item';
}

const props = withDefaults(defineProps<Props>(), {
  variant: 'button',
});

const { t } = useI18n();
const viewer3cr = useViewer3cr();
const { enableMouse } = storeToRefs(useViewerStore());

const { target } = toRefs(props);
useEventListener(target, 'mousedown', onMouseDown);

const enabled = ref<boolean>(false);

function toggleZoom(): void {
  enabled.value = !enabled.value;
}

async function zoomIn(delta: number): Promise<void> {
  const message: MovementData = {
    Version: '0.0.0',
    View: props.view,
    Movement: delta,
  };
  await viewer3cr.zoomIn({ message });
}

function onMouseDown(event: MouseEvent): void {
  if (!enabled.value || event.button !== 0) {
    return;
  }

  let originY = event.clientY;

  const onMouseMove = async (event: MouseEvent) => {
    const offsetY = event.clientY;
    const delta = (originY - offsetY) * SENSITIVITY;
    originY = offsetY;
    await zoomIn(delta);
  };

  const onMouseUp = () => {
    globalThis.removeEventListener('mousemove', onMouseMove);
    globalThis.removeEventListener('mouseup', onMouseUp);
    enableMouse.value = true;
  };

  globalThis.addEventListener('mousemove', onMouseMove);
  globalThis.addEventListener('mouseup', onMouseUp);
  enableMouse.value = false;
}
</script>
