<script setup lang="ts">
import type { FormErrors } from '~/types/error'
import { Input } from '~/components/pub/ui/input'
import { cn } from '~/lib/utils'
import { computed } from 'vue'
import { useFieldError } from 'vee-validate'

import * as DE from '~/components/pub/my-ui/doc-entry'

type InputType = 'text' | 'number' | 'password' | 'email' | 'date' | 'time' | 'datetime-local' | 'search' | 'tel'

const props = defineProps<{
  fieldName: string
  placeholder: string
  label?: string
  errors?: FormErrors
  class?: string
  colSpan?: number
  numericOnly?: boolean
  maxLength?: number
  isRequired?: boolean
  isDisabled?: boolean
  rightLabel?: string
  bottomLabel?: string
  suffixMsg?: string
  iconName?: string
  inputType?: InputType
}>()

const { class: containerClass } = props

function handleInput(event: Event) {
  const target = event.target as HTMLInputElement
  let value = target.value

  // Filter numeric only jika diperlukan
  if (props.numericOnly) {
    value = value.replace(/\D/g, '')
  }

  // Batasi panjang maksimal jika diperlukan
  if (props.maxLength && value.length > props.maxLength) {
    value = value.slice(0, props.maxLength)
  }

  // Update value jika ada perubahan
  if (target.value !== value) {
    target.value = value
    // Trigger input event untuk update form
    target.dispatchEvent(new Event('input', { bubbles: true }))
  }
}

// Get error state from vee-validate
const fieldError = useFieldError(() => props.fieldName)
const hasError = computed(() => !!fieldError.value)
</script>

<template>
  <DE.Cell :col-span="colSpan || 1">
    <DE.Label
      v-if="label"
      :label-for="fieldName"
      :is-required="isRequired && !isDisabled"
    >
      {{ label }}
    </DE.Label>
    <DE.Field
      :id="fieldName"
      :errors="errors"
    >
      <FormField
        v-slot="{ componentField }"
        :name="fieldName"
      >
        <FormItem>
          <FormControl :class="cn('relative', containerClass)">
            <div class="relative w-full max-w-sm items-center">
              <Input
                :disabled="isDisabled"
                v-bind="componentField"
                :placeholder="placeholder"
                :maxlength="maxLength"
                :class="cn(hasError && 'border-red-500 focus-visible:border-red-500 focus-visible:ring-red-500')"
                autocomplete="off"
                aria-autocomplete="none"
                autocorrect="off"
                autocapitalize="off"
                spellcheck="false"
                @input="handleInput"
                :type="inputType"
              />
              <span
                v-if="suffixMsg"
                class="absolute inset-y-0 end-0 flex items-center justify-center px-2 text-muted-foreground"
              >
                {{ suffixMsg }}
              </span>
              <Icon
                v-if="iconName"
                :name="iconName"
                class="absolute right-2 top-1/2 -translate-y-1/2 text-gray-500 dark:text-gray-400"
              />
              <p
                v-show="rightLabel"
                class="absolute right-3 top-0 text-gray-400"
              >
                {{ rightLabel }}
              </p>
            </div>
          </FormControl>
          <FormMessage />
        </FormItem>
      </FormField>
    </DE.Field>
    <p
      v-show="bottomLabel"
      class="text-gray-400"
    >
      {{ bottomLabel }}
    </p>
  </DE.Cell>
</template>
