<template>
  <ui-group-option 
    class="sign-tagging" 
    :class="{active: selected, edit}" 
    @click="edit && getTaggingIsShow(tagging) && emit('select', true)"
  >
    <div class="info">
      <img 
        :src="getResource(getFileUrl(tagging.images[0]))" 
        v-if="tagging.images.length"
      >
      <div>
        <p>{{ tagging.title }}</p>
        <span>放置：{{ positions.length }}</span>
      </div>
    </div>
    <div class="actions" @click.stop>
      <ui-icon 
         v-if="!edit"
        type="pin" 
        ctrl 
        @click.stop="$emit('select', true)" 
        :class="{ disabled: !getTaggingIsShow(tagging) }"
      />
      <template v-else>
        <ui-icon type="pin1" ctrl @click.stop="$emit('fixed')" tip="放置" />
        <ui-more 
          :options="menus" 
          style="margin-left: 20px" 
          @click="(action: keyof typeof actions) => actions[action]()" 
        />
      </template>
    </div>
  </ui-group-option>
</template>

<script setup lang="ts">
import { getFileUrl } from '@/utils'
import { computed, ref, watchEffect, nextTick } from 'vue';
import { getResource, showTaggingPositionsStack } from '@/env'
import { sdk } from '@/sdk'
import { 
  getTaggingStyle, 
  getTaggingPositions, 
  getFuseModel,
  getFuseModelShowVariable,
  getTaggingIsShow
} from '@/store'

import type { Tagging } from '@/store'

const props = withDefaults(
  defineProps<{ tagging: Tagging, selected?: boolean, edit?: boolean }>(),
  { edit: true }
)
const style = computed(() => getTaggingStyle(props.tagging.styleId))
const positions = computed(() => getTaggingPositions(props.tagging))

const emit = defineEmits<{ 
  (e: 'delete'): void 
  (e: 'edit'): void
  (e: 'select', selected: boolean): void
  (e: 'fixed'): void
}>()

const menus = [
  { label: '编辑', value: 'edit' },
  { label: '删除', value: 'delete' },
]
const actions = {
  edit: () => emit('edit'),
  delete: () => emit('delete')
}

const flyTaggingPositions = (tagging: Tagging, callback?: () => void) => {
  const positions = getTaggingPositions(tagging)

  let isStop = false
  const flyIndex = (i: number) => {
    if (isStop || i >= positions.length) {
      callback && nextTick(callback)
      return;
    }
    const position = positions[i]
    const model = getFuseModel(position.modelId)
    if (!model || !getFuseModelShowVariable(model).value) {
      flyIndex(i + 1)
      return;
    }

    const pop = showTaggingPositionsStack.push(ref(new WeakSet([position])))
    sdk.comeTo({ 
      position: position.localPos, 
      modelId: position.modelId,
      dur: 300,
      distance: 3
    })
    
    setTimeout(() => {
      pop()
      flyIndex(i + 1)
    }, 2000)
  }
  flyIndex(0)
  return () => isStop = true
}
watchEffect((onCleanup) => {
  if (props.selected) {
    const success = () => emit('select', false)
    const stop = flyTaggingPositions(props.tagging, success)
    const keyupHandler = (ev: KeyboardEvent) => ev.code === 'Escape' && success()

    document.documentElement.addEventListener('keyup', keyupHandler, false)
    onCleanup(() => {
      stop()
      document.documentElement.removeEventListener('keyup', keyupHandler, false)
    })
  }
})
</script>

<style lang="scss" scoped src="./style.scss"></style>