<template>
  <div
    class="pui-input"
    :class="[
      size,
      state,
      {
        'has-icon': icon,
        'has-hint': hint,
        'has-label': label,
        'has-action': (clearable && computedValue && !disabled) || passwordReveal,
        'filled': isFilled,
        'focused': isFocused,
        'is-required': required
      }
    ]"
    :disabled="disabled"
  >
    <p-icon v-if="icon" :size="size" :icon="icon" />
    <span class="label" v-if="label">{{ label }}</span>
    <input
      ref="input"
      :type="newType"
      :maxlength="maxlength"
      :autocomplete="autocomplete"
      :value="computedValue"
      :placeholder="computedPlaceholder"
      v-bind="$attrs"
      :disabled="disabled"
      @input="onInput"
      @change="onChange"
      @blur="onBlur"
      @focus="onFocus"
    />
    <p-tooltip 
      class="hint" 
      v-if="hint"
      :label="hint"
      position="is-top"
      :width="tooltipWidth"
      :is-multiline="hint.length > 80"
      trigger="hover"
    >
      <i class="mdi mdi-information-outline"></i>
    </p-tooltip>
    <div class="action-trigger" v-if="clearable && computedValue && !disabled" @click="clear">
      <i class="mdi mdi-close"></i>
    </div>
    <div
      class="action-trigger" 
      v-else-if="passwordReveal" 
      @click="togglePasswordVisibility"
    >
      <i class="mdi" :class="[passwordVisibleIcon]"></i>
    </div>
  </div>
</template>

<script>
import Inputmask from "inputmask";

export default {
  name: "PInput",
  props: {
    value: [Number, String],
    type: {
      type: String,
      default: "text",
    },
    required: Boolean,
    size: String,
    state: String,
    icon: String,
    label: String,
    placeholder: String,
    passwordReveal: Boolean,
    clearable: Boolean,
    maxlength: String,
    autocomplete: String,
    disabled: Boolean,
    hint: String,
    mask: String
  },
  data() {
    return {
      newValue: this.value,
      newType: this.type,
      isPasswordVisible: false,
      isFocused: false,
    };
  },
  methods: {
    onInput(event) {
      const value = event.target.value;
      this.updateValue(value);
    },
    onChange(event) {
      const value = event.target.value;
      this.updateValue(value);
    },
    onFocus() {
      this.isFocused = true;
      this.$emit("focus");
    },
    onBlur() {
      this.isFocused = false;
      this.$emit("blur");
    },
    clear() {
      this.updateValue('')
      
      this.$nextTick(() => {
          this.$refs.input.focus()
      })
    },
    togglePasswordVisibility() {
      this.isPasswordVisible = !this.isPasswordVisible
      this.newType = this.isPasswordVisible ? 'text' : 'password'

      this.$nextTick(() => {
          this.$refs.input.focus()
      })
    },
    updateValue(value) {
      this.computedValue = value;
    },
  },
  mounted() {
    if(this.mask) {
      let im = new Inputmask(this.mask);
      im.mask(this.$refs.input);
    }
  },
  computed: {
    isFilled() {
      return (
        this.computedValue !== null &&
        this.computedValue !== undefined &&
        this.computedValue !== ''
      )
    },
    computedPlaceholder() {
      return (this.isFocused || !this.label) ? this.placeholder : null
    },
    computedValue: {
      get() {
        return this.newValue;
      },
      set(value) {
        this.newValue = value;
        this.$emit("input", value);
      },
    },
    passwordVisibleIcon() {
        return !this.isPasswordVisible ? 'mdi-eye-outline' : 'mdi-eye-off-outline'
    },
    tooltipWidth() {
      return (typeof this.hint === 'string' && this.hint.length > 80) ? 200 : 'auto'
    }
  },
  watch: {
    value(value) {
      this.newValue = value;
    }
  },
};
</script>