<script setup lang="ts">
// Components
import { Button } from '~/components/pub/ui/button'
import AppEncounterEntryForm from '~/components/app/encounter/entry-form.vue'
import AppViewPatient from '~/components/app/patient/view-patient.vue'

// Helpers
import { refDebounced } from '@vueuse/core'

// Handlers
import { getDetail as getDoctorDetail  } from '~/services/doctor.service'
import { useEncounterEntry } from '~/handlers/encounter-entry.handler'
import { genDoctor, type Doctor } from '~/models/doctor'

// Props
const props = defineProps<{
  id: number
  classCode?: 'ambulatory' | 'emergency' | 'inpatient' | 'outpatient'
  subClassCode?: 'reg' | 'rehab' | 'chemo' | 'emg' | 'eon' | 'op' | 'icu' | 'hcu' | 'vk'
  formType: string
}>()

const route = useRoute()
const formRef = ref<InstanceType<typeof AppEncounterEntryForm> | null>(null)

const {
  paymentsList,
  sepNumber,
  sepsList,
  participantGroupsList,
  specialistsTree,
  doctorsList,
  recSelectId,
  isLoadingDetail,
  formObjects,
  openPatient,
  isSepValid,
  isCheckingSep,
  isSaveDisabled,
  isSaving,
  isLoading,
  patients,
  selectedPatient,
  selectedPatientObject,
  paginationMeta,
  toNavigateSep,
  getListPath,
  handleInit,
  loadEncounterDetail,
  handleSaveEncounter,
  getPatientsList,
  getPatientCurrent,
  getPatientByIdentifierSearch,
  getIsSubspecialist,
  getValidateSepNumber,
  handleFetchDoctors,
} = useEncounterEntry(props)

const debouncedSepNumber = refDebounced(sepNumber, 500)
const selectedDoctor = ref<Doctor>(genDoctor())

provide('rec_select_id', recSelectId)
provide('table_data_loader', isLoading)

watch(debouncedSepNumber, async (newValue) => {
  await getValidateSepNumber(newValue)
})

watch(
  () => formObjects.value?.paymentType,
  (newValue) => {
    isSepValid.value = false
    if (newValue !== 'jkn') {
      sepNumber.value = ''
    }
  },
)

onMounted(async () => {
  await handleInit()
  if (props.id > 0) {
    await loadEncounterDetail()
  }
})

///// Functions
function handleSavePatient() {
  selectedPatientObject.value = null
  setTimeout(() => {
    getPatientCurrent(selectedPatient.value)
  }, 150)
}

function handleSaveClick() {
  if (formRef.value && typeof formRef.value.submitForm === 'function') {
    formRef.value.submitForm()
  }
}

function handleFetch(value?: any) {
  if (value?.subSpecialistId) {
    handleFetchDoctors(value.subSpecialistId)
  }
}

async function handleEvent(menu: string, value?: any) {
  if (menu === 'search') {
    getPatientsList({ 'page-size': 10, includes: 'person' }).then(() => {
      openPatient.value = true
    })
  } else if (menu === 'add') {
    navigateTo('/client/patient/add')
  } else if (menu === 'add-sep') {
    if (isSepValid.value) {
      return
    }
    toNavigateSep({
      isService: 'false',
      sourcePath: route.path,
      resource: `${props.classCode}-${props.subClassCode}`,
      ...value,
    })
  } else if (menu === 'sep-number-changed') {
    await getValidateSepNumber(String(value || ''))
  } else if (menu === 'save') {
    await handleSaveEncounter(value)
  } else if (menu === 'cancel') {
    navigateTo(getListPath())
  }
}

async function getDoctorInfo(value: string) {
  const resp = await getDoctorDetail(value, { includes: 'unit,specialist,subspecialist'})
  if (resp.success) {
    selectedDoctor.value = resp.body.data
    // console.log(selectedDoctor.value)
  }
}
</script>

<template>
  <div class="mb-5 border-b border-b-slate-300 pb-3 text-lg xl:text-xl">
    <Icon
      name="i-lucide-user"
      class="me-2"
    />
    <span class="font-semibold">{{ props.formType }}</span>
    Kunjungan
  </div>

  <AppEncounterEntryForm
    ref="formRef"
    :is-loading="isLoadingDetail"
    :is-sep-valid="isSepValid"
    :is-checking-sep="isCheckingSep"
    :payments="paymentsList"
    :seps="sepsList"
    :participant-groups="participantGroupsList"
    :specialists="specialistsTree"
    :doctorItems="doctorsList"
    :selectedDoctor="selectedDoctor"
    :patient="selectedPatientObject"
    :objects="formObjects"
    @on-select-doctor="getDoctorInfo"
    @event="handleEvent"
    @fetch="handleFetch"
  />

  <AppViewPatient
    v-model:open="openPatient"
    v-model:selected="selectedPatient"
    :patients="patients"
    :pagination-meta="paginationMeta"
    @fetch="
      (value) => {
        if (value.search && value.search.length >= 3) {
          // Use identifier search for specific searches (NIK, RM, etc.)
          getPatientByIdentifierSearch(value.search)
        } else {
          // Use regular search for general searches
          getPatientsList({ ...value, 'page-size': 10, includes: 'person' })
        }
      }
    "
    @save="handleSavePatient"
  />

  <!-- Footer Actions -->
  <div class="mt-6 flex justify-end gap-2 border-t border-t-slate-300 pt-4">
    <Button
      variant="outline"
      type="button"
      class="h-[40px] min-w-[120px] rounded-md border-orange-400 text-orange-400 hover:bg-green-50 hover:text-orange-400"
      @click="handleEvent('cancel')"
    >
      <Icon
        name="i-lucide-x"
        class="h-5 w-5"
      />
      Batal
    </Button>
    <Button
      type="button"
      class="h-[40px] min-w-[120px] text-white"
      :disabled="isSaveDisabled"
      @click="handleSaveClick"
    >
      <Icon
        name="i-lucide-save"
        class="h-5 w-5"
      />
      Simpan
    </Button>
  </div>
</template>
