<template>
    <div ref="modalRef"
         class="tabs_item 小手指"
         v-if="modal"
         :style="displayLocation">
        <slot v-if="slots"/>
        <ul v-else>
            <li v-for="(item,index) in props.config"
                :style="prohibit(item)"
                @click="handlingClickEvents(item.click, index)">
                <div class="icon">
                    <component v-if="item.icon" :is="item.icon"/>
                </div>
                <div class="writtenWords">
                    {{ item.name }}
                </div>
                <div class="suffix"/>
            </li>
            <li @click="modal = false">
                <div class="icon">
                    <el-icon>
                        <Close/>
                    </el-icon>
                </div>
                <div class="writtenWords">
                    关闭
                </div>
                <div class="suffix"/>
            </li>
        </ul>
    </div>
</template>

<script setup name='RightClickMenu'>
import {ref} from "vue";
import {onClickOutside} from '@vueuse/core'

const props = defineProps({
    config: {
        type: Array,
        default: [{
            name: '请设置', click: () => {
                console.warn('请先设置')
            }
        }]
    },
    mousePosition: {
        type: Object,
        default: {}
    },
    closeManually: {
        type: Boolean,
        default: false
    }
})


const modal = ref(false)
const modalRef = ref(null)

onClickOutside(modalRef, () => {
    if (!props.closeManually) {
        modal.value = false
    }
})

let displayLocation = $ref({
    left: '0px',
    top: '0px'
})

const handlingClickEvents = (cb, index) => {
    let data = props.config[index]
    if (data.validator && !data.validator(props.mousePosition.data)) {
        modal.value = false
        return;
    }

    cb(props.mousePosition.data, props.mousePosition.index);
    modal.value = false
}

const prohibit = (data) => {
    if (!data.validator) {
        return
    }
    if (!data.validator(props.mousePosition.data)) {
        return {
            color: '#c8c9cc',
            cursor: 'not-allowed'
        }
    }
}

watch(() => props.mousePosition, () => {
    modal.value = true
    nextTick(() => {
        calculateTheLocation(props.mousePosition.event.pageX, props.mousePosition.event.pageY)
    })
})

const calculateTheLocation = (x, y) => {

    const {innerWidth: windowWidth, innerHeight: windowHeight} = window;

    const menu = modalRef.value;
    const menuHeight = menu.offsetHeight;
    const menuWidth = menu.offsetWidth


    if (menuWidth + x + 20 >= windowWidth) {
        displayLocation.left = x - menuWidth + 'px';
    } else {
        displayLocation.left = x + 'px';
    }

    if (menuHeight + y + 20 >= windowHeight) {
        displayLocation.top = y - menuHeight + 'px'
    } else {
        displayLocation.top = y + 'px';
    }
}

const close = () => {
    modal.value = false
}

defineExpose({
    close
})

let slots = $ref(false)
onMounted(() => {
    if (!!useSlots().default) {
        slots = true
    }
})

</script>

<style scoped lang="scss">
.tabs_item {
  position: fixed;
  margin: 5px;
  padding: 5px;
  z-index: 100;
  background-color: white;
  box-shadow: 2px 2px 3px 0 rgb(4 4 4);
  border-radius: 5px;

  li {
    margin: 3px 0;
    border-radius: 5px;
    font-size: 14px;
    padding: 5px 10px;
    line-height: 20px;
    display: flex;
    align-items: center;

    .icon {
      width: 20px;
      display: flex;
      align-items: center;
      box-sizing: border-box;
    }

    .writtenWords {
      min-width: max-content;
    }

    .suffix {
      width: 30px
    }

    &:hover {
      background-color: #c6e2ff;
      //color: white;
    }
  }
}
</style>
