package encounter

import (
	"errors"
	"fmt"
	"net/http"
	e "simrs-vx/internal/domain/main-entities/encounter"
	ere "simrs-vx/internal/domain/references/encounter"
	ua "simrs-vx/internal/use-case/main-use-case/ambulatory"
	ue "simrs-vx/internal/use-case/main-use-case/emergency"
	ui "simrs-vx/internal/use-case/main-use-case/inpatient"

	d "github.com/karincake/dodol"
	rw "github.com/karincake/risoles"
)

const dataValidationFail = "data-validation-fail"

func verifyClassCode(input e.CreateDto) (err error) {
	switch input.Class_Code {
	case ere.ECAmbulatory:
		_, err = ua.CheckClassCode(input.SubClass_Code)
	case ere.ECEmergency:
		_, err = ue.CheckClassCode(input.SubClass_Code)
	case ere.ECInpatient:
		_, err = ui.CheckClassCode(input.SubClass_Code)
	default:
		return errors.New("invalid encounter class code")
	}

	if err != nil {
		return
	}

	return nil
}

func validateRequestCheckout(w http.ResponseWriter, i e.DischargeDto) (valid bool) {
	if *i.Discharge_Method_Code == ere.DMCDeath && i.DeathCause == nil {
		rw.DataResponse(w, nil, d.FieldError{
			Code:    dataValidationFail,
			Message: "deathCause required if discharge_method_code is death",
		})
		return
	}
	return true
}

func validateRequestCheckIn(w http.ResponseWriter, i e.CheckinDto) (valid bool) {
	if i.Responsible_Doctor_Code == nil {
		rw.DataResponse(w, nil, d.FieldError{
			Code:    dataValidationFail,
			Message: "responsible_doctor_code required",
		})
		return
	}

	return true
}

func validateRequestSwitchUnit(w http.ResponseWriter, i e.SwitchUnitDto) (valid bool) {
	// validate poly-switch-code
	if i.PolySwitchCode == nil {
		rw.DataResponse(w, nil, d.FieldError{
			Code:    dataValidationFail,
			Message: fmt.Sprintf("polySwitchCode required"),
		})
		return
	}

	if *i.PolySwitchCode != ere.PSCConsulPoly && *i.PolySwitchCode != ere.PSCConsulExecutive {
		rw.DataResponse(w, nil, d.FieldError{
			Code:    dataValidationFail,
			Message: "invalid PolySwitchCode",
		})
	}

	if i.InternalReferences == nil {
		rw.DataResponse(w, nil, d.FieldError{
			Code:    dataValidationFail,
			Message: fmt.Sprintf("internalReferences required"),
		})
		return
	}

	for _, v := range *i.InternalReferences {
		if v.Unit_Code == nil {
			rw.DataResponse(w, nil, d.FieldError{
				Code:    dataValidationFail,
				Message: "internalReferences.unit_code required",
			})
			return
		}

		if v.Doctor_Code == nil {
			rw.DataResponse(w, nil, d.FieldError{
				Code:    dataValidationFail,
				Message: "internalReferences.doctor_code required",
			})
			return
		}
	}

	return true
}
