<script lang="ts">
export default {
  name: "LayInput",
};
</script>

<script setup lang="ts">
import "./index.less";
import { LayIcon } from "@layui/icons-vue";
import { computed, ref, useSlots, watch } from "vue";
import PasswordIcon from "./svg/Password.vue";
import UnPasswordIcon from "./svg/unPassword.vue";
import { InputSize } from "./interface";

export interface InputProps {
  name?: string;
  type?: string;
  prefixIcon?: string;
  suffixIcon?: string;
  modelValue?: string | number | string[] | undefined;
  allowClear?: boolean;
  autocomplete?: string;
  placeholder?: string;
  autofocus?: boolean;
  disabled?: boolean;
  readonly?: boolean;
  password?: boolean;
  size?: InputSize;
  maxlength?: number;
  max?: number;
  min?: number;
  qfw?: boolean;
}

const props = withDefaults(defineProps<InputProps>(), {
  disabled: false,
  readonly: false,
  allowClear: false,
  autofocus: false,
  password: false,
  modelValue: "",
  size: "md",
  qfw: false
});

interface InputEmits {
  (e: "blur", event: Event): void;
  (e: "input", value: string): void;
  (e: "update:modelValue", value: string): void;
  (e: "change", value: string): void;
  (e: "focus", event: Event): void;
  (e: "clear"): void;
}

const emit = defineEmits<InputEmits>();

const slots = useSlots();
const type = ref(props.type);
const currentValue = ref<string>(
  String(props.modelValue == null ? "" : props.modelValue)
);
const hasContent = computed(() => (props.modelValue as string)?.length > 0);
const isPassword = computed(() => type.value == "password");
const composing = ref(false);

const formatMoney = function (s: string) {
  var noNegative = true;
  s = parseFloat((s + "").replace(/[^\d\.-]/g, "")) + "";
  if (parseFloat(s) < 0) {
    s = Math.abs(s) + "";
    noNegative = false;
  }

  var l = s.split(".")[0].split("").reverse(),
    r = s.split(".")[1];
  var t = "";
  for (let i = 0; i < l.length; i++) {
    if (i % 3 == 2 && i != l.length - 1) {
      t += l[i] + ",";
    } else {
      t += l[i] + ""; //加上空格
    }
  }
  let z:any = (noNegative ? "" : "-") + t.split("").reverse().join("")
  z = isNaN(z) ? 0 : z
  if(r){
    return  z+ "." + r;

  }else{
    return z
  }
}

watch(
  () => props.type,
  () => {
    type.value = props.type;
  }
);
const input:any = ref<Element>()

watch(
  () => props.modelValue,
  () => {
    console.log(input)
    if(!(input.value == document.activeElement) && props.qfw){
      currentValue.value = formatMoney(props.modelValue.toString());
      return
    }
    currentValue.value = String(
      props.modelValue == null ? "" : props.modelValue
    );
  }
);

const onInput = function (event: Event) {
  const inputElement = event.target as HTMLInputElement;
  let value = inputElement.value;
  emit("input", value);
  if (composing.value) return;
  if (props.qfw) {
    value = value.replace(/,/g, "")
  }
  emit("update:modelValue", value);
};

const onClear = () => {
  emit("update:modelValue", "");
  emit("clear");
};

const onFocus = (event: Event) => {
  currentValue.value = new String(props.modelValue).replace(/,/g, "")
  emit("focus", event);
};

const onChange = (event: Event) => {
  const inputElement = event.target as HTMLInputElement;
  let value = inputElement.value;
  if (props.qfw) {
    value = value.replace(/,/g, "")
  }
  emit("change", value);
};

const onBlur = (event: Event) => {
  if (props.type === "number") {
    onNumberBlur(event);
  }
  if (props.qfw) {

    try {
      let reg = /\d{1,3}(?=(\d{3})+$)/g;
      // new String(props.modelValue).replace(reg, '$&,');
      console.log("添加，", formatMoney(props.modelValue.toString()))
      currentValue.value = formatMoney(props.modelValue.toString());
    } catch {
      currentValue.value = "输入错误"
    }
  }


  emit("blur", event);
};

const onNumberBlur = (event: Event) => {
  let value = (event.target as HTMLInputElement).value;
  if (value === "") {
    value = props.min ? String(props.min) : "0";
  } else {
    if (props.max && props.max < Number(value)) value = props.max.toString();
    if (props.min && props.min > Number(value)) value = props.min.toString();
  }
  if (props.qfw) {
    value = value.replace(/,/g, "")
  }
  emit("update:modelValue", value);
};

const onCompositionstart = () => {
  composing.value = true;
};

const onCompositionend = (event: Event) => {
  composing.value = false;
  onInput(event);
};

const classes = computed(() => {
  return {
    "layui-input-disabled": props.disabled,
    "layui-input-has-prefix": slots.prefix || props.prefixIcon,
  };
});

const showPassword = () => {
  if (isPassword.value) {
    type.value = "text";
  } else {
    type.value = "password";
  }
};
</script>

<template>
  <div class="layui-input" :class="classes" :size="size">
    <div class="layui-input-prepend" v-if="slots.prepend">
      <slot name="prepend"></slot>
    </div>
    <div class="layui-input-wrapper">
      <span class="layui-input-prefix" v-if="slots.prefix || props.prefixIcon">
        <slot name="prefix" v-if="slots.prefix"></slot>
        <lay-icon v-else :type="props.prefixIcon" class="layui-input-prefix-icon"></lay-icon>
      </span>
      <input :type="type" :name="name" :disabled="disabled" :placeholder="placeholder" :autofocus="autofocus"
        :autocomplete="autocomplete" :maxlength="maxlength" :max="max" :min="min" :readonly="readonly"
        :value="currentValue" @input="onInput" @change="onChange" @focus="onFocus" @blur="onBlur"
        @compositionstart="onCompositionstart" @compositionend="onCompositionend" ref="input" />
      <span class="layui-input-password" @click="showPassword" v-if="password && hasContent">
        <password-icon v-if="isPassword"></password-icon>
        <un-password-icon v-else></un-password-icon>
      </span>
      <span class="layui-input-clear" v-if="allowClear && hasContent && !disabled">
        <lay-icon type="layui-icon-close-fill" @click.stop="onClear"></lay-icon>
      </span>
      <span class="layui-input-suffix" v-if="slots.suffix || props.suffixIcon">
        <slot name="suffix" v-if="slots.suffix"></slot>
        <lay-icon v-else :type="props.suffixIcon" class="layui-input-suffix-icon"></lay-icon>
      </span>
    </div>
    <div class="layui-input-append" v-if="slots.append">
      <slot name="append"></slot>
    </div>
  </div>
</template>
