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

<script setup>
import UIText from './text'
import { numberPropsDesc } from './state'
import { defineProps, defineEmits, computed, watchEffect, ref } from 'vue'
import { toRawType } from '../../utils'
import Icon from '../icon'

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

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

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

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

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

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