<template>
  <div :class="['form-item', half ? 'form-item-half' : '', elclass || '']">
    <span class="form-item-title" v-if="title !== undefined && title !== ''">
      {{ title }}
    </span>
    <slot name="input">
      <label>
        <span v-if="label !== undefined && label !== ''">
          {{ label }}
          <i v-if="required" class="form-item-alert">*</i>
        </span>
        <input
          :value="modelValue"
          :type="inputType"
          :placeholder="placeholder"
          :disabled="disabled"
          @input="OnInput"
          @click="OnClick"
          @change="OnChange"
          @focus="OnFocus"
          @keydown="OnKeyDown"
          @keyup="OnKeyUp"
          :class="[
            invalidText !== undefined && invalidText !== '' ? 'invalid' : '',
            iclass || '',
            isPasswordVisible || props.type === 'password' ? 'password-visible' : ''
          ]"
          :min="min"
          :max="max"
          :minlength="minlength"
          :maxlength="maxlength" />
        <i
          class="ico-c ico-password-visible"
          v-if="props.type === 'password'"
          @click="PasswordVisibleToggle">
          <svg>
            <use
              :href="
                '/src/assets/images/icons.svg#' + (isPasswordVisible ? 'eye' : 'eyeclose')
              "></use>
          </svg>
        </i>
        <span
          class="form-item-alert"
          v-if="InvalidMessages.length > 0 && InvalidMessages !== ''">
          {{ InvalidMessages }}
        </span>
        <span
          class="form-item-description"
          v-if="description !== undefined && description !== ''">
          {{ description }}
        </span>
      </label>
    </slot>
  </div>
</template>
<script setup lang="ts">
  import { ref, reactive, computed, watch } from 'vue'
  import { useValidationStore } from '@/stores/validationStore'
  const validationStore = useValidationStore()

  export interface Props {
    type?: string
    label?: string
    disabled?: boolean
    modelValue: number | string | null | undefined
    half?: boolean
    title?: string
    invalidText?: string
    description?: string
    placeholder?: string
    required?: boolean
    min?: string | number
    max?: string | number
    maxlength?: string | number
    minlength?: string | number
    iclass?: string
    elclass?: string
    modelKey?: string
  }
  const props = withDefaults(defineProps<Props>(), {
    type: 'text',
    disabled: false,
    half: false,
    required: false
  })

  const emit = defineEmits([
    'update:modelValue',
    'change',
    'input',
    'focus',
    'click',
    'keydown',
    'keyup'
  ])
  const isPasswordVisible = ref<boolean>(false)
  const InvalidMessageText = reactive<Record<string, any>>({})

  const inputType = computed(() => {
    if (props.type !== 'password') {
      return props.type
    } else {
      if (isPasswordVisible.value) return 'text'
      else return 'password'
    }
  })

  const InvalidMessages = computed<string>(() => {
    let text = ''
    Object.keys(InvalidMessageText).forEach((k: string, i: number) => {
      text += InvalidMessageText[k] + ', '
    })
    return text
  })

  const OnChange = (e: Event) => {
    emit('update:modelValue', (e.target as HTMLInputElement).value)
    emit('change', e)
  }
  const OnInput = (e: Event) => {
    emit('update:modelValue', (e.target as HTMLInputElement).value)
    emit('input', e)
  }
  const OnFocus = (e: Event) => {
    emit('focus', e)
  }
  const OnClick = (e: Event) => {
    emit('click', e)
  }
  const OnKeyDown = (e: Event) => {
    emit('update:modelValue', (e.target as HTMLInputElement).value)
    emit('keydown', e)
  }
  const OnKeyUp = (e: Event) => {
    if (props.minlength !== undefined) {
      if ((e.target as HTMLInputElement).value.length < Number(props.minlength)) {
        InvalidMessageText.minlength = `Girdiğiniz bilgi en az ${props.minlength} karakter uzunluğunda olmalı`
      } else {
        delete InvalidMessageText.minlength
      }
    }

    if (props.required) {
      if ((e.target as HTMLInputElement).value.length < 1) {
        InvalidMessageText[props.modelKey + 'Empty'] = 'Bu alan boş bırakılamaz'
      } else {
        delete InvalidMessageText[props.modelKey + 'Empty']
      }
    }

    if (props.type === 'email') {
      if (!validationStore.checkEmail((e.target as HTMLInputElement).value))
        InvalidMessageText.validmail =
          'Lütfen e-postayı doğru formatta giriniz. Örn: isim@alanadi.td'
      else delete InvalidMessageText.validmail
    }

    emit('update:modelValue', (e.target as HTMLInputElement).value)
    emit('keyup', e)
  }
  const PasswordVisibleToggle = () => {
    if (props.type === 'password') isPasswordVisible.value = !isPasswordVisible.value
  }
  watch(
    () => props.invalidText,
    () => {
      if (props.invalidText !== undefined && props.invalidText !== '') {
        Object.assign(InvalidMessageText, {})
        InvalidMessageText.invalid = props.invalidText
      } else {
        delete InvalidMessageText.invalid
      }
    }
  )
</script>
<style scoped>
  .ico-password-visible {
    position: absolute;
    right: 8px;
    top: 32px;
    min-width: 32px;
    min-height: 32px;
    cursor: pointer;
  }
  .password-visible {
    padding: 8px 40px 8px 8px;
  }
</style>
