// Handlers
import { genCrudHandler } from '~/handlers/_handler'

// Types
import type { PatientEntity } from '~/models/patient'
import type { PaginationMeta } from '~/components/pub/my-ui/pagination/pagination.type'

// Services
import {
  postPatient as create,
  patchPatient as update,
  removePatient as remove,
  getPatientDetail,
  getPatients,
  getPatientByIdentifier,
} from '~/services/patient.service'

const isPatientsLoading = ref(false)
const patients = ref<Array<{ id: string; identity: string; number: string; bpjs: string; name: string }>>([])
const selectedPatient = ref<string>('')
const selectedPatientObject = ref<PatientEntity | null>(null)
const paginationMeta = ref<PaginationMeta>({
  recordCount: 0,
  page: 1,
  pageSize: 10,
  totalPage: 5,
  hasNext: false,
  hasPrev: false,
})

function mapPatientToRow(patient: PatientEntity) {
  const identity = patient?.person?.residentIdentityNumber || '-'
  const number = patient?.number || '-'
  const bpjs = '-'
  const name = patient?.person?.name || '-'
  return { id: patient.id ? String(patient.id) : '-', identity, number, bpjs, name }
}

function mapPaginationMetaToRow(meta: any) {
  const recordCount = meta['record_totalCount'] ? Number(meta['record_totalCount']) : 0
  const currentCount = meta['record_currentCount'] ? Number(meta['record_currentCount']) : 0
  const page = meta['page_number'] ? Number(meta['page_number']) : 1
  const pageSize = meta['page_size'] ? Number(meta['page_size']) : 10
  const totalPage = Math.ceil(recordCount / pageSize)

  return {
    recordCount,
    page,
    pageSize,
    totalPage,
    hasNext: currentCount < recordCount && page < totalPage,
    hasPrev: page > 1,
  }
}

async function getPatientsList(params: any = { 'page-size': 10 }) {
  try {
    isPatientsLoading.value = true
    patients.value = []
    paginationMeta.value = {} as PaginationMeta
    const result = await getPatients(params)
    if (result && result.success && result.body && Array.isArray(result.body.data)) {
      const meta = result.body.meta
      patients.value = result.body.data.map(mapPatientToRow)
      paginationMeta.value = mapPaginationMetaToRow(meta)
    } else {
      patients.value = [] // fallback to empty array
    }
  } catch (err) {
    console.error('Failed to fetch patients for SEP search:', err)
    patients.value = []
  } finally {
    isPatientsLoading.value = false
  }
}

async function getPatientCurrent(id: string) {
  try {
    const result = await getPatientDetail(Number(id))
    if (result && result.success && result.body && result.body.data) {
      const patient = result.body.data || null
      selectedPatientObject.value = patient
    }
  } catch (err) {
    console.error('Failed to fetch patient:', err)
  }
}

async function getPatientByIdentifierSearch(search: string) {
  try {
    isPatientsLoading.value = true
    patients.value = []
    paginationMeta.value = {} as PaginationMeta
    const result = await getPatientByIdentifier(search)
    if (result && result.success && result.body) {
      if (result.type === 'resident-identity' && result.body.data) {
        patients.value = [mapPatientToRow(result.body.data)]
      } else if (result.type === 'identity') {
        patients.value = Array.isArray(result.body.data) ? result.body.data.map(mapPatientToRow) : result.body.data ? [mapPatientToRow(result.body.data)] : []
      } else {
        const meta = result.body.meta
        patients.value = Array.isArray(result.body.data) ? result.body.data.map(mapPatientToRow) : result.body.data ? [mapPatientToRow(result.body.data)] : []
        paginationMeta.value = mapPaginationMetaToRow(meta)
      }
    } else {
      patients.value = [] // fallback to empty array
    }
  } catch (err) {
    console.error('Failed to fetch patients by identifier:', err)
    patients.value = []
  } finally {
    isPatientsLoading.value = false
  }
}

export {
  isPatientsLoading,
  patients,
  selectedPatient,
  selectedPatientObject,
  paginationMeta,
  getPatientsList,
  getPatientCurrent,
  getPatientByIdentifierSearch,
}

export const {
  recId,
  recAction,
  recItem,
  isReadonly,
  isProcessing,
  isFormEntryDialogOpen,
  isRecordConfirmationOpen,
  onResetState,
  handleActionSave,
  handleActionEdit,
  handleActionRemove,
  handleCancelForm,
} = genCrudHandler({
  create,
  update,
  remove,
})
