package encounter

import "fmt"

type (
	EncounterClassCode    string
	QueueStatusCode       string
	DischargeMethodCode   string
	TransportationCode    string
	PersonConditionCode   string
	EmergencyClassCode    string
	OutpatientClassCode   string
	AmbulatoryClassCode   string
	InpatientClassCode    string
	ChemoClassCode        string
	AmbulanceFacilityCode string
	AmbulanceNeedsCode    string
	RefTypeCode           string
	AllPaymentMethodCode  string
	SEPRefTypeCode        string
	VisitModeCode         string
	PolySwitchCode        string
	DocTypeCode           string
	EntityTypeCode        string
)

const (
	ECAmbulatory EncounterClassCode = "ambulatory" // Rawat Jalan
	ECEmergency  EncounterClassCode = "emergency"  // Gawat Darurat
	ECInpatient  EncounterClassCode = "inpatient"  // Rawat Inap

	QSCWait   QueueStatusCode = "wait"   // Tunggu
	QSCProc   QueueStatusCode = "proc"   // Proses
	QSCDone   QueueStatusCode = "done"   // Selesai
	QSCCancel QueueStatusCode = "cancel" // Dibatalkan
	QSCSkip   QueueStatusCode = "skip"   // Dilewati

	DMCHome            DischargeMethodCode = "home"             // Pulang
	DMCHomeReq         DischargeMethodCode = "home-request"     // Pulang Atas Permintaan Sendiri
	DMCConsulBack      DischargeMethodCode = "consul-back"      // Konsultasi Balik / Lanjutan
	DMCConsulPoly      DischargeMethodCode = "consul-poly"      // Konsultasi Poliklinik Lain
	DMCConsulExecutive DischargeMethodCode = "consul-executive" // Konsultasi Antar Dokter Eksekutif
	DMCConsulChDay     DischargeMethodCode = "consul-ch-day"    // Konsultasi Hari Lain
	DMCEmergency       DischargeMethodCode = "emergency"        // Rujuk IGD
	DMCEmergencyCovid  DischargeMethodCode = "emergency-covid"  // Rujuk IGD Covid
	DMCInpatient       DischargeMethodCode = "inpatient"        // Rujuk Rawat Inap
	DMCExtRef          DischargeMethodCode = "external"         // Rujuk Faskes Lain
	DMCDeath           DischargeMethodCode = "death"            // Meninggal
	DMCDeathOnArrival  DischargeMethodCode = "death-on-arrival" // Meninggal Saat Tiba
	DMCRunAway         DischargeMethodCode = "run-away"         // Melarikan Diri

	TCAmbulance  TransportationCode = "ambulance"   // Ambulans
	TCCar        TransportationCode = "car"         // Mobil
	TCMotorCycle TransportationCode = "motor-cycle" // Motor
	TCOther      TransportationCode = "other"       // Lainnya

	PCCRes  PersonConditionCode = "res"  // Resutiasi
	PCCEmg  PersonConditionCode = "emg"  // Darurat
	PCCUrg  PersonConditionCode = "urg"  // Mendesak
	PCCLurg PersonConditionCode = "lurg" // Kurang mendesak
	PCCNurg PersonConditionCode = "nurg" // Mendesak
	PCCDoa  PersonConditionCode = "doa"  // Meninggal saat tiba

	ECCEmg EmergencyClassCode = "emg" // Darurat/Emergency biasa
	ECCEon EmergencyClassCode = "eon" // Ponek/Emergency obstetri neonatal

	OCCOp  OutpatientClassCode = "op"  // Rawat Jalan
	OCCIcu OutpatientClassCode = "icu" // ICU
	OCCHcu OutpatientClassCode = "hcu" // HCU
	OCCVk  OutpatientClassCode = "vk"  // Verlos kamer

	ACCReg AmbulatoryClassCode = "reg" // Regular
	// ACCRehab ACCRme AmbulatoryClassCode = "rme"       // Rehab Medik
	// ACCCad AmbulatoryClassCode = "chemo-adm"         // Chemotherapy
	// ACCCac AmbulatoryClassCode = "chemo-act"        // Chemotherapy
	ACCRehab AmbulatoryClassCode = "rehab" // Rehab Medik
	ACCChemo AmbulatoryClassCode = "chemo" // Rehab Medik

	ICCIp  InpatientClassCode = "ip"  // Regular Rawat Inap
	ICCICU InpatientClassCode = "icu" // ICU
	ICCHCU InpatientClassCode = "hcu" // HCU
	ICCVK  InpatientClassCode = "vk"  // Verlos kamer

	CCCAdm ChemoClassCode = "adm" // Administrasi
	CCCAct ChemoClassCode = "act" // Tindakan

	AFCStd AmbulanceFacilityCode = "std" // Standar
	AFCIcu AmbulanceFacilityCode = "icu" // ICU

	ANCAssist    AmbulanceNeedsCode = "assist"     // Dengan Pendampingan
	ANCNonassist AmbulanceNeedsCode = "non-assist" // Tanpa Pendampingan

	RTCNone    RefTypeCode = "none"    // Tidak Ada
	RTCGov     RefTypeCode = "gov"     // Pemerintah
	RTCPrivate RefTypeCode = "private" // Swasta
	RTCBpjs    RefTypeCode = "bpjs"    // BPJS

	APMCJkn  AllPaymentMethodCode = "jkn"  // JKN -> Jaminan Kesehatan Nasional -> BPJS Kesehatan
	APMCJkmm AllPaymentMethodCode = "jkmm" // JKMM -> Jaminan Kesehatan Masyarakat Miskin -> Dibiayai oleh APBD daerah
	APMCSpm  AllPaymentMethodCode = "spm"  // SPM -> Surat Pernyataan Miskin
	APMCPks  AllPaymentMethodCode = "pks"  // PKS -> Perjanjian Kerjasama -> Pembayaran melalui instansi atau perusahaan yang memiliki kontrak dengan rumah sakit
	APMCUmum AllPaymentMethodCode = "umum"

	SRTCInternal SEPRefTypeCode = "internal" // Rujukan Internal
	SRTCExternal SEPRefTypeCode = "external" // Faskes Lain

	VMCAdm    VisitModeCode = "adm"
	VMCSeries VisitModeCode = "series"

	PSCConsulPoly      PolySwitchCode = "consul-poly"      // Konsultasi Poliklinik Lain
	PSCConsulExecutive PolySwitchCode = "consul-executive" // Konsultasi Antar Dokter Eksekutif

	DTCPRN       DocTypeCode = "person-resident-number" // Person Resident Number
	DTCPDL       DocTypeCode = "person-driver-license"  // Person Driver License
	DTCPP        DocTypeCode = "person-passport"        // Person Passport
	DTCPFC       DocTypeCode = "person-family-card"     // Person Family Card
	DTCMIR       DocTypeCode = "mcu-item-result"        // Mcu Item Result
	DTCEnPatient DocTypeCode = "encounter-patient"
	DTCEnSupport DocTypeCode = "encounter-support"
	DTCEnOther   DocTypeCode = "encounter-other"
	DTCSEP       DocTypeCode = "vclaim-sep"  // SEP
	DTCSIPP      DocTypeCode = "vclaim-sipp" // SIPP
	DTCGC        DocTypeCode = "general-consent"
	DTCVSCL      DocTypeCode = "vclaim-control-letter" // vclaim control letter
	DTCResume    DocTypeCode = "resume"                // Resume
	DTCScreening DocTypeCode = "screening"             // Screening

	ETCPerson    EntityTypeCode = "person"
	ETCEncounter EntityTypeCode = "encounter"
	ETCMCU       EntityTypeCode = "mcu"
)

func (ec EncounterClassCode) Code() string {
	switch ec {
	case ECAmbulatory:
		return "AMB"
	case ECInpatient:
		return "IMP"
	case ECEmergency:
		return "EMER"
	default:
		return "UNKNOWN"
	}
}

var validUploadCodesByEntity = map[EntityTypeCode][]DocTypeCode{
	ETCPerson: {
		DTCPRN, DTCPDL, DTCPP, DTCPFC,
	},
	ETCEncounter: {
		DTCSEP, DTCSIPP, DTCEnPatient, DTCEnSupport, DTCGC, DTCEnOther,
	},
	ETCMCU: {
		DTCMIR,
	},
}

func IsValidUploadCode(entity EntityTypeCode, code DocTypeCode) (bool, string) {
	allowedCodes, ok := validUploadCodesByEntity[entity]
	if !ok {
		return false, fmt.Sprintf("unknown entityType_code: %s", entity)
	}

	for _, c := range allowedCodes {
		if c == code {
			return true, ""
		}
	}

	return false, fmt.Sprintf("invalid doctype_code '%s' for entityType_code '%s'", code, entity)
}
