<template>
    <UIText
        class="number ready"
        :class="{ ctrl }"
        type="number"
        :right="right"
        :model-value="tempValue"
        :placeholder="placeholder"
        :other="{ min, max, step }"
        :readonly="!inInput"
        @update:model-value="updateTempValue"
        @blur="blurHandler"
    >
        <template v-for="(slot, name) in $slots" #[name]="raw">
            <slot :name="name" v-bind="raw" />
        </template>
        <template v-if="ctrl" #icon>
            <div class="ctrls">
                <UIIcon type="up-a" ctrl class="up" @click="updateModelValue(normValue(modelValue) + step)" />
                <UIIcon type="d-r" ctrl class="down" @click="updateModelValue(normValue(modelValue) - step)" />
            </div>
        </template>
    </UIText>
</template>

<script setup lang="ts">
import { defineEmits, defineProps, ref, watchEffect } from 'vue'
import { toRawType } from '@kankan/utils'
import UIIcon from '@kankan/components/basic/icon'
import UIText from '../text/text.vue'
import { numberProps } from './number'

const emit = defineEmits(['update:modelValue'])
const props = defineProps(numberProps)

const isNumber = raw => !(toRawType(raw) === 'Number' ? Number.isNaN(raw) : Number.isNaN(Number(raw)))
const tempValue = ref(props.modelValue)

watchEffect(() => {
    tempValue.value = props.modelValue
})
const updateTempValue = val => {
    tempValue.value = val
    const tval = Number(val)
    if (!Number.isNaN(tval) && tval !== props.modelValue) {
        updateModelValue(tval)
    }
}

const blurHandler = () => {
    tempValue.value = props.modelValue
    updateModelValue(props.modelValue)
}

const normValue = val => {
    val = Number(val)
    if (Number.isNaN(val)) {
        return props.min || 0
    } else {
        return val
    }
}

const updateModelValue = val => {
    val = normValue(val)
    if (isNumber(props.min)) {
        const min = Number(props.min)
        val = val < min ? min : val
    }
    if (isNumber(props.max)) {
        const max = Number(props.max)
        val = val > max ? max : val
    }
    emit('update:modelValue', val)
}
</script>
