<template>
  <view :class="inputClass" :style="inputStyle">
    <view :class="bem.e('content')">
      <view v-if="$slots.prepend" :class="bem.e('prepend')">
        <slot name="prepend"></slot>
      </view>
      <textarea
        v-if="type === 'textarea'"
        :class="classNames(bem.e('control'), bem.em('control', 'textarea'))"
        :value="innerValue"
        :placeholder="placeholder"
        :placeholder-style="placeholderStyle"
        :placeholder-class="classNames(bem.e('placeholder'), placeholderClass)"
        :disabled="isDisabled || isReadonly"
        :maxlength="maxlength"
        :focus="focus"
        :cursor-spacing="cursorSpacing"
        :cursor="cursor"
        :confirm-type="confirmType"
        :confirm-hold="confirmHold"
        :selection-start="selectionStart"
        :selection-end="selectionEnd"
        :adjust-position="adjustPosition"
        :hold-keyboard="holdKeyboard"
        :auto-blur="autoBlur"
        :ignore-composition-event="ignoreCompositionEvent"
        :inputmode="inputmode"
        autocomplete="off"
        :fixed="fixed"
        :show-confirm-bar="showConfirmBar"
        :disable-default-padding="disableDefaultPadding"
        @input="onInput"
        @focus="onFocus"
        @blur="onBlur"
        @linechange="onLinechange"
        @confirm="onConfirm"
        @keyboardheightchange="onKeyboardheightchange"
        :auto-height="autoHeight"
        :style="controlStyle"
      />
      <input
        v-else
        :class="classNames(bem.e('control'), bem.em('control', 'input'))"
        :value="innerValue"
        :placeholder="placeholder"
        :placeholder-style="placeholderStyle"
        :placeholder-class="classNames(bem.e('placeholder'), placeholderClass)"
        :disabled="isDisabled || isReadonly"
        :maxlength="maxlength"
        :focus="focus"
        :cursor-spacing="cursorSpacing"
        :cursor="cursor"
        :confirm-type="confirmType"
        :confirm-hold="confirmHold"
        :selection-start="selectionStart"
        :selection-end="selectionEnd"
        :adjust-position="adjustPosition"
        :hold-keyboard="holdKeyboard"
        :auto-blur="autoBlur"
        :ignore-composition-event="ignoreCompositionEvent"
        :inputmode="inputmode"
        autocomplete="off"
        @input="onInput"
        @focus="onFocus"
        @blur="onBlur"
        @confirm="onConfirm"
        @keyboardheightchange="onKeyboardheightchange"
        :type="type"
        :password="type === 'password'"
        :always-embed="alwaysEmbed"
        :safe-password-cert-path="safePasswordCertPath"
        :safe-password-length="safePasswordLength"
        :safe-password-time-stamp="safePasswordTimeStamp"
        :safe-password-nonce="safePasswordNonce"
        :safe-password-salt="safePasswordSalt"
        :safe-password-custom-hash="safePasswordCustomHash"
        :random-number="randomNumber"
        :controlled="controlled"
        :always-system="alwaysSystem"
      />
      <view
        v-show="clearVisible"
        :class="bem.e('clear')"
        @click.stop="onClearClick"
        @mousedown="onClearMouseDown"
        @touchstart="onClearTouchStart"
        @touchend="onClearTouchEnd"
        @touchcancel="onClearTouchEnd"
      >
        <sar-icon name="x-circle-fill" />
      </view>
      <view v-if="$slots.append" :class="bem.e('append')">
        <slot name="append"></slot>
      </view>
      <slot name="addon"></slot>
    </view>
    <view v-if="showCount" :class="bem.e('count')">
      {{ String(innerValue).length }} / {{ maxlength }}
    </view>
  </view>
</template>

<script lang="ts">
import { defineComponent as _defineComponent } from "vue";
import { computed, ref, watch } from "vue";
import { classNames, stringifyStyle, createBem } from "../utils";
import SarIcon from "../icon/icon.vue";
import { useFormContext, useFormItemContext } from "../form/common";
import { inputProps } from "./common";
const __default__ = {
  options: {
    virtualHost: true,
    styleIsolation: "shared"
  }
};
export default /* @__PURE__ */ _defineComponent({
  ...__default__,
  __name: "input",
  props: inputProps,
  emits: [
    "update:model-value",
    "clear",
    "focus",
    "blur",
    "linechange",
    "confirm",
    "keyboardheightchange"
  ],
  setup(__props, { expose: __expose, emit: __emit }) {
    __expose();
    const props = __props;
    const emit = __emit;
    const bem = createBem("input");
    const formContext = useFormContext();
    const formItemContext = useFormItemContext();
    const isDisabled = computed(() => {
      return formContext?.disabled ?? props.disabled;
    });
    const isReadonly = computed(() => {
      return formContext?.readonly ?? props.readonly;
    });
    const innerValue = ref(props.modelValue);
    const setInnerValue = (value) => {
      innerValue.value = value;
      emit("update:model-value", value);
    };
    watch(
      () => props.modelValue,
      () => {
        innerValue.value = props.modelValue ?? "";
        if (props.validateEvent) {
          formItemContext?.onChange();
        }
      }
    );
    const onInput = (event) => {
      const value = event.detail.value;
      setInnerValue(value);
      return value;
    };
    const innerFocused = ref(props.focus || props.focused);
    watch([() => props.focus, () => props.focused], () => {
      innerFocused.value = props.focus || props.focused;
    });
    const onFocus = (event) => {
      innerFocused.value = true;
      emit("focus", event);
    };
    const onBlur = (event) => {
      innerFocused.value = false;
      emit("blur", event);
      if (props.validateEvent) {
        formItemContext?.onBlur();
      }
    };
    const clearVisible = computed(() => {
      const visibleBase = props.clearable && innerValue.value && !isDisabled.value && !isReadonly.value;
      return props.showClearOnlyFocus ? holdupClear.value || innerFocused.value && visibleBase : visibleBase;
    });
    const holdupClear = ref(false);
    const onClearTouchStart = () => {
      holdupClear.value = true;
    };
    const onClearTouchEnd = () => {
      holdupClear.value = false;
    };
    const onClearMouseDown = () => {
      onClearTouchStart();
      const upHandler = () => {
        onClearTouchEnd();
        document.removeEventListener("mouseup", upHandler);
      };
      document.addEventListener("mouseup", upHandler);
    };
    const onClearClick = () => {
      setInnerValue("");
      emit("clear");
    };
    const onLinechange = (event) => {
      emit("linechange", event);
    };
    const onConfirm = (event) => {
      emit("confirm", event);
    };
    const onKeyboardheightchange = (event) => {
      emit("keyboardheightchange", event);
    };
    const inputClass = computed(() => {
      return classNames(
        bem.b(),
        bem.m("inlaid", props.inlaid),
        bem.m("borderless", props.borderless),
        bem.m("disabled", isDisabled.value),
        bem.m("readonly", isReadonly.value),
        bem.m("focused", innerFocused.value),
        props.rootClass
      );
    });
    const inputStyle = computed(() => {
      return stringifyStyle(props.rootStyle);
    });
    const controlStyle = computed(() => {
      return stringifyStyle({
        minHeight: props.minHeight,
        height: !props.autoHeight && props.minHeight
      });
    });
    const __returned__ = { props, emit, bem, formContext, formItemContext, isDisabled, isReadonly, innerValue, setInnerValue, onInput, innerFocused, onFocus, onBlur, clearVisible, holdupClear, onClearTouchStart, onClearTouchEnd, onClearMouseDown, onClearClick, onLinechange, onConfirm, onKeyboardheightchange, inputClass, inputStyle, controlStyle, get classNames() {
      return classNames;
    }, SarIcon };
    return __returned__;
  }
});
</script>

<style lang="scss">
@use './index.scss';
</style>