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

// Types
import type { DataTableLoader } from '~/components/pub/my-ui/data-table/type'
import type { TreeItem } from '~/components/pub/my-ui/select-tree/type'

// Constants
import { paymentTypes, sepRefTypeCodes, participantGroups } from '~/lib/constants.vclaim'

// Services
import {
  getList as getSpecialistList,
  getValueTreeItems as getSpecialistTreeItems,
} from '~/services/specialist.service'
import { getValueLabelList as getDoctorValueLabelList } from '~/services/doctor.service'

// Handlers
import {
  patients,
  selectedPatient,
  selectedPatientObject,
  paginationMeta,
  getPatientsList,
  getPatientCurrent,
  getPatientByIdentifierSearch,
} from '~/handlers/patient.handler'

const props = defineProps<{
  id: number
  formType: string
}>()

const openPatient = ref(false)
const isLoading = reactive<DataTableLoader>({
  isTableLoading: false,
})
const paymentsList = ref<Array<{ value: string; label: string }>>([])
const sepsList = ref<Array<{ value: string; label: string }>>([])
const participantGroupsList = ref<Array<{ value: string; label: string }>>([])
const specialistsTree = ref<TreeItem[]>([])
const doctorsList = ref<Array<{ value: string; label: string }>>([])

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

function toKebabCase(str: string): string {
  return str.replace(/([A-Z])/g, '-$1').toLowerCase()
}

function toNavigateSep(values: any) {
  const queryParams = new URLSearchParams()
  Object.keys(values).forEach((field) => {
    if (values[field]) {
      queryParams.append(toKebabCase(field), values[field])
    }
  })
  navigateTo('/integration/bpjs/sep/add' + `?${queryParams.toString()}`)
}

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') {
    console.log('formValues', value)
    toNavigateSep({ resource: 'encounter', isService: 'false', ...value })
  } else if (menu === 'save') {
    console.log('Save encounter:', value)
  } else if (menu === 'cancel') {
    console.log('Cancel')
  }
}

async function handleFetchSpecialists() {
  try {
    const specialistsResult = await getSpecialistList({ 'page-size': 100, includes: 'subspecialists' })
    if (specialistsResult.success) {
      const specialists = specialistsResult.body?.data || []
      specialistsTree.value = getSpecialistTreeItems(specialists)
    }
  } catch (error) {
    console.error('Error fetching specialist-subspecialist tree:', error)
  }
}

/**
 * Helper function to check if a value exists in the specialistsTree
 * Returns true if it's a leaf node (subspecialist), false if parent node (specialist)
 */
function isSubspecialist(value: string, items: TreeItem[]): boolean {
  for (const item of items) {
    if (item.value === value) {
      // If this item has children, it's not selected, so skip
      // If this is the selected item, check if it has children in the tree
      return false // This means it's a specialist, not a subspecialist
    }
    if (item.children) {
      for (const child of item.children) {
        if (child.value === value) {
          // This is a subspecialist (leaf node)
          return true
        }
      }
    }
  }
  return false
}

async function handleFetchDoctors(subSpecialistId: string) {
  try {
    // Check if the selected value is a subspecialist or specialist
    const isSub = isSubspecialist(subSpecialistId, specialistsTree.value)

    // Build filter based on selection type
    const filterParams: any = { 'page-size': 100 }

    if (isSub) {
      // If selected is subspecialist, filter by subspecialist-id
      filterParams['subspecialist-id'] = subSpecialistId
    } else {
      // If selected is specialist, filter by specialist-id
      filterParams['specialist-id'] = subSpecialistId
    }

    console.log('Fetching doctors with filter:', filterParams)

    const doctors = await getDoctorValueLabelList(filterParams)
    doctorsList.value = doctors
    console.log('Fetched doctors:', doctors)
  } catch (error) {
    console.error('Error fetching doctors:', error)
    doctorsList.value = []
  }
}

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

async function handleInit() {
  paymentsList.value = Object.keys(paymentTypes).map((item) => ({
    value: item.toString(),
    label: paymentTypes[item],
  })) as any
  sepsList.value = Object.keys(sepRefTypeCodes).map((item) => ({
    value: item.toString(),
    label: sepRefTypeCodes[item],
  })) as any
  participantGroupsList.value = Object.keys(participantGroups).map((item) => ({
    value: item.toString(),
    label: participantGroups[item],
  })) as any
  // Fetch tree data
  await handleFetchSpecialists()
}

provide('table_data_loader', isLoading)

onMounted(async () => {
  await handleInit()
})
</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
    :payments="paymentsList"
    :seps="sepsList"
    :participant-groups="participantGroupsList"
    :specialists="specialistsTree"
    :doctor="doctorsList"
    :patient="selectedPatientObject"
    @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"
  />
</template>
