/*
DESCRIPTION:
Any functions that are used internally by the use-case
*/
package soapi

import (
	"encoding/json"
	"fmt"
	ere "simrs-vx/internal/domain/references/encounter"
	"strconv"
	"time"

	ercl "simrs-vx/internal/domain/references/clinical"
	erc "simrs-vx/internal/domain/references/common"

	es "simrs-vx/internal/domain/main-entities/soapi"

	etdt "simrs-vx/internal/domain/simgos-entities/t-diagnosadanterapi"
	eicd "simrs-vx/internal/domain/simgos-entities/t-icd"
	eicdcm "simrs-vx/internal/domain/simgos-entities/t-icd-cm"
	etp "simrs-vx/internal/domain/simgos-entities/t-pendaftaran"

	esyncLog "simrs-vx/internal/domain/sync-entities/log"
	esync "simrs-vx/internal/domain/sync-entities/soapi"
)

func setDataCreateTDiagnosaDanTerapi(input es.Soapi, enc *etp.TPendaftaran) (data etdt.TDiagnosaDanTerapi) {
	switch input.TypeCode {
	case ercl.STCEEarlyMedic:
		data.Idxdaftar = enc.Idxdaftar
		data.Nomr = enc.Nomr
		data.Kdpoly = enc.Kdpoly
		data.Kddokter = enc.Kddokter

		if e := input.Encounter; e != nil {
			data.Tanggal = e.VisitDate
			if e.Class_Code == ere.ECAmbulatory {
				data.Rajal = 1
			}

		}

		if e := input.Employee; e != nil {
			if u := e.User; u != nil {
				data.Nip = u.Name
			}
		}

		setEarlyMedicTDT(input, &data)
		return
	}

	return
}

func setEarlyMedicTDT(input es.Soapi, data *etdt.TDiagnosaDanTerapi) {
	value := ercl.EarlyMedicValue{}
	_ = json.Unmarshal([]byte(*input.Value), &value)

	data.TekananDarah = fmt.Sprintf("%v/%v", value.SystolicBloodPressure, value.DiastolicBloodPressure)
	data.GolonganDarah = value.BloodType
	if value.BloodType == "" {
		data.GolonganDarah = "X"
	}

	data.TinggiBadan = float64(value.Height)
	data.BeratBadan = float64(value.Weight)
	data.Diagnosa = &value.EarlyMedicDiagnose
	data.Terapi = &value.Therapy
	data.Anamnesa = &value.PrimaryComplain

	// TODO : status, tindakan_mdeis (?)
	data.KunjunganBl = uint(value.EncounterStatus)
	data.KasusBl = uint(value.CaseStatus)

	data.PemeriksaanFisik = &value.PhysicalExamination
	data.RiwayatPasien = &value.CurrentDiseaseHistory

	if value.Vaccinated {
		data.SudahVaksin = "YA"
	} else {
		data.SudahVaksin = "TIDAK"
	}

	data.DenyutJantung = strconv.Itoa(value.Pulse)
	data.Pernapasan = strconv.Itoa(value.RespiratoryRate)
	data.Suhu = strconv.Itoa(value.Temperature)
	data.Sp02 = strconv.Itoa(value.SpO2)

	if o := value.ExpectedOutcome; len(o) > 0 {
		expectedOutput := []string{}
		for _, v := range o {
			expectedOutput = append(expectedOutput, v.Name)
		}

		jsonData, _ := json.Marshal(expectedOutput)
		data.TargetCapaian = string(jsonData)
	}
	return
}

func setDataIcd(input es.Soapi, enc *etp.TPendaftaran) (data []eicd.TIcd) {
	value := ercl.EarlyMedicValue{}
	_ = json.Unmarshal([]byte(*input.Value), &value)

	var (
		visitDate  time.Time
		ambulatory uint16
	)

	if e := input.Encounter; e != nil {
		visitDate = e.VisitDate
		if e.Class_Code == ere.ECAmbulatory {
			ambulatory = 1
		}

	}

	if d := value.DiagnoseSrc; len(d) > 0 {
		for _, v := range d {
			data = append(data, eicd.TIcd{
				Nomr:        enc.Nomr,
				Idxdaftar:   enc.Idxdaftar,
				Kddokter:    enc.Kddokter,
				Icd:         v.Code,
				StatusRajal: ambulatory,
				Tanggal:     visitDate,
			})
		}
	}

	return
}

func setDataIcdCm(input es.Soapi, enc *etp.TPendaftaran) (data []eicdcm.TIcdCm) {
	value := ercl.EarlyMedicValue{}
	_ = json.Unmarshal([]byte(*input.Value), &value)

	var (
		visitDate  time.Time
		ambulatory uint16
	)

	if e := input.Encounter; e != nil {
		visitDate = e.VisitDate
		if e.Class_Code == ere.ECAmbulatory {
			ambulatory = 1
		}

	}

	if p := value.ProcedureSrc; len(p) > 0 {
		for _, v := range p {
			data = append(data, eicdcm.TIcdCm{
				Nomr:        enc.Nomr,
				Idxdaftar:   enc.Idxdaftar,
				Kddokter:    enc.Kddokter,
				Icd:         &v.Code,
				StatusRajal: ambulatory,
				Tanggal:     visitDate,
			})
		}
	}

	return
}

func setDataSimxLog(input *esyncLog.SimxLogDto) (data esync.SoapiSimxLog) {
	// encode to JSON
	jsonData, _ := json.MarshalIndent(input.Payload, "", "  ")
	jsonString := string(jsonData)

	var status erc.ProcessStatusCode
	if input.IsSuccess {
		status = erc.PSCSuccess
	} else {
		status = erc.PSCFailed
		if input.ErrMessage != nil {
			data.ErrMessage = input.ErrMessage
		}
	}

	data.Value = &jsonString
	data.Date = &now
	data.Status = status

	return
}

func setDataSimxLink(simxId, simgosId uint) (data esync.SoapiLink) {
	data.Simx_Id = simxId
	data.Simgos_Id = simgosId
	return
}

func stringtouint(v string) uint {
	u, _ := strconv.Atoi(v)
	return uint(u)
}
