<template>
  <div class="space-y-4">
    <!-- Upload Area -->
    <div>
      <UFileUpload
        v-model="selectedFiles"
        :accept="allowedFileTypes"
        :multiple="true"
        :disabled="isUploading || disabled"
        :label="t('applicationForms.formElements.fileUpload.label')"
        :description="t('applicationForms.formElements.fileUpload.allowedTypes')"
        variant="area"
        layout="list"
        position="inside"
        @change="handleFileSelect"
      />
    </div>

    <!-- Upload Progress -->
    <div v-if="isUploading" class="space-y-2">
      <UProgress :value="uploadProgress" />
      <p class="text-sm text-gray-600">
        {{ t('applicationForms.formElements.fileUpload.uploading') }}
      </p>
    </div>

    <!-- Error Message -->
    <UAlert
      v-if="errorMessage"
      color="error"
      variant="soft"
      :title="t('applicationForms.formElements.fileUpload.uploadError')"
      :description="errorMessage"
      :close-button="{ icon: 'i-ph-x', color: 'red', variant: 'link' }"
      @close="errorMessage = ''"
    />

    <!-- Uploaded Files List -->
    <div v-if="uploadedFiles.length > 0" class="space-y-2">
      <p class="text-sm font-medium">
        {{ t('applicationForms.formElements.fileUpload.uploadedFiles') }}
      </p>
      <div class="space-y-2">
        <div
          v-for="file in uploadedFiles"
          :key="file.fileId"
          class="flex items-center justify-between p-3 bg-gray-50 rounded-lg"
        >
          <div class="flex items-center gap-3 flex-1 min-w-0">
            <UIcon :name="getFileIcon(file.mimeType)" class="text-xl flex-shrink-0" />
            <div class="flex-1 min-w-0">
              <p class="text-sm font-medium truncate">{{ file.filename }}</p>
              <p class="text-xs text-gray-500">{{ formatFileSize(file.size) }}</p>
            </div>
          </div>
          <div class="flex items-center gap-2 flex-shrink-0">
            <UButton
              v-if="isViewableInBrowser(file.mimeType)"
              icon="i-ph-eye"
              color="neutral"
              variant="ghost"
              size="sm"
              :title="t('applicationForms.formElements.fileUpload.view')"
              @click="viewFile(file.fileId)"
            />
            <UButton
              icon="i-ph-download"
              color="info"
              variant="ghost"
              size="sm"
              :disabled="isDownloading"
              @click="downloadFile(file.fileId, file.filename)"
            />
            <UButton
              icon="i-ph-trash"
              color="error"
              variant="ghost"
              size="sm"
              :disabled="disabled || isDeleting"
              @click="deleteFile(file.fileId)"
            />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { EmployeeDataCategory, type FormOptionDto, ProcessingPurpose } from '~~/.api-client'
import { useFile, type UploadedFileMetadata } from '~/composables/file/useFile'
import { useUserStore } from '~~/stores/useUserStore'

const props = defineProps<{
  formOptions: FormOptionDto[]
  disabled?: boolean
  applicationFormId?: string
  formElementReference?: string
}>()

const emit = defineEmits<{
  (e: 'update:formOptions', value: FormOptionDto[]): void
}>()

const { t } = useI18n()
const {
  uploadFile: uploadFileApi,
  downloadFile: downloadFileApi,
  viewFile: viewFileApi,
  deleteFile: deleteFileApi,
  parseUploadedFiles,
  createFileMetadata,
  getFileIcon,
  formatFileSize,
  isViewableInBrowser
} = useFile()

const isUploading = ref(false)
const isDownloading = ref(false)
const isDeleting = ref(false)
const uploadProgress = ref(0)
const errorMessage = ref('')
const selectedFiles = ref<File[] | null>(null)

const allowedFileTypes = '.pdf,.docx,.doc,.odt,.jpg,.jpeg,.png,.zip'

// Parse uploaded files from formOptions
const uploadedFiles = computed<UploadedFileMetadata[]>(() => {
  const values = props.formOptions.map((option) => option.value)
  return parseUploadedFiles(values)
})

const userStore = useUserStore()
const organizationId = computed(() => userStore.selectedOrganization?.id)

const handleFileSelect = async () => {
  if (!selectedFiles.value || selectedFiles.value.length === 0) return

  const files = Array.isArray(selectedFiles.value) ? selectedFiles.value : [selectedFiles.value]
  errorMessage.value = ''

  for (const file of files) {
    const maxFileSize = 10 * 1024 * 1024 // 10 MB
    if (file.size > maxFileSize) {
      errorMessage.value = t('applicationForms.formElements.fileUpload.fileTooLarge', {
        filename: file.name,
        maxSize: formatFileSize(maxFileSize)
      })
      continue
    }

    await uploadFile(file)
  }

  selectedFiles.value = null
}

const uploadFile = async (file: File) => {
  if (!props.formElementReference) {
    errorMessage.value = 'Missing required context: formElementReference'
    return
  }

  isUploading.value = true
  uploadProgress.value = 0

  try {
    const response = await uploadFileApi({
      file,
      applicationFormId: props.applicationFormId,
      formElementReference: props.formElementReference,
      organizationId: organizationId.value
    })

    const metadata = createFileMetadata(response)

    const newOption: FormOptionDto = {
      value: JSON.stringify(metadata),
      label: props.formElementReference,
      processingPurpose: props.formOptions[0]?.processingPurpose ?? ProcessingPurpose.None,
      employeeDataCategory: props.formOptions[0]?.employeeDataCategory ?? EmployeeDataCategory.None
    }

    const updatedOptions = [...props.formOptions, newOption]
    emit('update:formOptions', updatedOptions)

    uploadProgress.value = 100
  } catch (error: unknown) {
    errorMessage.value = error instanceof Error ? error.message : String(error)
  } finally {
    isUploading.value = false
    uploadProgress.value = 0
  }
}

const downloadFile = async (fileId: string, filename: string) => {
  isDownloading.value = true
  try {
    await downloadFileApi(fileId, filename)
  } catch (error: unknown) {
    errorMessage.value = error instanceof Error ? error.message : String(error)
  } finally {
    isDownloading.value = false
  }
}

const viewFile = (fileId: string) => {
  viewFileApi(fileId)
}

const deleteFile = async (fileId: string) => {
  if (!confirm(t('common.confirmDelete'))) return

  isDeleting.value = true
  try {
    await deleteFileApi(fileId)

    // Remove from formOptions
    const updatedOptions = props.formOptions.filter((option) => {
      try {
        const metadata = JSON.parse(option.value) as UploadedFileMetadata
        return metadata.fileId !== fileId
      } catch {
        return true
      }
    })
    emit('update:formOptions', updatedOptions)
  } catch (error: unknown) {
    errorMessage.value = error instanceof Error ? error.message : String(error)
  } finally {
    isDeleting.value = false
  }
}
</script>
