<template>
    <div :class="{ 'disabled': disabled }">
      <ul class="ipAdress">
        <li v-for="(item, index) in ipAddress" :key="index">
          <input :ref="el => getInputRef(el, index)" v-model="item.value" type="text" class="ipInputClass"
            :disabled="disabled" @input="checkIpVal(item)" @keyup="$event => turnIpPosition(item, index, $event)"
            @blur="handleBlur" @mouseup="handleMouseUp(index)" />
          <div></div>
        </li>
      </ul>
    </div>
  </template>
  
  <script lang="ts" setup name="routePage">
  import { ref, watch } from 'vue'
  
  // 接收来自上层的数据
  const props = defineProps(['value', 'disabled'])
  
  // 更新数据
  const $emits = defineEmits(['update:value', 'blur'])
  
  // 存储四个ref
  const ipInputRefs = ref<HTMLInputElement[]>([]);
  // 存储左右标识位
  let markFlag = ref([
    {
      left: false,
      right: false
    },
    {
      left: false,
      right: false
    },
    {
      left: false,
      right: false
    },
    {
      left: false,
      right: false
    }
  ])
  
  // 更新标识
  let flag = ref(false)
  
  // 鼠标点击
  const handleMouseUp = (index: any) => {
    let input = ipInputRefs.value[index]
    // 全为false
    markFlag.value.forEach(item => {
      item.left = false
      item.right = false
    })
    // 证明在开始阶段
    if (input.selectionStart == 0) {

      markFlag.value[index].left = true
    } else {
      markFlag.value[index].left = false
    }
    // 证明在结束
    if (input.selectionStart == (input.value || '').length) {
      markFlag.value[index].right = true
    } else {
      markFlag.value[index].right = false
    }
  }
  
  // 获取四个input refs
  const getInputRef = (el: any, index: number) => {
    if (el) {
      ipInputRefs.value[index] = el;
    }
  };
  // 声明IP存储类型
  interface IpType {
    value: string
  }
  // 定义要显示的四个ip
  let ipAddress = ref<IpType[]>([
    {
      value: "",
    },
    {
      value: "",
    },
    {
      value: "",
    },
    {
      value: "",
    },
  ])
  // 初始化显示数据
  const initShowData = () => {
    // 判断不合理行为
    if (props.value === '') {
      ipAddress.value.forEach(item => {
        item.value = ''
      })
    } else {
      let ipList = props.value.split('.')
      ipAddress.value.forEach((item: IpType, index: number) => {
        item.value = ipList[index]
      })
    }
  }
  
  // 检查ip输入
  const checkIpVal = (item: any) => {
    let val = item.value;
 
    // 处理非数字
    val = val.toString().replace(/[^0-9]/g, "");
    val = parseInt(val, 10);
    if (isNaN(val)) {
      val = "";
    } else {
      val = val < 0 ? 0 : val;
      if (val > 255) {
        // 判断val是几位数
        let num = (val + '').length
        if (num > 3) {
          val = parseInt((val + '').substring(0, 3))
        } else {
          val = 255
        }
      }
    }
    item.value = val;
   
  }
  
  // 判断光标左右移动位置
  const turnIpPosition = (item: IpType, index: number, event: any) => {
    let e = event || window.event;
    if (e.keyCode === 37) {
      // 左箭头向左跳转，左一不做任何措施
      if (index == 0) {
        return
      }
      if (e.currentTarget.selectionStart === 0) {
        if (markFlag.value[index].left) {
          handleFocus(index - 1, 'toLeft')
          markFlag.value[index].left = false
          markFlag.value[index].right = false
        } else {
        
          markFlag.value[index].left = true
        }
      } else {
        markFlag.value[index].right = false
        markFlag.value[index].left = false
      }
    } else if (e.keyCode == 39) {
      // 右箭头向右跳转，右一不做任何措施
      markFlag.value[index].left = false
      let start = e.currentTarget.selectionStart
      if (index != 3 && start === item.value.toString().length) {
        if (markFlag.value[index].right) {
          handleFocus(index + 1, 'toRight')
          markFlag.value[index].left = false
          markFlag.value[index].right = false
        } else {
          markFlag.value[index].right = true
        }
      } else {
        markFlag.value[index].right = false
      }
    } else if (e.keyCode === 8) {
      
      // 删除键把当前数据删除完毕后会跳转到前一个input，左一不做任何处理
      if (index !== 0 && e.currentTarget.selectionStart === 0) {
        if (markFlag.value[index].left) {
          ipInputRefs.value[index - 1].focus();
          markFlag.value[index].left = false
        } else {
          
          markFlag.value[index].left = true
        }
      }
    } else if (e.keyCode === 13 || e.keyCode === 32) {
     
      // 回车键、空格键、冒号均向右跳转，右一不做任何措施
      if (index !== 3) {
        ipInputRefs.value[index + 1].focus();
      }
    }
    else if (e.keyCode === 110 || e.keyCode === 190) {
      // 点 . 向右跳转，右一不做任何措施
  
      if (item.value == '') {
        return
      }
      if (index !== 3) {
        ipInputRefs.value[index + 1].select();
      }
    }
    else if (item.value.toString().length === 3) {
    
      // 满3位，光标自动向下一个文本框.
      if (index !== 3) {
        //ipInputRefs.value[index + 1].setSelectionRange(0, 0)
        ipInputRefs.value[index + 1].focus();
      }
    }
  }
  
  // 处理聚焦
  const handleFocus = (index: number, direction: string) => {
    // 设置当前位置为选中状态 toRight:从左边来的
    let input = ipInputRefs.value[index]
    input.focus()
    let value = input.value
    // null 左右全部设置为true,可以直接跳转
    if ((value || '').length == 0) {
      markFlag.value[index].right = true
      markFlag.value[index].left = true
    } else {
      if (direction == 'toRight') {
        // 可以直接跳回
      
        markFlag.value[index].left = true
        // 设置光标为左边第一个
        ipInputRefs.value[index].setSelectionRange(0, 0)
        // 设置上一个的右边标识为false
        markFlag.value[index - 1] && (markFlag.value[index - 1].right = false)
      } else {
        // 直接跳回
        markFlag.value[index].right = true
        // 设置后一个侧边为false
        markFlag.value[index + 1] && (markFlag.value[index + 1].left = false)
      }
    }
  }
  
  
  // 格式化补零方法
  const formatter = (val: string) => {
    let value = val.toString();
    if (value.length === 2) {
      value = "0" + value;
    } else if (value.length === 1) {
      value = "00" + value;
    } else if (value.length === 0) {
      value = "000";
    }
    return value;
  }
  
  // 监听数据变化,并初始化显示四个数据
  watch(() => props.value, () => {

    if(flag.value){
  
    }else{
      initShowData()
    }
  }, {
    immediate: true
  })
  
  // 监听ipAddress数据变化
  watch(ipAddress, () => {
    let str = "";
    for (const i in ipAddress.value) {
      str += formatter(ipAddress.value[i].value);
    }
    if (str === "000000000000") {
      str = "";
    } else {
      str = ipAddress.value.map(item => {
        if (item.value !== null) {
          return item.value + ''
        } else {
          return '0'
        }
      }).join(".")
    }
    $emits('update:value', str)
    flag.value = true
    setTimeout(() => {
      flag.value = false
    }, 100)
  }, {
    deep: true
  })
  
  const handleBlur = () => {
    $emits('blur')
  }
  
  </script>
  <style lang="scss" scoped>
  .disabled {
    cursor: not-allowed;
    background-color: #f5f7fa;
  
    .ipAdress {
      li {
        .ipInputClass {
          color: #c3c4cc;
          cursor: not-allowed;
        }
      }
    }
  }
  
  .ipAdress {
    display: flex;
    border: 1px solid #dcdfe6;
    border-radius: 4px;
    line-height: 40px;
    width: 100%;
    height: 35px;
    padding-inline-start: 0px;
    padding-left: 10px;
    padding-right: 20px;
    padding-top: 0px;
    padding-bottom: 0px;;
    box-sizing: border-box;
    margin: 0;
  }
  
  .ipAdress li {
    position: relative;
    margin: 0;
    list-style-type: none;
  }
  
  .ipInputClass {
    border: none;
    width: 50px;
    height: 23px;
    text-align: center;
    color: #606266;
    background: transparent;
  }
  
  .ipAdress li div {
    position: absolute;
    bottom: 12px;
    right: 0;
    border-radius: 50%;
    background: #b6b8bc;
    width: 2px;
    height: 2px;
  }
  
  /*只需要3个div*/
  .ipAdress li:last-child div {
    display: none;
  }
  
  /*取消掉默认的input focus状态*/
  .ipAdress input:focus {
    outline: none;
  }
  </style>
  
  