<template>
  <v-menu v-model:model-value="m_open">
    <template #activator="{ props: menu }">
      <v-tooltip location="bottom" open-delay="1000">
        <template #activator="{ props: tooltip }">
          <v-btn v-bind="mergeProps(menu, tooltip)" data-testid="menu" :icon="true" size="24" variant="text">
            <v-icon icon="more_vert" size="16" color="shark_400" />
          </v-btn>
        </template>
        <span>{{ t('labels.moreActions') }}</span>
      </v-tooltip>
    </template>
    <v-list id="mcad-menu">
      <template v-for="option in dropdownOptions" :key="option.label">
        <v-list-item
          v-if="option.display"
          class="px-4 py-2"
          :data-testid="option.dataTestId"
          :prepend-icon="option.icon"
          @click="option.onClick"
        >
          <v-list-item-title>{{ option.label }}</v-list-item-title>
          <v-spacer />
          <v-list-item-subtitle class="ml-4">{{ option.hotkey }}</v-list-item-subtitle>
        </v-list-item>
      </template>
    </v-list>
  </v-menu>
  <mcad-update-modal v-model="m_update" :mcad="mcad" />
  <mcad-delete-modal v-model="m_delete" :mcad="mcad" />
</template>

<script setup lang="ts">
import { computed, mergeProps, ref, watch } from 'vue';
import { useViewer3cr } from '@/composables/useViewer3cr';
import { storeToRefs } from 'pinia';
import { useViewerStore } from '@/stores/viewer.store';
import { useToolStore } from '@/stores/tool.store';
import { defineHotkeys, Hotkeys, HotkeyScope, resetScope } from '@/functions/HotkeyScope';
import { useI18n } from 'vue-i18n';
import { SHORTCUT_TEXT, translateTooltipShortcut } from '@/functions/translateTooltipShortcut';
import { ObjectVisibility } from '@3cr/types-ts';
import { useToolGroup } from '@/composables/useToolGroup';
import { DataOverlayMcad } from '@3cr/viewer-types-ts';
import { MaybePromise } from 'rollup';

interface Props {
  mcad: DataOverlayMcad;
}

interface DropdownOption {
  dataTestId: string;
  icon: string;
  onClick: () => MaybePromise<void>;
  label: string;
  hotkey: string;
  display: boolean;
}

const props = defineProps<Props>();

const { t } = useI18n();
const { mcadMoveTool, mcadRotateTool, mcadScaleTool, mcadSelectTool } = useToolStore();
const { toggleTool } = useToolGroup(mcadMoveTool, mcadRotateTool, mcadScaleTool);
const viewer3cr = useViewer3cr();
const { options } = storeToRefs(useViewerStore());

const m_delete = ref<boolean>(false);
const m_update = ref<boolean>(false);
const m_open = ref<boolean>(false);

const selected = computed(() => mcadSelectTool.selected.value);

const showDownloadMcad = computed(() => {
  return !!options.value.onDownloadMcad;
});

const dropdownOptions = computed<Array<DropdownOption>>(() => [
  {
    dataTestId: 'update',
    icon: 'edit_square',
    onClick: updateMcad,
    label: t('labels.edit'),
    hotkey: translateTooltipShortcut(SHORTCUT_TEXT.e),
    display: true
  },
  {
    dataTestId: 'move',
    icon: 'drag_pan',
    onClick: move,
    label: t('labels.move'),
    hotkey: translateTooltipShortcut(SHORTCUT_TEXT.m),
    display: true
  },
  {
    dataTestId: 'rotate',
    icon: '360',
    onClick: rotate,
    label: t('labels.rotate'),
    hotkey: translateTooltipShortcut(SHORTCUT_TEXT.r),
    display: true
  },
  // TODO: not implemented in 3cr
  // {
  //   dataTestId: 'scale',
  //   icon: 'open_in_full',
  //   onClick: scale,
  //   label: t('labels.scale'),
  //   hotkey: translateTooltipShortcut(SHORTCUT_TEXT.s),
  //   display: true
  // },
  {
    dataTestId: 'group',
    icon: 'folder',
    onClick: group,
    label: t('labels.group'),
    hotkey: translateTooltipShortcut(SHORTCUT_TEXT.g),
    display: !!selected.value && props.mcad.Id !== selected.value.Id
  },
  {
    dataTestId: 'show',
    icon: 'visibility',
    onClick: toggle,
    label: t('labels.show'),
    hotkey: translateTooltipShortcut(SHORTCUT_TEXT.h),
    display: !props.mcad.Visibility || false
  },
  {
    dataTestId: 'hide',
    icon: 'visibility_off',
    onClick: toggle,
    label: t('labels.hide'),
    hotkey: translateTooltipShortcut(SHORTCUT_TEXT.h),
    display: props.mcad.Visibility || false
  },
  {
    dataTestId: 'lock',
    icon: 'lock',
    onClick: lockMcad,
    label: t('labels.lock'),
    hotkey: translateTooltipShortcut(SHORTCUT_TEXT.l),
    display: !props.mcad.Locked || false
  },
  {
    dataTestId: 'unlock',
    icon: 'lock_open',
    onClick: unlockMcad,
    label: t('labels.unlock'),
    hotkey: translateTooltipShortcut(SHORTCUT_TEXT.l),
    display: props.mcad.Locked || false
  },
  {
    dataTestId: 'download',
    icon: 'download',
    onClick: downloadMcad,
    label: t('labels.download'),
    hotkey: translateTooltipShortcut(SHORTCUT_TEXT.q),
    display: showDownloadMcad.value
  },
  {
    dataTestId: 'delete',
    icon: 'delete',
    onClick: deleteMcad,
    label: t('labels.delete'),
    hotkey: translateTooltipShortcut(SHORTCUT_TEXT.d),
    display: true
  }
]);

watch(m_open, (isOpen: boolean) => {
  if (isOpen) {
    defineHotkeys(HotkeyScope.MCAD_MENU, {
      [Hotkeys.CTRL_SHIFT_E]: () => updateMcad(),
      [Hotkeys.CTRL_SHIFT_M]: () => move(),
      [Hotkeys.CTRL_SHIFT_R]: () => rotate(),
      [Hotkeys.CTRL_SHIFT_S]: () => scale(),
      [Hotkeys.CTRL_SHIFT_G]: () => group(),
      [Hotkeys.CTRL_SHIFT_L]: () => lockMcad(),
      [Hotkeys.CTRL_SHIFT_D]: () => downloadMcad(),
      [Hotkeys.CTRL_SHIFT_DEL]: () => deleteMcad(),
      [Hotkeys.CTRL_SHIFT_H]: () => toggle(),
      [Hotkeys.CTRL_SHIFT_Q]: () => downloadMcad()
    });
  } else {
    resetScope(HotkeyScope.MCAD_MENU);
  }
});

async function lockMcad(): Promise<void> {
  const message = { Version: '0.0.0', Id: props.mcad.Id, Value: true };
  await viewer3cr.lockMcad({ message });
}

async function toggle(): Promise<void> {
  const message: ObjectVisibility = { Version: '0.0.0', Id: props.mcad.Id, Visibility: !props.mcad.Visibility };
  await viewer3cr.setMcadObjectVisibility({ message });
}

async function unlockMcad(): Promise<void> {
  const message = { Version: '0.0.0', Id: props.mcad.Id, Value: false };
  await viewer3cr.lockMcad({ message });
}

async function group(): Promise<void> {
  const ids = [props.mcad.Id, selected.value!.Id];
  const message = { Version: '0.0.0', Parent: '', Children: ids };
  await viewer3cr.groupMcad({ message });
}

async function downloadMcad(): Promise<void> {
  if (options.value.onDownloadMcad) {
    await options.value.onDownloadMcad(props.mcad.Key);
  }
}

function move(): void {
  toggleTool(mcadMoveTool);
}

function rotate(): void {
  toggleTool(mcadRotateTool);
}

function scale(): void {
  toggleTool(mcadScaleTool);
}

function deleteMcad(): void {
  m_delete.value = true;
}

function updateMcad(): void {
  m_update.value = true;
}

defineExpose({
  dropdownOptions,
  m_delete,
  m_update
});
</script>

<style scoped lang="scss">
:deep(.v-list-item__content) {
  display: flex;
  align-items: baseline;
  width: 100%;
}
</style>
