<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRoute } from 'vue-router'

// Components
import AppSepEntryForm from '~/components/app/sep/entry-form.vue'
import AppViewPatient from '~/components/app/sep/view-patient.vue'
import AppViewHistory from '~/components/app/sep/view-history.vue'
import { toast } from '~/components/pub/ui/toast'

// Types
import type { PaginationMeta } from '~/components/pub/my-ui/pagination/pagination.type'
import type { PatientEntity } from '~/models/patient'
import type { SepHistoryData } from '~/components/app/sep/list-cfg.history'
import type { SepVisitData } from '~/components/app/sep/list-cfg.visit'

// Constants
import {
  serviceTypes,
  serviceAssessments,
  registerMethods,
  trafficAccidents,
  supportCodes,
  procedureTypes,
  purposeOfVisits,
  classLevels,
  classLevelUpgrades,
  classPaySources,
} from '~/lib/constants.vclaim'

// Services
import { getPatientDetail, getPatients } from '~/services/patient.service'
import { getValueLabelList as getProvinceList } from '~/services/vclaim-region-province.service'
import { getValueLabelList as getCityList } from '~/services/vclaim-region-city.service'
import { getValueLabelList as getDistrictList } from '~/services/vclaim-region-district.service'
import { getValueLabelList as getDoctorLabelList } from '~/services/vclaim-doctor.service'
import { getValueLabelList as getHealthFacilityLabelList } from '~/services/vclaim-health-facility.service'
import { getValueLabelList as getDiagnoseLabelList } from '~/services/vclaim-diagnose.service'
import { getList as geMonitoringVisitList } from '~/services/vclaim-monitoring-visit.service'
import { getList as getMonitoringHistoryList } from '~/services/vclaim-monitoring-history.service'
import { create as createSep, makeSepData } from '~/services/vclaim-sep.service'

const route = useRoute()
const openPatient = ref(false)
const openLetter = ref(false)
const openHistory = ref(false)
const selectedPatient = ref('')
const selectedPatientObject = ref<PatientEntity | null>(null)
const selectedLetter = ref('SK22334442')
const selectedObjects = ref<any>({})
const selectedServiceType = ref<string>('')
const histories = ref<Array<SepHistoryData>>([])
const visits = ref<Array<SepVisitData>>([])
const patients = ref<Array<{ id: string; identity: string; number: string; bpjs: string; name: string }>>([])
const doctors = ref<Array<{ value: string | number; label: string }>>([])
const diagnoses = ref<Array<{ value: string | number; label: string }>>([])
const facilitiesFrom = ref<Array<{ value: string | number; label: string }>>([])
const facilitiesTo = ref<Array<{ value: string | number; label: string }>>([])
const supportCodesList = ref<Array<{ value: string; label: string }>>([])
const serviceTypesList = ref<Array<{ value: string; label: string }>>([])
const registerMethodsList = ref<Array<{ value: string; label: string }>>([])
const accidentsList = ref<Array<{ value: string; label: string }>>([])
const purposeOfVisitsList = ref<Array<{ value: string; label: string }>>([])
const proceduresList = ref<Array<{ value: string; label: string }>>([])
const assessmentsList = ref<Array<{ value: string; label: string }>>([])
const provincesList = ref<Array<{ value: string; label: string }>>([])
const citiesList = ref<Array<{ value: string; label: string }>>([])
const districtsList = ref<Array<{ value: string; label: string }>>([])
const classLevelsList = ref<Array<{ value: string; label: string }>>([])
const classLevelUpgradesList = ref<Array<{ value: string; label: string }>>([])
const classPaySourcesList = ref<Array<{ value: string; label: string }>>([])
const isPatientsLoading = ref(false)
const isServiceHidden = ref(false)
const isSaveLoading = ref(false)
const resourceType = ref('')
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 getMonitoringHistoryMappers() {
  histories.value = []
  const dateFirst = new Date()
  const dateLast = new Date()
  dateLast.setMonth(dateFirst.getMonth() - 3)
  const result = await getMonitoringHistoryList({
    nop: '0002078925513',
    tglawal: dateFirst.toISOString().substring(0, 10),
    tglakhir: dateLast.toISOString().substring(0, 10),
  })
  if (result && result.success && result.body) {
    const historiesRaw = result.body?.response?.histori || []
    if (!historiesRaw) return
    historiesRaw.forEach((result: any) => {
      histories.value.push({
        sepNumber: result.noSep,
        sepDate: result.tglSep,
        referralNumber: result.noRujukan,
        diagnosis:
          result.diagnosa && typeof result.diagnosa === 'string' && result.diagnosa.length > 20
            ? result.diagnosa.toString().substring(0, 17) + '...'
            : '-',
        serviceType: !result.jnsPelayanan ? '-' : result.jnsPelayanan === '1' ? 'Rawat Jalan' : 'Rawat Inap',
        careClass: result.kelasRawat,
      })
    })
  }
}

async function getMonitoringVisitMappers() {
  visits.value = []
  const dateFirst = new Date()
  const result = await geMonitoringVisitList({
    nop: '0002078925513',
    tglpelayanan: dateFirst.toISOString().substring(0, 10),
    jnspelayanan: 1,
  })
  if (result && result.success && result.body) {
    const visitsRaw = result.body?.response?.sep || []

    // "jnsPelayanan": "R.Inap",
    // "kelasRawat": "2",
    // "nama": "HANIF ABDURRAHMAN",
    // "noKartu": "0001819122189",
    // "noRujukan": "0301U01108180200084",
    // "poli": null,
    // "tglPlgSep": "2017-10-03",
    // "tglSep": "2017-10-01"

    if (!visitsRaw) return
    visitsRaw.forEach((result: any) => {
      visits.value.push({
        letterNumber: result.noRujukan,
        letterDate: result.tglSep,
        sepNumber: result.noSep,
        patientName: result.nama,
        bpjsNumber: result.noKartu,
        diagnosis: result.diagnosa,
        poly: result.poli || '-',
        serviceType: result.jnsPelayanan,
        careClass: result.kelasRawat,
      })
    })
  }
}

const letters = [
  {
    noSurat: 'SK22334442',
    tglRencana: '12 Agustus 2025',
    noSep: 'SEP3232332',
    namaPasien: 'Ahmad Baidowi',
    noBpjs: '33442331214',
    klinik: 'Penyakit Dalam',
    dokter: 'dr. Andi Prasetyo, Sp.PD-KHOM',
  },
  {
    noSurat: 'SK99120039',
    tglRencana: '12 Agustus 2025',
    noSep: 'SEP4443232',
    namaPasien: 'Bian Maulana',
    noBpjs: '33442367656',
    klinik: 'Gigi',
    dokter: 'dr. Achmad Suparjo',
  },
]

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

function handleSaveLetter() {
  console.log('Letter dipilih:', selectedLetter.value)
}

async function handleEvent(menu: string, value: any) {
  if (menu === 'admission-type') {
    console.log('service-type:', value)
    return
  }
  if (menu === 'service-type') {
    selectedServiceType.value = value
    doctors.value = await getDoctorLabelList({
      'jenis-pelayanan': selectedServiceType.value || 1,
      'tgl-pelayanan': new Date().toISOString().substring(0, 10),
      'kode-spesialis': 0,
    })
  }
  if (menu === 'search-patient') {
    getPatientsList({ 'page-size': 10, includes: 'person' }).then(() => {
      openPatient.value = true
    })
    return
  }
  if (menu === 'search-letter') {
    getMonitoringVisitMappers().then(() => {
      openLetter.value = true
    })
    return
  }
  if (menu === 'history-sep') {
    getMonitoringHistoryMappers().then(() => {
      openHistory.value = true
    })
    return
  }
  if (menu === 'back') {
    navigateTo('/integration/bpjs/sep')
  }
  if (menu === 'save-sep') {
    isSaveLoading.value = true
    createSep(makeSepData(value))
      .then((res) => {
        const body = res?.body
        const code = body?.metaData?.code
        const message = body?.metaData?.message
        if (code && code !== '200') {
          toast({ title: 'Gagal', description: message || 'Gagal membuat SEP', variant: 'destructive' })
          return
        }
        toast({ title: 'Berhasil', description: 'SEP berhasil dibuat', variant: 'default' })
        if (resourceType.value === 'encounter') {
          navigateTo('/rehab/encounter/add')
          return
        }
        navigateTo('/integration/bpjs/sep')
      })
      .catch((err) => {
        console.error('Failed to save SEP:', err)
        toast({ title: 'Gagal', description: err?.message || 'Gagal membuat SEP', variant: 'destructive' })
      })
      .finally(() => {
        isSaveLoading.value = false
      })
  }
}

async function handleFetch(params: any) {
  const menu = params.menu || ''
  const value = params.value || ''
  if (menu === 'diagnosis') {
    diagnoses.value = await getDiagnoseLabelList({ diagnosa: value })
  }
  if (menu === 'clinic-from') {
    facilitiesFrom.value = await getHealthFacilityLabelList({
      faskes: value,
      'jenis-faskes': selectedServiceType.value || 1,
    })
  }
  if (menu === 'clinic-to') {
    facilitiesTo.value = await getHealthFacilityLabelList({
      faskes: value,
      'jenis-faskes': selectedServiceType.value || 1,
    })
  }
  if (menu === 'province') {
    citiesList.value = await getCityList({ province: value })
    districtsList.value = []
  }
  if (menu === 'city') {
    districtsList.value = await getDistrictList({ city: value })
  }
}

async function handleInit() {
  const facilities = await getHealthFacilityLabelList({
    faskes: 'Puskesmas',
    'jenis-faskes': selectedLetter.value || 1,
  })
  diagnoses.value = await getDiagnoseLabelList({ diagnosa: 'paru' })
  facilitiesFrom.value = facilities
  facilitiesTo.value = facilities
  doctors.value = await getDoctorLabelList({
    'jenis-pelayanan': selectedServiceType.value || 1,
    'tgl-pelayanan': new Date().toISOString().substring(0, 10),
    'kode-spesialis': 0,
  })
  provincesList.value = await getProvinceList()
  serviceTypesList.value = Object.keys(serviceTypes).map((item) => ({
    value: item.toString(),
    label: serviceTypes[item],
  })) as any
  registerMethodsList.value = Object.keys(registerMethods)
    .filter((item) => !['4'].includes(item))
    .map((item) => ({
      value: item.toString(),
      label: registerMethods[item],
    })) as any
  accidentsList.value = Object.keys(trafficAccidents).map((item) => ({
    value: item.toString(),
    label: trafficAccidents[item],
  })) as any
  purposeOfVisitsList.value = Object.keys(purposeOfVisits).map((item) => ({
    value: item.toString(),
    label: purposeOfVisits[item],
  })) as any
  proceduresList.value = Object.keys(procedureTypes).map((item) => ({
    value: item.toString(),
    label: procedureTypes[item],
  })) as any
  assessmentsList.value = Object.keys(serviceAssessments).map((item) => ({
    value: item.toString(),
    label: `${item.toString()} - ${serviceAssessments[item]}`,
  })) as any
  supportCodesList.value = Object.keys(supportCodes).map((item) => ({
    value: item.toString(),
    label: `${item.toString()} - ${supportCodes[item]}`,
  })) as any
  classLevelsList.value = Object.keys(classLevels).map((item) => ({
    value: item.toString(),
    label: classLevels[item],
  })) as any
  classLevelUpgradesList.value = Object.keys(classLevelUpgrades).map((item) => ({
    value: item.toString(),
    label: classLevelUpgrades[item],
  })) as any
  classPaySourcesList.value = Object.keys(classPaySources).map((item) => ({
    value: item.toString(),
    label: classPaySources[item],
  })) as any
  if (route.query) {
    // resource=encounter&register-date=2025-10-23&payment-type=bpjs&bpjs-number=121212121222&sep-type=ri
    const queries = route.query as any
    isServiceHidden.value = queries['is-service'] === 'true'
    selectedObjects.value = {}
    if (queries['bpjs-number']) selectedObjects.value['bpjsNumber'] = queries['bpjs-number']
    if (queries['sep-type']) selectedObjects.value['sepType'] = queries['sep-type']
    if (queries['sep-number']) selectedObjects.value['sepNumber'] = queries['sep-number']
    if (queries['register-date']) selectedObjects.value['registerDate'] = queries['register-date']
    if (queries['doctor-id']) selectedObjects.value['doctorId'] = queries['doctor-id']
    if (queries['patient_name']) selectedObjects.value['patientName'] = queries['patient_name']
    if (queries['national_identity']) selectedObjects.value['nationalIdentity'] = queries['national_identity']
    if (queries['payment-type']) selectedObjects.value['paymentType'] = queries['payment-type']
    if (queries['medical_record_number'])
      selectedObjects.value['medicalRecordNumber'] = queries['medical_record_number']
    if (queries['resource']) resourceType.value = queries['resource']
    delete selectedObjects.value['is-service']
  }
}

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-panel-bottom"
      class="me-2"
    />
    <span class="font-semibold">Tambah</span>
    SEP
  </div>
  <AppSepEntryForm
    :doctors="doctors"
    :diagnoses="diagnoses"
    :facilities-from="facilitiesFrom"
    :facilities-to="facilitiesTo"
    :service-types="serviceTypesList"
    :register-methods="registerMethodsList"
    :accidents="accidentsList"
    :purposes="purposeOfVisitsList"
    :procedures="proceduresList"
    :assessments="assessmentsList"
    :support-codes="supportCodesList"
    :provinces="provincesList"
    :cities="citiesList"
    :districts="districtsList"
    :class-levels="classLevelsList"
    :class-level-upgrades="classLevelUpgradesList"
    :class-pay-sources="classPaySourcesList"
    :is-save-loading="isSaveLoading"
    :is-service="isServiceHidden"
    :patient="selectedPatientObject"
    :objects="selectedObjects"
    @fetch="handleFetch"
    @event="handleEvent"
  />
  <AppViewPatient
    v-model:open="openPatient"
    v-model:selected="selectedPatient"
    :patients="patients"
    :pagination-meta="paginationMeta"
    @fetch="(value) => getPatientsList({ ...value, 'page-size': 10, includes: 'person' })"
    @save="handleSavePatient"
  />
  <AppSepTableSearchLetter
    v-model:open="openLetter"
    v-model:selected="selectedLetter"
    :letters="letters"
    @save="handleSaveLetter"
  />
  <AppViewHistory
    v-model:open="openHistory"
    :histories="histories"
  />
</template>
