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

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

interface Props {
  fieldName: string
  label?: string
  placeholder?: string
  hint?: string
  modelValue?: File | null
  accept?: string[]
  maxSizeMb?: number
  errors?: FormErrors
  class?: string
  isRequired?: boolean
  isDisabled?: boolean
  icons?: string
}

const props = withDefaults(defineProps<Props>(), {
  label: '',
  placeholder: 'Choose file...',
  maxSizeMb: 1,
  isDisabled: false,
  isRequired: false,
})

const emit = defineEmits<{
  (e: 'update:modelValue', value: File | null): void
  (e: 'fileSelected', file: File | null): void
}>()

const hintMsg = computed(() => {
  if (props.hint) return props.hint
  if (props.accept) {
    return `${props.accept.map((ext) => '.' + ext.replace(/^\./, '')).join(', ')}, maksimal ${props.maxSizeMb} MB`
  }
  return 'Gunakan file yang sesuai'
})

async function onFileChange(event: Event, handleChange: (value: any) => void) {
  const target = event.target as HTMLInputElement
  const file = target.files?.[0]

  if (!file) {
    handleChange(null)
    emit('update:modelValue', null)
    emit('fileSelected', null)
    return
  }

  // Validate file size
  const maxSizeBytes = props.maxSizeMb * 1024 * 1024
  if (file.size > maxSizeBytes) {
    console.warn(`File size exceeds ${props.maxSizeMb}MB limit`)
    handleChange(null)
    emit('update:modelValue', null)
    emit('fileSelected', null)
    return
  }

  handleChange(file)
  emit('update:modelValue', file)
  emit('fileSelected', file)
}
</script>

<template>
  <DE.Cell>
    <DE.Label
      v-if="label !== ''"
      :label-for="fieldName"
      :is-required="isRequired && !isDisabled"
    >
      {{ label }} ({{ hintMsg }})
    </DE.Label>
    <DE.Field
      :id="fieldName"
      :errors="errors"
    >
      <FormField
        v-slot="{ componentField, handleChange }"
        :name="fieldName"
      >
        <FormItem>
          <FormControl class="flex flex-col">
            <Input
              @change="onFileChange($event, handleChange)"
              type="file"
              :disabled="isDisabled"
              v-bind="{ onBlur: componentField.onBlur }"
              :placeholder="placeholder"
              :class="cn('focus:border-primary focus:ring-2 focus:ring-primary focus:ring-offset-0')"
            />
          </FormControl>
          <FormMessage />
        </FormItem>
      </FormField>
    </DE.Field>
  </DE.Cell>
</template>
