<script setup lang="ts">
// Components
import * as DE from '~/components/pub/my-ui/doc-entry'
import { Button } from '~/components/pub/ui/button'
import { Input } from '~/components/pub/ui/input'
import * as CB from '~/components/pub/my-ui/combobox'

import DatepickerSingle from '~/components/pub/my-ui/datepicker/datepicker-single.vue'
import FileUpload from '~/components/pub/my-ui/form/file-field.vue'

// Types
import { IntegrationEncounterSchema, type IntegrationEncounterFormData } from '~/schemas/integration-encounter.schema'
import type { PatientEntity } from '~/models/patient'

// Helpers
import { toTypedSchema } from '@vee-validate/zod'
import { useForm } from 'vee-validate'
import { refDebounced } from '@vueuse/core'
import type { Doctor } from '~/models/doctor'

// References
import { paymentMethodCodes } from '~/const/key-val/common'

// App things
import { genEncounter, type Encounter } from '~/models/encounter'
import { se } from 'date-fns/locale'

// Props
const props = defineProps<{
  mode?: string
  isLoading?: boolean
  isReadonly?: boolean
  isSepValid?: boolean
  isMemberValid?: boolean
  isCheckingSep?: boolean
  doctorItems?: CB.Item[]
  selectedDoctor: Doctor
  // subSpecialist?: any[]
  // specialists?: TreeItem[]
  payments?: any[]
  participantGroups?: any[]
  seps: any[]
  patient?: PatientEntity | null | undefined
  objects?: any
}>()

// Model
const model = defineModel<Encounter>()
model.value = genEncounter()

// Common preparation
const defaultCBItems = [{ label: 'Pilih', value: '' }]
const paymentMethodItems = CB.recStrToItem(paymentMethodCodes)

// Emit preparation
const emit = defineEmits<{
  (e: 'onSelectDoctor', code: string): void
  (e: 'event', menu: string, value?: any): void
  (e: 'fetch', value?: any): void
}>()

// Validation schema
const { handleSubmit, errors, defineField, meta } = useForm<IntegrationEncounterFormData>({
  validationSchema: toTypedSchema(IntegrationEncounterSchema),
})

// Bind fields and extract attrs
const [doctorCode, doctorCodeAttrs] = defineField('doctor_code')
const [unitCode, unitCodeAttrs] = defineField('unit_code')
const [registerDate, registerDateAttrs] = defineField('registerDate')
const [paymentMethodCode, paymentMethodCodeAttrs] = defineField('paymentMethod_code')
const [patientCategory, patientCategoryAttrs] = defineField('patientCategory')
const [cardNumber, cardNumberAttrs] = defineField('cardNumber')
const [sepType, sepTypeAttrs] = defineField('sepType')
const [sepNumber, sepNumberAttrs] = defineField('sepNumber')
const [patientName, patientNameAttrs] = defineField('patientName')
const [nationalIdentity, nationalIdentityAttrs] = defineField('nationalIdentity')
const [medicalRecordNumber, medicalRecordNumberAttrs] = defineField('medicalRecordNumber')
const [sepFile, sepFileAttrs] = defineField('sepFile')
const [sippFile, sippFileAttrs] = defineField('sippFile')
const patientId = ref('')
const sepReference = ref('')
const sepControlDate = ref('')
const sepTrafficStatus = ref('')
const diagnosis = ref('')
const noteReference = ref('Hanya diperlukan jika pembayaran jenis JKN')
const noteFile = ref('Gunakan file [.pdf, .jpg, .png] dengan ukuran maksimal 1MB')

const isLoading = props.isLoading !== undefined ? props.isLoading : false
const isReadonly = props.isReadonly !== undefined ? props.isReadonly : false
const mode = props.mode !== undefined ? props.mode : 'add'
// SEP validation state from props
const isSepValid = computed(() => props.isSepValid || false)
const isCheckingSep = computed(() => props.isCheckingSep || false)
const isInsurancePayment = computed(() => ['insurance', 'jkn'].includes(paymentMethodCode.value))
const isDateLoading = ref(false)
const debouncedSepNumber = refDebounced(sepNumber, 500)
const debouncedCardNumber = refDebounced(cardNumber, 500)
const sepFileReview = ref<any>(null)
const sippFileReview = ref<any>(null)
const unitFullName = ref('') // Unit, specialist, subspecialist
const formRef = ref<HTMLFormElement | null>(null) // Expose submit method for parent component

if (mode === 'add') {
  // Set default sepDate to current date in YYYY-MM-DD format
  const today = new Date()
  const year = today.getFullYear()
  const month = String(today.getMonth() + 1).padStart(2, '0')
  const day = String(today.getDate()).padStart(2, '0')
  registerDate.value = `${year}-${month}-${day}`
}

watch(
  () => props.selectedDoctor,
  (doctor) => {
    unitFullName.value = doctor.subspecialist?.name ?? doctor.specialist?.name ?? doctor.unit?.name ?? 'tidak diketahui'
    model.value!.unit_code = doctor.unit_code || ''
    model.value!.specialist_code = doctor.specialist_code || ''
    model.value!.subspecialist_code = doctor.subspecialist_code || ''
  },
)

// Sync props to form fields
watch(
  () => props.objects,
  (objects) => {
    if (objects && Object.keys(objects).length > 0) {
      patientName.value = objects?.patientName || ''
      nationalIdentity.value = objects?.nationalIdentity || ''
      medicalRecordNumber.value = objects?.medicalRecordNumber || ''
      doctorCode.value = objects?.doctorCode || ''
      paymentMethodCode.value = objects?.paymentMethodCode || ''
      patientCategory.value = objects?.patientCategory || ''
      cardNumber.value = objects?.cardNumber || ''
      sepType.value = objects?.sepType || ''
      sepNumber.value = objects?.sepNumber || ''
      sepFileReview.value = objects?.sepFileReview || ''
      sippFileReview.value = objects?.sippFileReview || ''
      isDateLoading.value = true
      setTimeout(() => {
        registerDate.value = objects?.registerDate || ''
        isDateLoading.value = false
      }, 100)
    }
  },
  { deep: true, immediate: true },
)

watch(
  () => props.patient,
  (patient) => {
    if (patient && Object.keys(patient).length > 0) {
      patientId.value = patient?.id ? String(patient.id) : ''
      patientName.value = patient?.person?.name || ''
      nationalIdentity.value = patient?.person?.residentIdentityNumber || ''
      medicalRecordNumber.value = patient?.number || ''
    }
  },
  { deep: true, immediate: true },
)

watch(
  () => props.isSepValid,
  (value) => {
    if (!value) return
    const objects = props.objects
    if (objects && Object.keys(objects).length > 0) {
      sepReference.value = objects?.sepReference || ''
      sepControlDate.value = objects?.sepControlDate || ''
      sepTrafficStatus.value = objects?.sepTrafficStatus || ''
      diagnosis.value = objects?.diagnosis || ''
    }
  },
)

watch(debouncedSepNumber, (newValue) => {
  emit('event', 'sep-number-changed', newValue)
})

watch(debouncedCardNumber, (newValue) => {
  emit('event', 'member-changed', newValue)
})

function onAddSep() {
  const formValues = {
    patientId: patientId.value || '',
    doctorCode: doctorCode.value,
    registerDate: registerDate.value,
    cardNumber: cardNumber.value,
    paymentMethodCode: paymentMethodCode.value,
    sepFile: sepFile.value,
    sippFile: sippFile.value,
    sepType: sepType.value,
  }
  emit('event', 'add-sep', formValues)
}

function onSearchSep() {
  emit('event', 'search-sep', { cardNumber: cardNumber.value })
}

// Submit handler
const onSubmit = handleSubmit((values) => {
  let payload: any = values
  if (props.mode === 'edit') {
    payload = {
      ...payload,
      sepFileReview: sepFileReview.value,
      sippFileReview: sippFileReview.value,
    }
  }
  emit('event', 'save', payload)
})

function openFile(path: string) {
  window.open(path, '_blank')
}

function submitForm() {
  // Trigger form submit using native form submit
  // This will trigger validation and onSubmit handler
  if (formRef.value) {
    formRef.value.requestSubmit()
  } else {
    // Fallback: directly call onSubmit handler
    // Create a mock event object
    const mockEvent = {
      preventDefault: () => {},
      target: formRef.value || {},
    } as SubmitEvent

    // Call onSubmit directly
    onSubmit(mockEvent)
  }
}

defineExpose({
  submitForm,
})
</script>

<template>
  <div class="mx-auto w-full">
    <form
      ref="formRef"
      @submit.prevent="onSubmit"
      class="grid gap-6 p-4"
    >
      <!-- Data Pasien -->
      <div class="flex flex-col gap-2">
        <h3 class="text-lg font-semibold">Data Pasien</h3>
        <div class="flex items-center gap-2">
          <span class="text-sm">sudah pernah terdaftar sebagai pasien?</span>
          <Button
            variant="outline"
            type="button"
            class="h-[40px] rounded-md border-orange-400 text-orange-400 hover:bg-green-50"
            @click="emit('event', 'search')"
          >
            <Icon
              name="i-lucide-search"
              class="h-5 w-5"
            />
            Cari Pasien
          </Button>
          <span class="text-sm">belum pernah terdaftar sebagai pasien?</span>
          <Button
            variant="outline"
            type="button"
            class="h-[40px] rounded-md border-orange-400 text-orange-400 hover:bg-green-50"
            @click="emit('event', 'add')"
          >
            <Icon
              name="i-lucide-plus"
              class="h-5 w-5"
            />
            Tambah Pasien Baru
          </Button>
        </div>
      </div>

      <DE.Block
        labelSize="thin"
        class="!pt-0"
        :colCount="3"
        :cellFlex="false"
      >
        <DE.Cell>
          <DE.Label height="compact">Nama Pasien</DE.Label>
          <DE.Field :errMessage="errors.patientName">
            <Input
              id="patientName"
              v-model="patientName"
              v-bind="patientNameAttrs"
              :disabled="true"
            />
          </DE.Field>
        </DE.Cell>

        <DE.Cell>
          <DE.Label height="compact">NIK</DE.Label>
          <DE.Field :errMessage="errors.nationalIdentity">
            <Input
              id="nationalIdentity"
              v-model="nationalIdentity"
              v-bind="nationalIdentityAttrs"
              :disabled="true"
            />
          </DE.Field>
        </DE.Cell>

        <DE.Cell>
          <DE.Label height="compact">No. RM</DE.Label>
          <DE.Field :errMessage="errors.medicalRecordNumber">
            <Input
              id="medicalRecordNumber"
              v-model="medicalRecordNumber"
              v-bind="medicalRecordNumberAttrs"
              :disabled="true"
            />
          </DE.Field>
        </DE.Cell>
      </DE.Block>

      <hr />

      <!-- Data Kunjungan -->
      <h3 class="text-lg font-semibold">Data Kunjungan</h3>

      <DE.Block
        labelSize="thin"
        class="!pt-0"
        :colCount="3"
        :cellFlex="false"
      >
        <DE.Cell>
          <DE.Label height="compact">
            Dokter
            <span class="text-red-500">*</span>
          </DE.Label>
          <DE.Field :errMessage="errors.doctor_code">
            <CB.Combobox
              id="doctorCode"
              v-model="doctorCode"
              v-bind="doctorCodeAttrs"
              :items="[...defaultCBItems, ...doctorItems]"
              :is-disabled="isLoading || isReadonly"
              placeholder="Pilih Dokter"
              search-placeholder="Cari Dokter"
              empty-message="Dokter tidak ditemukan"
              @update:model-value="(value) => emit('onSelectDoctor', value)"
            />
          </DE.Field>
        </DE.Cell>

        <DE.Cell>
          <DE.Label height="compact">
            Spesialis / Subspesialis
            <span class="text-red-500">*</span>
          </DE.Label>
          <DE.Field :errMessage="errors.unit_code">
            <Input
              :value="unitFullName"
              :disabled="true"
            />
          </DE.Field>
        </DE.Cell>

        <DE.Cell>
          <DE.Label height="compact">
            Tanggal Daftar
            <span class="text-red-500">*</span>
          </DE.Label>
          <DE.Field :errMessage="errors.registerDate">
            <DatepickerSingle
              v-if="!isDateLoading"
              id="registerDate"
              v-model="registerDate"
              v-bind="registerDateAttrs"
              placeholder="Pilih tanggal"
            />
          </DE.Field>
        </DE.Cell>
      </DE.Block>

      <DE.Block
        labelSize="thin"
        class="!pt-0"
        :colCount="3"
        :cellFlex="false"
      >
        <DE.Cell>
          <DE.Label height="compact">
            Jenis Pembayaran
            <span class="text-red-500">*</span>
          </DE.Label>
          <DE.Field :errMessage="errors.paymentMethod_code">
            <CB.Combobox
              id="paymentMethodCode"
              v-model="paymentMethodCode"
              v-bind="paymentMethodCodeAttrs"
              :items="paymentMethodItems"
              :disabled="isLoading || isReadonly"
              placeholder="Pilih Jenis Pembayaran"
            />
          </DE.Field>
        </DE.Cell>
      </DE.Block>

      <!-- BPJS Fields (conditional) -->
      <template v-if="isInsurancePayment">
        <DE.Block
          labelSize="thin"
          class="!pt-0"
          :colCount="3"
          :cellFlex="false"
        >
          <DE.Cell>
            <DE.Label height="compact">
              Kelompok Peserta
              <span class="text-red-500">*</span>
            </DE.Label>
            <DE.Field :errMessage="errors.patientCategory">
              <Select
                id="patientCategory"
                v-model="patientCategory"
                v-bind="patientCategoryAttrs"
                :items="participantGroups || []"
                :disabled="isLoading || isReadonly"
                placeholder="Pilih Kelompok Peserta"
              />
            </DE.Field>
            <span class="text-sm text-gray-500">
              {{ noteReference }}
            </span>
          </DE.Cell>

          <DE.Cell>
            <DE.Label height="compact">
              No. Kartu BPJS
              <span class="text-red-500">*</span>
            </DE.Label>
            <DE.Field :errMessage="errors.cardNumber">
              <Input
                id="cardNumber"
                v-model="cardNumber"
                v-bind="cardNumberAttrs"
                :disabled="isLoading || isReadonly"
                placeholder="Masukkan nomor kartu BPJS"
              />
            </DE.Field>
            <div
              v-if="isMemberValid"
              class="mt-1 flex items-center gap-2"
            >
              <Icon
                name="i-lucide-badge-check"
                class="h-4 w-4 bg-green-500 text-white"
              />
              <span class="text-sm text-green-500">Aktif</span>
            </div>
            <div
              v-if="!isMemberValid"
              class="mt-1 flex items-center gap-2"
            >
              <Icon
                name="i-lucide-x"
                class="h-4 w-4 bg-red-500 text-white"
              />
              <span class="text-sm text-red-500">Tidak aktif</span>
            </div>
          </DE.Cell>

          <DE.Cell>
            <DE.Label height="compact">
              Jenis SEP
              <span class="text-red-500">*</span>
            </DE.Label>
            <DE.Field :errMessage="errors.sepType">
              <Select
                id="sepType"
                v-model="sepType"
                v-bind="sepTypeAttrs"
                :items="seps"
                :disabled="isLoading || isReadonly"
                placeholder="Pilih Jenis SEP"
              />
            </DE.Field>
          </DE.Cell>
        </DE.Block>

        <DE.Block
          labelSize="thin"
          class="!pt-0"
          :colCount="3"
          :cellFlex="false"
        >
          <DE.Cell>
            <DE.Label height="compact">
              No. SEP
              <span class="text-red-500">*</span>
            </DE.Label>
            <DE.Field :errMessage="errors.sepNumber">
              <div class="flex gap-2">
                <Input
                  id="sepNumber"
                  v-model="sepNumber"
                  v-bind="sepNumberAttrs"
                  placeholder="Tambah SEP terlebih dahulu"
                  class="flex-1"
                  :disabled="isLoading || isReadonly || isSepValid"
                />
                <Button
                  v-if="!isSepValid"
                  variant="outline"
                  type="button"
                  class="bg-primary"
                  size="sm"
                  :disabled="isCheckingSep || isLoading || isReadonly"
                  @click="onAddSep"
                >
                  <Icon
                    v-if="isCheckingSep"
                    name="i-lucide-loader-2"
                    class="h-4 w-4 animate-spin"
                  />
                  <Icon
                    v-else
                    name="i-lucide-plus"
                    class="h-4 w-4"
                  />
                </Button>
                <Button
                  v-if="isMemberValid"
                  variant="outline"
                  type="button"
                  class="bg-primary"
                  size="sm"
                  @click="onSearchSep"
                >
                  <Icon
                    name="i-lucide-search"
                    class="h-4 w-4"
                  />
                </Button>
              </div>
            </DE.Field>
            <div
              v-if="isSepValid"
              class="mt-1 flex items-center gap-2"
            >
              <Icon
                name="i-lucide-badge-check"
                class="h-4 w-4 bg-green-500 text-white"
              />
              <span class="text-sm text-green-500">Aktif</span>
            </div>
            <span class="text-sm text-gray-500">
              {{ noteReference }}
            </span>
          </DE.Cell>

          <DE.Cell>
            <FileUpload
              field-name="sepFile"
              label="Dokumen SEP"
              placeholder="Pilih file"
              :accept="['pdf', 'jpg', 'png']"
              :max-size-mb="1"
              v-model="sepFile"
              v-bind="sepFileAttrs"
              @file-selected="() => {}"
            />
            <span class="mt-1 text-sm text-gray-500">
              {{ noteFile }}
            </span>
            <p v-if="sepFileReview">
              <a
                class="mt-1 text-sm text-blue-500 capitalize"
                href="#"
                @click="openFile(sepFileReview.filePath)"
              >
                {{ sepFileReview?.fileName }}
              </a>
            </p>
          </DE.Cell>

          <DE.Cell>
            <FileUpload
              field-name="sippFile"
              label="Dokumen SIPP"
              placeholder="Pilih file"
              :accept="['pdf', 'jpg', 'png']"
              :max-size-mb="1"
              v-model="sippFile"
              v-bind="sippFileAttrs"
              @file-selected="() => {}"
            />
            <span class="mt-1 text-sm text-gray-500">
              {{ noteFile }}
            </span>
            <p v-if="sippFileReview">
              <a
                class="mt-1 text-sm text-blue-500 capitalize"
                href="#"
                @click="openFile(sippFileReview.filePath)"
              >
                {{ sippFileReview?.fileName }}
              </a>
            </p>
          </DE.Cell>
        </DE.Block>
      </template>

      <template v-if="isSepValid">
        <hr />
        <!-- Data SEP -->
        <h3 class="text-lg font-semibold">Data SEP</h3>

        <DE.Block
          labelSize="thin"
          class="!pt-0"
          :colCount="3"
          :cellFlex="false"
        >
          <DE.Cell>
            <Label height="compact">Dengan Rujukan / Surat Kontrol</Label>
            <DE.Field>
              <Input
                id="sepReference"
                v-model="sepReference"
                :disabled="true"
              />
            </DE.Field>
          </DE.Cell>

          <DE.Cell>
            <Label height="compact">No. Rujukan / Surat Kontrol</Label>
            <DE.Field>
              <Input
                id="sepReference"
                v-model="sepNumber"
                :disabled="true"
              />
            </DE.Field>
          </DE.Cell>

          <DE.Cell>
            <Label height="compact">
              Tanggal Rujukan / Surat Kontrol
              <span class="ml-1 text-red-500">*</span>
            </Label>
            <DE.Field>
              <DatepickerSingle
                id="sepControlDate"
                v-model="sepControlDate"
                :disabled="true"
                placeholder="Pilih tanggal sep"
              />
            </DE.Field>
          </DE.Cell>
        </DE.Block>

        <DE.Block
          labelSize="thin"
          class="!pt-0"
          :colCount="3"
          :cellFlex="false"
        >
          <DE.Cell :col-span="2">
            <Label height="compact">Diagnosis</Label>
            <DE.Field>
              <Input
                id="diagnosis"
                v-model="diagnosis"
                :disabled="true"
              />
            </DE.Field>
          </DE.Cell>

          <DE.Cell>
            <Label height="compact">Status Kecelakaan</Label>
            <DE.Field>
              <Input
                id="sepTrafficStatus"
                v-model="sepTrafficStatus"
                :disabled="true"
              />
            </DE.Field>
          </DE.Cell>
        </DE.Block>
      </template>
    </form>
  </div>
</template>
