<template>
   <div class="input-container">
       <input
           :disabled="disabled"
           :type="type"
           class="input-control"
           @blur="testError"
           :value="props.value"
           @input="input"
           @focus="emitFn('focus')"
           :class="{ 'is-invalid': inputRef.error }"
           :placeholder="placeholder"
           :style="{...inputStyle }"
       />
       <div v-if="inputRef.error" class="error-text" :style="{...inputStyle }">
           {{ inputRef.message }}
       </div>
   </div>
</template>

<script lang="ts" setup>
import { PropType, reactive } from "vue"
import { RuleProp } from "@types/index"
import { ruleStrategies } from "@/utils"
const emitFn = defineEmits(["update", "blur", "focus"])

const props = defineProps({
   type: {
      type: String,
      default: "text"
   },
   name: String,
   value: [String, Number, Boolean],
   placeholder: String,
   rules: Array as PropType<RuleProp[]>,
   inputStyle: Object,
   disabled: Boolean
})

// 响应式错误信息
const inputRef = reactive({
   error: false,
   message: ""
})

// 检查错误
const testError = () => {
   if (props.rules) {
      const allPassed = props.rules.every((rule: RuleProp) => {
         let passed = true
         inputRef.message = rule.message
         passed = ruleStrategies[rule.type](props.value)
         console.log("allPassed", props.value, ruleStrategies[rule.type])
         return passed
      })
      inputRef.error = !allPassed
   }
   emitFn("blur")
}

// 传回数据
const input = (e: Event) => {
   const targetValue = (e.target as HTMLInputElement).value
   emitFn("update", { name: props.name, value: targetValue })
}
</script>

<style lang="less">
.input-container {
  .input-control{
     padding: 4px 10px;
     border-radius: @smallRadius;
     border: 1px solid @borderColor;
     align-items: center;
     font-size: 1em;
     &:focus{
        border: 1px solid @activeColor;
        outline: 2px solid @mainColor;
     }
  }
  .error-text{
     padding:6px 0 0 1px;
     color:@danger;
     text-align:left;
  }
}
</style>
