<template>
    <UItext
        ref="vmRef"
        :disabled="props.disabled"
        class="select ready"
        :class="{
            focus: showOption,
            [className]: className,
        }"
        :model-value="typeof labelValue === 'string' ? labelValue : inputValue"
        :width="props.width"
        :height="props.height"
        :readonly="readonly"
        :placeholder="props.placeholder"
        @update:model-value="val => emit('update:modelValue', val)"
        @blur="blurHandler"
        @focus="showHandler"
        @click="clickShowHandler"
    >
        <template #icon>
            <icon v-if="!$slots.icon" type="pull-down" small />
            <slot v-else name="icon" />
        </template>
        <template v-if="$slots.preIcon" #preIcon>
            <slot name="preIcon" />
        </template>
    </UItext>

    <UIFloating
        :mount="mountEl"
        :refer="vmRef && vmRef.root"
        width="100%"
        :class="{
            show: showOption || props.showOptions,
            [`dire-${dire}`]: true,
            ...(floatingClass ? { [floatingClass]: true } : {}),
        }"
        class="select-float"
        :dire="dire === 'top' ? 'left-top' : 'left-bottom'"
    >
        <slot name="floating-pre" />
        <div class="select-replace" :class="{ 'hide-scroll': props.hideScroll }">
            <ul>
                <template v-for="option in props.options" :key="option.value">
                    <li v-if="props.options?.length" :key="option.value" :class="{ active: props.modelValue === option.value }" @mousedown="ev => optionClickHandler(ev, option)">
                        <template v-if="$slots.option">
                            <slot name="option" :raw="option" :active="props.modelValue === option.value" />
                        </template>
                        <template v-else>{{ option.label }}</template>
                    </li>
                    <li v-else class="un-data">{{ unplaceholder }}</li>
                </template>
            </ul>
        </div>
    </UIFloating>
</template>

<script setup lang="ts">
import { computed, defineExpose, ref } from 'vue'
import icon from '@kankan/components/basic/icon'
import UIFloating from '@kankan/components/basic/floating'
import UItext from '../text/text.vue'
import { selectProps } from './select'

const props = defineProps(selectProps)
const emit = defineEmits(['update:modelValue'])
const vmRef = ref(null)
const showOption = ref(false)
const mountEl = document.body

const inputValue = computed(() => {
    const selectOption = props.options.find(({ value }) => value === props.modelValue)
    return selectOption ? selectOption.label : ''
})

const optionClickHandler = (ev, option) => {
    if (props.stopEl && props.stopEl.toUpperCase() === ev.target.tagName.toUpperCase()) {
        setTimeout(() => {
            vmRef.value.input.focus()
        })
    } else {
        clickCount = 0
        emit('update:modelValue', option.value)
        vmRef.value.input.focus()
        showOption.value = false
    }
}

let clickCount = 0
const clickShowHandler = () => {
    clickCount++
    if (showOption.value && props.dbhide && !(clickCount % 2)) {
        showOption.value = false
        vmRef.value.input.blur()
    } else {
        showHandler()
    }
}

const showHandler = () => {
    clearTimeout(timeout)
    showOption.value = true
    vmRef.value.input.focus()
}

let timeout
const blurHandler = () =>
    (timeout = setTimeout(() => {
        showOption.value = false
        clickCount = 0
    }, 16))

defineExpose({
    vmRef,
    animationRef: {
        changeShow(show) {
            showOption.value = show
        },
    },
})
</script>
