<template>
    <UItext
        :disabled="props.disabled"
        class="select ready"
        :class="{
            focus: showOption,
            [className]: className,
        }"
        ref="vmRef"
        :modelValue="typeof labelValue === 'string' ? labelValue : inputValue"
        @update:modelValue="val => emit('update:modelValue', val)"
        :width="props.width"
        :height="props.height"
        :readonly="readonly"
        :placeholder="props.placeholder"
        @blur="blurHandler"
        @focus="showHandler"
        @click="clickShowHandler"
    >
        <template v-slot:icon>
            <icon type="pull-down" small v-if="!$slots.icon" />
            <slot name="icon" v-else />
        </template>
        <template v-slot:preIcon v-if="$slots.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">
            <ul>
                <li
                    v-if="props.options.length"
                    v-for="option in props.options"
                    :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>
            </ul>
        </div>
    </UIFloating>
</template>

<script setup>
import UItext from './text.vue'
import UIFloating from '../floating/index.vue'
import { ref, onUnmounted, computed, defineExpose, watchEffect } from 'vue'
import { selectPropsDesc } from './state'
import icon from '../icon'

const props = defineProps({
    ...selectPropsDesc,
    readonly: {
        type: Boolean,
        default: true,
    },
    className: {
        type: String,
    },
    labelValue: {
        type: String,
        require: false,
    },
    dbhide: {
        type: Boolean,
        default: true,
    },
})
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>
