<script lang="ts" setup>
import { computed, reactive, ref } from 'vue'
import * as select from '@zag-js/select'
import { RouterLink } from 'vue-router'
import { Box } from '@/components/ui/box'
import { Button } from '@/components/ui/button'
import { Field, FieldDescription, FieldError, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
import {
  SelectRoot,
  SelectControl,
  SelectTrigger,
  SelectValueText,
  SelectContent,
  SelectItemGroup,
  SelectItemGroupLabel,
  SelectItem,
  SelectItemText,
} from '@/components/ui/select'
import { Textarea } from '@/components/ui/textarea'
import { AlertRoot, AlertDescription, AlertTitle } from '@/components/ui/alert'
import { Lucide } from '@/components/ui/lucide'
import { getApiErrorMessage, getApiValidationErrors } from '@/core/utils/getApiErrorMessage'
import { HelpdeskFab } from '@/modules/feedback'
import { submitMembershipApplication, lookupMemberByIcNumber } from '../services/membership-application.service'
import { sanitizeIcNumberInput, sanitizeNameInput } from '@/utils/form-input.utils'
import type {
  MembershipApplicationFormState,
  MembershipApplicationHeirForm,
  MembershipApplicationReferenceForm,
} from '../types/membership-application.types'
import illustrationUrl from '@/assets/images/logo.svg'
import { EMPLOYERS } from '@/constants/employers'

const MAX_FILE_SIZE_MB = 10
const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024
const MIN_STOCK_MONTHLY_CONTRIBUTION = 50
const INITIAL_MANDATORY_STOCK_MONTHLY_CONTRIBUTION = 84
const MIN_FEE_MONTHLY_CONTRIBUTION = 30

const steps = [
  { id: 1, label: 'Maklumat Peribadi' },
  { id: 2, label: 'No. Telefon & Alamat' },
  { id: 3, label: 'Maklumat Pekerjaan' },
  { id: 4, label: 'Maklumat Penama' },
  { id: 5, label: 'Dokumen & Hantar' },
] as const

const currentStep = ref(1)
const loading = ref(false)
const submitted = ref(false)
const applicationNumber = ref('')
const errorMessage = ref('')
const fieldErrors = reactive<Record<string, string>>({})

type SelectOption = { label: string; value: string }

const GENDER_OPTIONS: SelectOption[] = [
  { label: 'Lelaki', value: 'Lelaki' },
  { label: 'Perempuan', value: 'Perempuan' },
]

const MARRIAGE_STATUS_OPTIONS: SelectOption[] = [
  { label: 'Belum Berkahwin', value: 'Belum Berkahwin' },
  { label: 'Berkahwin', value: 'Berkahwin' },
  { label: 'Bercerai', value: 'Bercerai' },
  { label: 'Balu', value: 'Balu' },
  { label: 'Duda', value: 'Duda' },
]

const RELATIONSHIP_OPTIONS: SelectOption[] = [
  { label: 'Isteri', value: 'Isteri' },
  { label: 'Suami', value: 'Suami' },
  { label: 'Anak', value: 'Anak' },
  { label: 'Bapa', value: 'Bapa' },
  { label: 'Ibu', value: 'Ibu' },
  { label: 'Orang Tua', value: 'Orang Tua' },
  { label: 'Saudara', value: 'Saudara' },
  { label: 'Lain-lain', value: 'Lain-lain' },
]

const EMPLOYER_OPTIONS: SelectOption[] = EMPLOYERS.map((employer) => ({
  label: employer.name,
  value: employer.name,
}))

function createSelectCollection(options: SelectOption[]) {
  return select.collection({
    items: options,
    itemToValue: (item) => item.label,
  })
}

function labelToApiValue(options: SelectOption[], label: string | undefined): string {
  if (!label) return ''
  return options.find((option) => option.label === label)?.value ?? ''
}

function apiValueToLabel(options: SelectOption[], value: string | undefined): string[] {
  if (!value) return []
  const option = options.find((item) => item.value === value)
  return option ? [option.label] : [value]
}

const genderCollection = createSelectCollection(GENDER_OPTIONS)
const marriageStatusCollection = createSelectCollection(MARRIAGE_STATUS_OPTIONS)
const relationshipCollection = createSelectCollection(RELATIONSHIP_OPTIONS)
const employerCollection = createSelectCollection(EMPLOYER_OPTIONS)

function getEmployerAddress(name: string): string {
  return EMPLOYERS.find((employer) => employer.name === name)?.address ?? ''
}

function createEmptyReference(): MembershipApplicationReferenceForm {
  return {
    ic_number: '',
    user_id: '',
    name: '',
  }
}

function createEmptyHeir(): MembershipApplicationHeirForm {
  return {
    name: '',
    ic_number: '',
    relationship: '',
    phone_number: '',
  }
}

const form = reactive<MembershipApplicationFormState>({
  applicant: {
    name: '',
    email: '',
    ic_number: '',
    birth_date: '',
    birth_place: '',
    gender: '',
    marriage_status: '',
    address: '',
    phone_number: '',
    office_number: '',
    postcode: '',
    employer_name: '',
    employer_address: '',
    current_position: '',
    start_work_date: '',
    stock_monthly_contribution: '',
    fee_monthly_contribution: '',
  },
  heirs: [createEmptyHeir()],
  references: {
    proposer: createEmptyReference(),
    supporter: createEmptyReference(),
  },
  documents: {
    ic_copy: null,
    photo: null,
    salary_slip: null,
    employer_letter: null,
  },
})

const genderInitial = computed(() => apiValueToLabel(GENDER_OPTIONS, form.applicant.gender))
const marriageStatusInitial = computed(() =>
  apiValueToLabel(MARRIAGE_STATUS_OPTIONS, form.applicant.marriage_status),
)
const employerInitial = computed(() => apiValueToLabel(EMPLOYER_OPTIONS, form.applicant.employer_name))

function setGenderValue(details: { value: string[] }) {
  form.applicant.gender = labelToApiValue(GENDER_OPTIONS, details.value[0])
  delete fieldErrors['applicant.gender']
}

function setMarriageStatusValue(details: { value: string[] }) {
  form.applicant.marriage_status = labelToApiValue(MARRIAGE_STATUS_OPTIONS, details.value[0])
  delete fieldErrors['applicant.marriage_status']
}

function setEmployerValue(details: { value: string[] }) {
  const employerName = labelToApiValue(EMPLOYER_OPTIONS, details.value[0])
  form.applicant.employer_name = employerName
  form.applicant.employer_address = getEmployerAddress(employerName)
  delete fieldErrors['applicant.employer_name']
  delete fieldErrors['applicant.employer_address']
}

function setHeirRelationshipValue(index: number, details: { value: string[] }) {
  const heir = form.heirs[index]
  if (!heir) return
  heir.relationship = labelToApiValue(RELATIONSHIP_OPTIONS, details.value[0])
  delete fieldErrors[`heirs.${index}.relationship`]
}

const referenceLookupLoading = reactive({
  proposer: false,
  supporter: false,
})

function clearReference(role: 'proposer' | 'supporter') {
  form.references[role].user_id = ''
  form.references[role].name = ''
  delete fieldErrors[`references.${role}_ic_number`]
}

function handleReferenceIcInput(role: 'proposer' | 'supporter') {
  form.references[role].ic_number = sanitizeIcNumberInput(form.references[role].ic_number)
  clearReference(role)
}

function handleApplicantNameInput() {
  form.applicant.name = sanitizeNameInput(form.applicant.name)
  delete fieldErrors['applicant.name']
}

function handleApplicantIcInput() {
  form.applicant.ic_number = sanitizeIcNumberInput(form.applicant.ic_number)
  delete fieldErrors['applicant.ic_number']
}

function handleHeirNameInput(index: number) {
  const heir = form.heirs[index]
  if (!heir) return
  heir.name = sanitizeNameInput(heir.name)
  delete fieldErrors[`heirs.${index}.name`]
}

function handleHeirIcInput(index: number) {
  const heir = form.heirs[index]
  if (!heir) return
  heir.ic_number = sanitizeIcNumberInput(heir.ic_number)
  delete fieldErrors[`heirs.${index}.ic_number`]
}

async function lookupReference(role: 'proposer' | 'supporter') {
  const reference = form.references[role]
  const icNumber = reference.ic_number.trim()
  const fieldKey = `references.${role}_ic_number`

  delete fieldErrors[fieldKey]

  if (!icNumber) {
    clearReference(role)
    return
  }

  if (icNumber === form.applicant.ic_number.trim()) {
    clearReference(role)
    setError(fieldKey, 'Pencadang/penyokong tidak boleh sama dengan pemohon.')
    return
  }

  const otherRole = role === 'proposer' ? 'supporter' : 'proposer'
  if (icNumber === form.references[otherRole].ic_number.trim()) {
    clearReference(role)
    setError(fieldKey, 'Pencadang dan penyokong mestilah ahli yang berbeza.')
    return
  }

  referenceLookupLoading[role] = true

  try {
    const response = await lookupMemberByIcNumber(icNumber)

    if (!response.success || !response.data) {
      clearReference(role)
      setError(fieldKey, response.message || 'Ahli tidak dijumpai.')
      return
    }

    reference.user_id = response.data.id
    reference.name = response.data.name
    reference.ic_number = response.data.ic_number
  } catch (error) {
    clearReference(role)
    setError(fieldKey, getApiErrorMessage(error, 'Gagal mencari ahli.'))
  } finally {
    referenceLookupLoading[role] = false
  }
}

function validateReference(role: 'proposer' | 'supporter', label: string): boolean {
  const reference = form.references[role]
  const fieldKey = `references.${role}_ic_number`

  if (!reference.ic_number.trim()) {
    return true
  }

  if (!reference.user_id) {
    setError(fieldKey, `${label} tidak dijumpai. Sila semak no. KP.`)
    return false
  }

  return true
}

const stepTitle = computed(() => {
  switch (currentStep.value) {
    case 1:
      return 'Maklumat Peribadi'
    case 2:
      return 'Hubungan & Alamat Rumah Semasa'
    case 3:
      return 'Maklumat Pekerjaan & Caruman'
    case 4:
      return 'Maklumat Penama'
    default:
      return 'Dokumen & Pengesahan'
  }
})

const stepDescription = computed(() => {
  switch (currentStep.value) {
    case 1:
      return 'Sila isi maklumat peribadi anda dengan lengkap dan tepat.'
    case 2:
      return 'Masukkan maklumat hubungan dan alamat semasa.'
    case 3:
      return 'Masukkan maklumat pekerjaan dan caruman bulanan.'
    case 4:
      return 'Tambah sekurang-kurangnya satu Penama.'
    default:
      return 'Muat naik dokumen sokongan dan semak maklumat sebelum hantar.'
  }
})

function clearErrors() {
  Object.keys(fieldErrors).forEach((key) => delete fieldErrors[key])
  errorMessage.value = ''
}

function setError(key: string, message: string) {
  fieldErrors[key] = message
}

function validateStep(step: number): boolean {
  clearErrors()
  let valid = true

  const requireField = (key: string, value: string | number | null | undefined, label: string) => {
    if (!String(value ?? '').trim()) {
      setError(key, `${label} diperlukan.`)
      valid = false
    }
  }

  if (step === 1) {
    requireField('applicant.name', form.applicant.name, 'Nama penuh')
    requireField('applicant.email', form.applicant.email, 'Emel')
    requireField('applicant.ic_number', form.applicant.ic_number, 'No. kad pengenalan')
    requireField('applicant.birth_date', form.applicant.birth_date, 'Tarikh lahir')
    requireField('applicant.birth_place', form.applicant.birth_place, 'Tempat lahir')
    requireField('applicant.gender', form.applicant.gender, 'Jantina')
    requireField('applicant.marriage_status', form.applicant.marriage_status, 'Status perkahwinan')

    if (form.applicant.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.applicant.email)) {
      setError('applicant.email', 'Emel tidak sah.')
      valid = false
    }
  }

  if (step === 2) {
    requireField('applicant.address', form.applicant.address, 'Alamat')
    requireField('applicant.phone_number', form.applicant.phone_number, 'No. telefon')
    requireField('applicant.postcode', form.applicant.postcode, 'Poskod')
  }

  if (step === 3) {
    requireField('applicant.employer_name', form.applicant.employer_name, 'Nama majikan')
    requireField('applicant.employer_address', form.applicant.employer_address, 'Alamat majikan')
    requireField('applicant.current_position', form.applicant.current_position, 'Jawatan semasa')
    requireField('applicant.start_work_date', form.applicant.start_work_date, 'Tarikh mula berkhidmat')
    requireField(
      'applicant.stock_monthly_contribution',
      form.applicant.stock_monthly_contribution,
      'Potongan modal syer minima',
    )

    const stockContribution = Number(form.applicant.stock_monthly_contribution)
    if (
      form.applicant.stock_monthly_contribution &&
      (Number.isNaN(stockContribution) || stockContribution < MIN_STOCK_MONTHLY_CONTRIBUTION)
    ) {
      setError(
        'applicant.stock_monthly_contribution',
        `Potongan modal syer minima mestilah sekurang-kurangnya RM${MIN_STOCK_MONTHLY_CONTRIBUTION}.`,
      )
      valid = false
    }
    requireField(
      'applicant.fee_monthly_contribution',
      form.applicant.fee_monthly_contribution,
      'Potongan yuran bulanan',
    )

    const feeContribution = Number(form.applicant.fee_monthly_contribution)
    if (
      form.applicant.fee_monthly_contribution &&
      (Number.isNaN(feeContribution) || feeContribution < MIN_FEE_MONTHLY_CONTRIBUTION)
    ) {
      setError(
        'applicant.fee_monthly_contribution',
        `Potongan yuran bulanan mestilah sekurang-kurangnya RM${MIN_FEE_MONTHLY_CONTRIBUTION}.`,
      )
      valid = false
    }
  }

  if (step === 4) {
    form.heirs.forEach((heir, index) => {
      requireField(`heirs.${index}.name`, heir.name, `Nama Penama ${index + 1}`)
      requireField(`heirs.${index}.ic_number`, heir.ic_number, `No. KP Penama ${index + 1}`)
      requireField(`heirs.${index}.relationship`, heir.relationship, `Hubungan Penama ${index + 1}`)
      requireField(`heirs.${index}.phone_number`, heir.phone_number, `No. telefon Penama ${index + 1}`)
    })
  }

  if (step === 5) {
    if (!validateReference('proposer', 'Pencadang')) {
      valid = false
    }

    if (!validateReference('supporter', 'Penyokong')) {
      valid = false
    }

    if (!form.documents.ic_copy) {
      setError('documents.ic_copy', 'Salinan kad pengenalan diperlukan.')
      valid = false
    }

    if (!form.documents.employer_letter) {
      setError('documents.employer_letter', 'Surat pengesahan majikan diperlukan.')
      valid = false
    }
  }

  return valid
}

function goNext() {
  if (!validateStep(currentStep.value)) return
  if (currentStep.value < steps.length) {
    currentStep.value += 1
  }
}

function goPrevious() {
  clearErrors()
  if (currentStep.value > 1) {
    currentStep.value -= 1
  }
}

function addHeir() {
  form.heirs.push(createEmptyHeir())
}

function removeHeir(index: number) {
  if (form.heirs.length <= 1) return
  form.heirs.splice(index, 1)
}

function handleFileChange(
  key: keyof MembershipApplicationFormState['documents'],
  event: Event,
) {
  const target = event.target as HTMLInputElement
  const file = target.files?.[0] ?? null

  if (file && file.size > MAX_FILE_SIZE_BYTES) {
    form.documents[key] = null
    target.value = ''
    setError(`documents.${key}`, `Saiz fail melebihi had maksimum ${MAX_FILE_SIZE_MB}MB.`)
    return
  }

  form.documents[key] = file
  delete fieldErrors[`documents.${key}`]
}

function applyServerErrors(errors: Record<string, string[]>) {
  Object.entries(errors).forEach(([key, messages]) => {
    if (messages[0]) {
      fieldErrors[key] = messages[0]
    }
  })

  const stepByField: Record<string, number> = {
    applicant: 1,
    heirs: 4,
    references: 5,
    documents: 5,
  }

  const firstKey = Object.keys(errors)[0]
  if (!firstKey) return

  const prefix = firstKey.split('.')[0] ?? ''
  const step = stepByField[prefix]

  if (step !== undefined) {
    currentStep.value = step
  }
}

async function handleSubmit() {
  if (!validateStep(5)) return

  loading.value = true
  clearErrors()

  try {
    const response = await submitMembershipApplication(form)
    applicationNumber.value = response.data.application_number
    submitted.value = true
  } catch (error) {
    const validationErrors = getApiValidationErrors(error)
    if (validationErrors) {
      applyServerErrors(validationErrors)
      errorMessage.value = 'Sila semak maklumat yang ditandakan.'
    } else {
      errorMessage.value = getApiErrorMessage(error, 'Gagal menghantar permohonan.')
    }
  } finally {
    loading.value = false
  }
}

function stepButtonClass(stepId: number) {
  if (stepId === currentStep.value) {
    return 'mx-2 size-12 rounded-full shadow-none'
  }

  if (stepId < currentStep.value) {
    return 'mx-2 size-12 rounded-full shadow-none bg-primary text-primary-foreground'
  }

  return 'bg-background border border-foreground/15 shadow-none mx-2 size-12 rounded-full'
}

function stepLabelClass(stepId: number) {
  return stepId === currentStep.value
    ? 'text-primary ml-3 font-medium opacity-100 lg:mx-auto lg:mt-3 lg:w-32'
    : 'ml-3 opacity-70 lg:mx-auto lg:mt-3 lg:w-32'
}
</script>

<template>
  <div class="min-h-screen bg-background">
    <HelpdeskFab />
    <div class="border-b border-foreground/10 bg-primary/5">
      <div class="container mx-auto flex items-center justify-between px-5 py-4 sm:px-8">
        <div class="flex items-center gap-4">
          <img :src="illustrationUrl" alt="MyKOPKB" class="h-10 w-auto" />
          <div>
            <div class="text-lg font-semibold">Permohonan Keahlian</div>
            <div class="text-sm opacity-70">Borang permohonan ahli koperasi</div>
          </div>
        </div>
        <RouterLink to="/login">
          <Button look="outline" size="sm">Log Masuk</Button>
        </RouterLink>
      </div>
    </div>

    <div v-if="submitted" class="container mx-auto px-5 py-16 sm:px-8">
      <Box class="mx-auto max-w-2xl py-12 text-center">
        <div class="mx-auto mb-4 flex size-16 items-center justify-center rounded-full bg-success/10 text-success">
          <Lucide icon="CircleCheck" class="size-8" />
        </div>
        <h2 class="text-2xl font-semibold">Permohonan Berjaya Dihantar</h2>
        <p class="mt-3 opacity-70">
          Terima kasih. Permohonan keahlian anda telah diterima.
        </p>
        <div class="mt-6 rounded-lg border border-foreground/10 bg-foreground/5 px-6 py-4">
          <div class="text-sm opacity-70">No. Permohonan</div>
          <div class="mt-1 text-xl font-semibold text-primary">{{ applicationNumber }}</div>
        </div>
        <p class="mt-6 text-sm opacity-70">
          E-mel permohonan anda telah dihantar. Anda akan menerima emel
          apabila keputusan permohonan tersedia.
        </p>
        <RouterLink to="/login" class="mt-8 inline-block">
          <Button>Kembali ke Log Masuk</Button>
        </RouterLink>
      </Box>
    </div>

    <div v-else class="container mx-auto px-5 py-8 sm:px-8">
      <Box class="py-10 sm:py-16">
        <div
          class="before:bg-foreground/10 relative flex flex-col justify-center px-5 before:absolute before:bottom-0 before:top-0 before:mt-6 before:hidden before:h-0.5 before:w-[69%] sm:px-10 lg:flex-row before:lg:block">
          <div v-for="step in steps" :key="step.id" class="z-10 flex flex-1 items-center lg:block lg:text-center">
            <Button :class="stepButtonClass(step.id)" :variant="step.id === currentStep ? 'primary' : 'ghost'">
              {{ step.id }}
            </Button>
            <div :class="stepLabelClass(step.id)">
              {{ step.label }}
            </div>
          </div>
        </div>

        <div class="mt-10 border-t border-foreground/10 px-5 pt-10 sm:px-10">
          <div class="text-center lg:text-left">
            <div class="text-lg font-medium">{{ stepTitle }}</div>
            <div class="mt-2 opacity-70">{{ stepDescription }}</div>
          </div>

          <AlertRoot v-if="errorMessage" class="mt-6" variant="danger">
            <AlertTitle>Ralat</AlertTitle>
            <AlertDescription>{{ errorMessage }}</AlertDescription>
          </AlertRoot>

          <div class="mt-8 grid grid-cols-12 gap-4 gap-y-5">
            <template v-if="currentStep === 1">
              <Field class="col-span-12 sm:col-span-6">
                <FieldLabel for="name">Nama Penuh</FieldLabel>
                <Input id="name" v-model="form.applicant.name" type="text" @input="handleApplicantNameInput" />
                <FieldError v-if="fieldErrors['applicant.name']">{{ fieldErrors['applicant.name'] }}</FieldError>
              </Field>
              <Field class="col-span-12 sm:col-span-6">
                <FieldLabel for="email">Emel</FieldLabel>
                <Input id="email" v-model="form.applicant.email" type="email" />
                <FieldError v-if="fieldErrors['applicant.email']">{{ fieldErrors['applicant.email'] }}</FieldError>
              </Field>
              <Field class="col-span-12 sm:col-span-6">
                <FieldLabel for="ic_number">No. Kad Pengenalan</FieldLabel>
                <Input id="ic_number" v-model="form.applicant.ic_number" type="text" inputmode="numeric" maxlength="15"
                  placeholder="Contoh: 900101011234" @input="handleApplicantIcInput" />
                <FieldError v-if="fieldErrors['applicant.ic_number']">{{ fieldErrors['applicant.ic_number'] }}
                </FieldError>
              </Field>
              <Field class="col-span-12 sm:col-span-6">
                <FieldLabel for="birth_date">Tarikh Lahir</FieldLabel>
                <Input id="birth_date" v-model="form.applicant.birth_date" type="date" />
                <FieldError v-if="fieldErrors['applicant.birth_date']">{{ fieldErrors['applicant.birth_date'] }}
                </FieldError>
              </Field>
              <Field class="col-span-12 sm:col-span-6">
                <FieldLabel for="birth_place">Tempat Lahir</FieldLabel>
                <Input id="birth_place" v-model="form.applicant.birth_place" type="text" />
                <FieldError v-if="fieldErrors['applicant.birth_place']">{{ fieldErrors['applicant.birth_place'] }}
                </FieldError>
              </Field>
              <Field class="col-span-12 sm:col-span-6">
                <FieldLabel>Jantina</FieldLabel>
                <SelectRoot :key="`gender-${form.applicant.gender}`" class="w-full" :collection="genderCollection"
                  :default-value="genderInitial" @value-change="setGenderValue">
                  <SelectControl>
                    <SelectTrigger :aria-invalid="!!fieldErrors['applicant.gender']">
                      <SelectValueText placeholder="Pilih jantina" />
                    </SelectTrigger>
                  </SelectControl>
                  <SelectContent>
                    <SelectItemGroup>
                      <SelectItemGroupLabel>Jantina</SelectItemGroupLabel>
                      <SelectItem v-for="item in genderCollection.items" :key="item.label" :item="item">
                        <SelectItemText>{{ item.label }}</SelectItemText>
                      </SelectItem>
                    </SelectItemGroup>
                  </SelectContent>
                </SelectRoot>
                <FieldError v-if="fieldErrors['applicant.gender']">{{ fieldErrors['applicant.gender'] }}</FieldError>
              </Field>
              <Field class="col-span-12 sm:col-span-6">
                <FieldLabel>Status Perkahwinan</FieldLabel>
                <SelectRoot :key="`marriage-status-${form.applicant.marriage_status}`" class="w-full"
                  :collection="marriageStatusCollection" :default-value="marriageStatusInitial"
                  @value-change="setMarriageStatusValue">
                  <SelectControl>
                    <SelectTrigger :aria-invalid="!!fieldErrors['applicant.marriage_status']">
                      <SelectValueText placeholder="Pilih status" />
                    </SelectTrigger>
                  </SelectControl>
                  <SelectContent>
                    <SelectItemGroup>
                      <SelectItemGroupLabel>Status Perkahwinan</SelectItemGroupLabel>
                      <SelectItem v-for="item in marriageStatusCollection.items" :key="item.label" :item="item">
                        <SelectItemText>{{ item.label }}</SelectItemText>
                      </SelectItem>
                    </SelectItemGroup>
                  </SelectContent>
                </SelectRoot>
                <FieldError v-if="fieldErrors['applicant.marriage_status']">
                  {{ fieldErrors['applicant.marriage_status'] }}
                </FieldError>
              </Field>
            </template>

            <template v-else-if="currentStep === 2">
              <Field class="col-span-12">
                <FieldLabel for="address">Alamat</FieldLabel>
                <Textarea id="address" v-model="form.applicant.address" rows="3" />
                <FieldError v-if="fieldErrors['applicant.address']">{{ fieldErrors['applicant.address'] }}</FieldError>
              </Field>
              <Field class="col-span-12 sm:col-span-4">
                <FieldLabel for="phone_number">No. Telefon</FieldLabel>
                <Input id="phone_number" v-model="form.applicant.phone_number" type="text" />
                <FieldError v-if="fieldErrors['applicant.phone_number']">
                  {{ fieldErrors['applicant.phone_number'] }}
                </FieldError>
              </Field>
              <Field class="col-span-12 sm:col-span-4">
                <FieldLabel for="office_number">No. Pejabat (Pilihan)</FieldLabel>
                <Input id="office_number" v-model="form.applicant.office_number" type="text" />
                <FieldError v-if="fieldErrors['applicant.office_number']">
                  {{ fieldErrors['applicant.office_number'] }}
                </FieldError>
              </Field>
              <Field class="col-span-12 sm:col-span-4">
                <FieldLabel for="postcode">Poskod</FieldLabel>
                <Input id="postcode" v-model="form.applicant.postcode" type="text" />
                <FieldError v-if="fieldErrors['applicant.postcode']">{{ fieldErrors['applicant.postcode'] }}
                </FieldError>
              </Field>
            </template>

            <template v-else-if="currentStep === 3">
              <Field class="col-span-12 sm:col-span-6">
                <FieldLabel>Nama Majikan</FieldLabel>
                <SelectRoot :key="`employer-${form.applicant.employer_name}`" class="w-full"
                  :collection="employerCollection" :default-value="employerInitial" @value-change="setEmployerValue">
                  <SelectControl>
                    <SelectTrigger :aria-invalid="!!fieldErrors['applicant.employer_name']">
                      <SelectValueText placeholder="Pilih majikan" />
                    </SelectTrigger>
                  </SelectControl>
                  <SelectContent>
                    <SelectItemGroup>
                      <SelectItemGroupLabel>Nama Majikan</SelectItemGroupLabel>
                      <SelectItem v-for="item in employerCollection.items" :key="item.label" :item="item">
                        <SelectItemText>{{ item.label }}</SelectItemText>
                      </SelectItem>
                    </SelectItemGroup>
                  </SelectContent>
                </SelectRoot>
                <FieldError v-if="fieldErrors['applicant.employer_name']">
                  {{ fieldErrors['applicant.employer_name'] }}
                </FieldError>
              </Field>
              <Field class="col-span-12 sm:col-span-6">
                <FieldLabel for="current_position">Jawatan Semasa</FieldLabel>
                <Input id="current_position" v-model="form.applicant.current_position" type="text" />
                <FieldError v-if="fieldErrors['applicant.current_position']">
                  {{ fieldErrors['applicant.current_position'] }}
                </FieldError>
              </Field>
              <Field class="col-span-12">
                <FieldLabel for="employer_address">Alamat Majikan</FieldLabel>
                <Textarea id="employer_address" v-model="form.applicant.employer_address" rows="3" disabled />
                <FieldError v-if="fieldErrors['applicant.employer_address']">
                  {{ fieldErrors['applicant.employer_address'] }}
                </FieldError>
              </Field>
              <Field class="col-span-12 sm:col-span-4">
                <FieldLabel for="start_work_date">Tarikh Mula Berkhidmat</FieldLabel>
                <Input id="start_work_date" v-model="form.applicant.start_work_date" type="date" />
                <FieldError v-if="fieldErrors['applicant.start_work_date']">
                  {{ fieldErrors['applicant.start_work_date'] }}
                </FieldError>
              </Field>
              <Field class="col-span-12 sm:col-span-4">
                <FieldLabel for="stock_monthly_contribution">Potongan Modal Syer Minima</FieldLabel>
                <FieldDescription>
                  Minima RM{{ MIN_STOCK_MONTHLY_CONTRIBUTION }} setiap bulan.
                </FieldDescription>
                <Input id="stock_monthly_contribution" v-model="form.applicant.stock_monthly_contribution" type="number"
                  :min="MIN_STOCK_MONTHLY_CONTRIBUTION" step="0.01" />
                <FieldDescription class="mt-2">
                  Potongan RM{{ INITIAL_MANDATORY_STOCK_MONTHLY_CONTRIBUTION }} setiap bulan adalah wajib bagi 6 bulan
                  pertama bagi menjelaskan modal syer minimum RM500. Anda boleh memilih potongan lebih tinggi. Selepas
                  RM500 dijelaskan, potongan boleh dikekalkan atau dikurangkan sehingga minima
                  RM{{ MIN_STOCK_MONTHLY_CONTRIBUTION }} setiap bulan.
                </FieldDescription>
                <FieldError v-if="fieldErrors['applicant.stock_monthly_contribution']">
                  {{ fieldErrors['applicant.stock_monthly_contribution'] }}
                </FieldError>
              </Field>
              <Field class="col-span-12 sm:col-span-4">
                <FieldLabel for="fee_monthly_contribution">Potongan Yuran Bulanan</FieldLabel>
                <FieldDescription>Minima RM{{ MIN_FEE_MONTHLY_CONTRIBUTION }} setiap bulan.</FieldDescription>
                <Input id="fee_monthly_contribution" v-model="form.applicant.fee_monthly_contribution" type="number"
                  :min="MIN_FEE_MONTHLY_CONTRIBUTION" step="0.01" />
                <FieldError v-if="fieldErrors['applicant.fee_monthly_contribution']">
                  {{ fieldErrors['applicant.fee_monthly_contribution'] }}
                </FieldError>
              </Field>
            </template>

            <template v-else-if="currentStep === 4">
              <div class="col-span-12 space-y-6">
                <div v-for="(heir, index) in form.heirs" :key="index"
                  class="rounded-lg border border-foreground/10 p-4">
                  <div class="mb-4 flex items-center justify-between">
                    <div class="font-medium">Penama</div>
                    <Button v-if="form.heirs.length > 1" type="button" look="outline" size="sm"
                      @click="removeHeir(index)">
                      Buang
                    </Button>
                  </div>
                  <div class="grid grid-cols-12 gap-4">
                    <Field class="col-span-12 sm:col-span-6">
                      <FieldLabel :for="`heir-name-${index}`">Nama</FieldLabel>
                      <Input :id="`heir-name-${index}`" v-model="heir.name" type="text"
                        @input="handleHeirNameInput(index)" />
                      <FieldError v-if="fieldErrors[`heirs.${index}.name`]">
                        {{ fieldErrors[`heirs.${index}.name`] }}
                      </FieldError>
                    </Field>
                    <Field class="col-span-12 sm:col-span-6">
                      <FieldLabel :for="`heir-ic-${index}`">No. Kad Pengenalan</FieldLabel>
                      <Input :id="`heir-ic-${index}`" v-model="heir.ic_number" type="text" inputmode="numeric"
                        maxlength="15" placeholder="Contoh: 900101011234" @input="handleHeirIcInput(index)" />
                      <FieldError v-if="fieldErrors[`heirs.${index}.ic_number`]">
                        {{ fieldErrors[`heirs.${index}.ic_number`] }}
                      </FieldError>
                    </Field>
                    <Field class="col-span-12 sm:col-span-6">
                      <FieldLabel>Hubungan</FieldLabel>
                      <SelectRoot :key="`heir-relationship-${index}-${heir.relationship}`" class="w-full"
                        :collection="relationshipCollection"
                        :default-value="apiValueToLabel(RELATIONSHIP_OPTIONS, heir.relationship)"
                        @value-change="(details) => setHeirRelationshipValue(index, details)">
                        <SelectControl>
                          <SelectTrigger :aria-invalid="!!fieldErrors[`heirs.${index}.relationship`]">
                            <SelectValueText placeholder="Pilih hubungan" />
                          </SelectTrigger>
                        </SelectControl>
                        <SelectContent>
                          <SelectItemGroup>
                            <SelectItemGroupLabel>Hubungan</SelectItemGroupLabel>
                            <SelectItem v-for="item in relationshipCollection.items" :key="item.label" :item="item">
                              <SelectItemText>{{ item.label }}</SelectItemText>
                            </SelectItem>
                          </SelectItemGroup>
                        </SelectContent>
                      </SelectRoot>
                      <FieldError v-if="fieldErrors[`heirs.${index}.relationship`]">
                        {{ fieldErrors[`heirs.${index}.relationship`] }}
                      </FieldError>
                    </Field>
                    <Field class="col-span-12 sm:col-span-6">
                      <FieldLabel :for="`heir-phone-${index}`">No. Telefon</FieldLabel>
                      <Input :id="`heir-phone-${index}`" v-model="heir.phone_number" type="text" />
                      <FieldError v-if="fieldErrors[`heirs.${index}.phone_number`]">
                        {{ fieldErrors[`heirs.${index}.phone_number`] }}
                      </FieldError>
                    </Field>
                  </div>
                </div>
                <!-- Penama hanya boleh 1 orang (disable in frontend)-->
                <!-- <Button type="button" look="outline" @click="addHeir">
                  <Lucide icon="Plus" class="mr-2 size-4" />
                  Tambah Penama
                </Button> -->
              </div>
            </template>

            <template v-else>
              <div class="col-span-12 rounded-lg border border-foreground/10 bg-foreground/5 p-4">
                <div class="mb-1 font-medium">Pencadang & Penyokong (Pilihan)</div>
                <p class="text-sm opacity-70">
                  Masukkan no. KP ahli sedia ada. Sistem akan mengesahkan dan mengisi nama secara automatik.
                </p>
              </div>

              <Field class="col-span-12 sm:col-span-6">
                <FieldLabel for="proposer_ic_number">No. KP Pencadang</FieldLabel>
                <Input id="proposer_ic_number" v-model="form.references.proposer.ic_number" type="text"
                  inputmode="numeric" maxlength="12" placeholder="Contoh: 900101011234"
                  :disabled="referenceLookupLoading.proposer" @input="handleReferenceIcInput('proposer')"
                  @blur="lookupReference('proposer')" />
                <p v-if="form.references.proposer.name" class="mt-1 text-sm text-success">
                  {{ form.references.proposer.name }}
                </p>
                <FieldError v-if="fieldErrors['references.proposer_ic_number']">
                  {{ fieldErrors['references.proposer_ic_number'] }}
                </FieldError>
              </Field>

              <Field class="col-span-12 sm:col-span-6">
                <FieldLabel for="supporter_ic_number">No. KP Penyokong</FieldLabel>
                <Input id="supporter_ic_number" v-model="form.references.supporter.ic_number" type="text"
                  inputmode="numeric" maxlength="12" placeholder="Contoh: 850505055678"
                  :disabled="referenceLookupLoading.supporter" @input="handleReferenceIcInput('supporter')"
                  @blur="lookupReference('supporter')" />
                <p v-if="form.references.supporter.name" class="mt-1 text-sm text-success">
                  {{ form.references.supporter.name }}
                </p>
                <FieldError v-if="fieldErrors['references.supporter_ic_number']">
                  {{ fieldErrors['references.supporter_ic_number'] }}
                </FieldError>
              </Field>

              <div class="col-span-12 rounded-lg border border-foreground/10 bg-foreground/5 p-4 text-sm opacity-80">
                Saiz maksimum setiap fail: <strong>{{ MAX_FILE_SIZE_MB }}MB</strong>.
                Format yang dibenarkan: PDF, JPG, JPEG atau PNG.
              </div>
              <Field class="col-span-12 sm:col-span-6">
                <FieldLabel for="ic_copy">Salinan Kad Pengenalan *</FieldLabel>
                <Input id="ic_copy" type="file" accept=".pdf,.jpg,.jpeg,.png"
                  @change="handleFileChange('ic_copy', $event)" />
                <FieldError v-if="fieldErrors['documents.ic_copy']">{{ fieldErrors['documents.ic_copy'] }}</FieldError>
              </Field>
              <Field class="col-span-12 sm:col-span-6">
                <FieldLabel for="photo">Gambar Passport (Pilihan)</FieldLabel>
                <Input id="photo" type="file" accept=".jpg,.jpeg,.png" @change="handleFileChange('photo', $event)" />
                <FieldError v-if="fieldErrors['documents.photo']">{{ fieldErrors['documents.photo'] }}</FieldError>
              </Field>
              <Field class="col-span-12 sm:col-span-6">
                <FieldLabel for="salary_slip">Slip Gaji (Pilihan)</FieldLabel>
                <Input id="salary_slip" type="file" accept=".pdf,.jpg,.jpeg,.png"
                  @change="handleFileChange('salary_slip', $event)" />
                <FieldError v-if="fieldErrors['documents.salary_slip']">{{ fieldErrors['documents.salary_slip'] }}
                </FieldError>
              </Field>
              <Field class="col-span-12 sm:col-span-6">
                <FieldLabel for="employer_letter">Surat Pengesahan Majikan *</FieldLabel>
                <Input id="employer_letter" type="file" accept=".pdf,.jpg,.jpeg,.png"
                  @change="handleFileChange('employer_letter', $event)" />
                <FieldError v-if="fieldErrors['documents.employer_letter']">{{ fieldErrors['documents.employer_letter']
                }}</FieldError>
              </Field>

              <div class="col-span-12 mt-2 rounded-lg border border-foreground/10 bg-foreground/5 p-4">
                <div class="mb-3 font-medium">Semakan Ringkas</div>
                <div class="grid gap-2 text-sm sm:grid-cols-2">
                  <div><span class="opacity-70">Nama:</span> {{ form.applicant.name }}</div>
                  <div><span class="opacity-70">Emel:</span> {{ form.applicant.email }}</div>
                  <div><span class="opacity-70">No. KP:</span> {{ form.applicant.ic_number }}</div>
                  <div><span class="opacity-70">Majikan:</span> {{ form.applicant.employer_name }}</div>
                  <div><span class="opacity-70">Bil. Penama:</span> {{ form.heirs.length }}</div>
                  <div>
                    <span class="opacity-70">Pencadang:</span>
                    {{ form.references.proposer.name || '-' }}
                  </div>
                  <div>
                    <span class="opacity-70">Penyokong:</span>
                    {{ form.references.supporter.name || '-' }}
                  </div>
                  <div><span class="opacity-70">Dokumen IC:</span> {{ form.documents.ic_copy?.name ?? '-' }}</div>
                </div>
              </div>
            </template>

            <div class="col-span-12 mt-5 flex items-center justify-center sm:justify-end">
              <Button v-if="currentStep > 1" type="button" look="outline" class="w-32" :disabled="loading"
                @click="goPrevious">
                Sebelum
              </Button>
              <Button v-if="currentStep < steps.length" type="button" class="ml-2 w-32" @click="goNext">
                Seterusnya
              </Button>
              <Button v-else type="button" class="ml-2 w-40" :disabled="loading" @click="handleSubmit">
                {{ loading ? 'Menghantar...' : 'Hantar Permohonan' }}
              </Button>
            </div>
          </div>
        </div>
      </Box>
    </div>
  </div>
</template>
