package mobile_api_controllers

import (
	"XT_New/enums"
	"XT_New/models"
	"XT_New/service"
	"XT_New/utils"
	"fmt"
	"github.com/jinzhu/gorm"
	"time"
)

// /m/api/monitor/add [post]
// @param patient_id:int
// @param order_id?:int 透析记录 ID
// @param date?:int 日期(10位时间戳)
// @param operate_time?:int 实际测量日期(10位时间戳)
// @param time?:string 时间(hh:mm) 废弃
// @param pulse_frequency?:float 脉率(P)(次/min)
// @param breathing_rated?:float 呼吸频率(R)(次/min)
// @param systolic_bp?:float 收缩压
// @param diastolic_bp?:float 舒张压
// @param bp_type?:int 血压测量类型
// @param blood_flow_volume?:float 血流量(ml/min)
// @param venous_pressure?:float 静脉压
// @param venous_pressure_unit?:string 静脉压单位
// @param arterial_pressure?:float 动脉压
// @param transmembrane_pressure?:float 跨膜压
// @param transmembrane_pressure_unit?:string 跨膜压单位
// @param ultrafiltration_rate?:float 超滤率(ml/h)
// @param ultrafiltration_volume?:float 超滤量(ml)
// @param sodium_concentration?:float 钠浓度(mmol/L)
// @param dialysate_temperature?:float 透析液温度(℃)
// @param replacement_rate?:float 置换率(ml/min)
// @param displacement_quantity?:float 置换量(L)
// @param ktv?:float KT/V(在线)
// @param symptom?:string 症状
// @param dispose?:string 处理
// @param result?:string 结果
// @param monitoring_nurse?:int 监测人
func (this *DialysisAPIController) AddMonitorRecord() {
	patientID, _ := this.GetInt64("patient_id")
	if patientID <= 0 {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
		return
	}
	orderID, _ := this.GetInt64("order_id")
	if orderID < 0 {
		orderID = 0
	}
	date, _ := this.GetInt64("date")
	operateTime, _ := this.GetInt64("operate_time")

	// recordTime := this.GetString("time")
	if date <= 0 || operateTime <= 0 {
		date = 0
		operateTime = 0
		// recordTime = ""
	}
	fmt.Println(date)
	fmt.Println(operateTime)

	pulseFrequency, _ := this.GetFloat("pulse_frequency")
	breathingRated, _ := this.GetFloat("breathing_rated")
	systolicBP, _ := this.GetFloat("systolic_bp")
	diastolicBP, _ := this.GetFloat("diastolic_bp")
	BPType, _ := this.GetInt("bp_type")
	bloodFlowVolume, _ := this.GetFloat("blood_flow_volume")
	venousPressure, _ := this.GetFloat("venous_pressure")
	venousPressureType, _ := this.GetInt64("venous_pressure_type", 1)
	arterialPressure, _ := this.GetFloat("arterial_pressure")
	arterialPressureType, _ := this.GetInt64("arterial_pressure_type", 1)
	transmembranePressure, _ := this.GetFloat("transmembrane_pressure", 0)
	transmembranePressureType, _ := this.GetInt64("transmembrane_pressure_type", 1)
	ultrafiltrationRate, _ := this.GetFloat("ultrafiltration_rate")
	ultrafiltrationVolume, _ := this.GetFloat("ultrafiltration_volume")
	sodiumConcentration, _ := this.GetFloat("sodium_concentration")
	dialysateTemperature, _ := this.GetFloat("dialysate_temperature")
	temperature, _ := this.GetFloat("temperature")
	replacementRate, _ := this.GetFloat("replacement_rate")
	displacementQuantity, _ := this.GetFloat("displacement_quantity")
	ktv, _ := this.GetFloat("ktv")
	fmt.Println("ktv -------------------", ktv)
	symptom := this.GetString("symptom")
	dispose := this.GetString("dispose")
	conductivity, _ := this.GetFloat("conductivity")
	displacement_flow_quantity, _ := this.GetFloat("displacement_flow_quantity")
	blood_oxygen_saturation := this.GetString("blood_oxygen_saturation")
	result := this.GetString("result")
	monitoringNurse, _ := this.GetInt64("monitoring_nurse")
	heparin, _ := this.GetFloat("heparin")
	dialysate_flow, _ := this.GetFloat("dialysate_flow")
	urr := this.GetString("urr")
	blood_sugar, _ := this.GetFloat("blood_sugar")
	monitor_anticoagulant, _ := this.GetInt64("monitor_anticoagulant")
	monitor_anticoagulant_value := this.GetString("monitor_anticoagulant_value")
	adminInfo := this.GetMobileAdminUserInfo()
	patient, getPatientErr := service.MobileGetPatientById(adminInfo.Org.Id, patientID)
	if getPatientErr != nil {
		this.ErrorLog("获取患者信息失败:%v", getPatientErr)
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
		return
	} else if patient == nil {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodePatientNoExist)
		return
	}

	record := models.MonitoringRecord{
		UserOrgId:       adminInfo.Org.Id,
		PatientId:       patientID,
		DialysisOrderId: orderID,
		MonitoringDate:  date,
		OperateTime:     operateTime,
		// MonitoringTime:            recordTime,
		PulseFrequency:            pulseFrequency,
		BreathingRate:             breathingRated,
		SystolicBloodPressure:     systolicBP,
		DiastolicBloodPressure:    diastolicBP,
		BloodPressureType:         int64(BPType),
		BloodFlowVolume:           bloodFlowVolume,
		VenousPressure:            venousPressure,
		VenousPressureType:        venousPressureType,
		ArterialPressure:          arterialPressure,
		ArterialPressureType:      arterialPressureType,
		TransmembranePressure:     transmembranePressure,
		TransmembranePressureType: transmembranePressureType,
		UltrafiltrationRate:       ultrafiltrationRate,
		UltrafiltrationVolume:     ultrafiltrationVolume,
		SodiumConcentration:       sodiumConcentration,
		DialysateTemperature:      dialysateTemperature,
		Temperature:               temperature,
		ReplacementRate:           replacementRate,
		DisplacementQuantity:      displacementQuantity,
		Ktv:                       ktv,
		Symptom:                   symptom,
		Dispose:                   dispose,
		Result:                    result,
		MonitoringNurse:           monitoringNurse,
		Status:                    1,
		CreatedTime:               time.Now().Unix(),
		UpdatedTime:               time.Now().Unix(),
		Conductivity:              conductivity,
		DisplacementFlowQuantity:  displacement_flow_quantity,
		BloodOxygenSaturation:     blood_oxygen_saturation,
		Creator:                   adminInfo.AdminUser.Id,
		Modify:                    0,
		Heparin:                   heparin,
		DialysateFlow:             dialysate_flow,
		Urr:                       urr,
		BloodSugar:                blood_sugar,
		MonitorAnticoagulant:      monitor_anticoagulant,
		MonitorAnticoagulantValue: monitor_anticoagulant_value,
	}

	err := service.CreateMonitor(&record)
	if err != nil {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeMonitorCreate)
		return
	}

	this.ServeSuccessJSON(map[string]interface{}{
		"monitor": record,
	})
}

// /m/api/monitor/edit [post]
// @param patient_id:int
// @param order_id?:int 透析记录 ID
// @param date?:int 日期(10位时间戳)
// @param operate_time?:int 实际测量日期(10位时间戳)
// @param time?:string 时间(hh:mm)废弃
// @param pulse_frequency?:float 脉率(P)(次/min)
// @param breathing_rated?:float 呼吸频率(R)(次/min)
// @param systolic_bp?:float 收缩压
// @param diastolic_bp?:float 舒张压
// @param bp_type?:int 血压测量类型
// @param blood_flow_volume?:float 血流量(ml/min)
// @param venous_pressure?:float 静脉压
// @param venous_pressure_unit?:string 静脉压单位
// @param arterial_pressure?:float 动脉压
// @param transmembrane_pressure?:float 跨膜压
// @param transmembrane_pressure_unit?:string 跨膜压单位
// @param ultrafiltration_rate?:float 超滤率(ml/h)
// @param ultrafiltration_volume?:float 超滤量(ml)
// @param sodium_concentration?:float 钠浓度(mmol/L)
// @param dialysate_temperature?:float 透析液温度(℃)
// @param replacement_rate?:float 置换率(ml/min)
// @param displacement_quantity?:float 置换量(L)
// @param ktv?:float KT/V(在线)
// @param symptom?:string 症状
// @param dispose?:string 处理
// @param result?:string 结果
// @param monitoring_nurse?:int 监测人
func (this *DialysisAPIController) EditMonitorRecord() {
	patientID, _ := this.GetInt64("patient_id")
	if patientID <= 0 {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
		return
	}
	id, _ := this.GetInt64("id")
	if id <= 0 {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
		return
	}
	orderID, _ := this.GetInt64("order_id")
	if orderID < 0 {
		orderID = 0
	}
	date, _ := this.GetInt64("date")
	operateTime, _ := this.GetInt64("operate_time")
	if date <= 0 {
		date = 0
		operateTime = 0
	}
	pulseFrequency, _ := this.GetFloat("pulse_frequency")
	breathingRated, _ := this.GetFloat("breathing_rated")
	systolicBP, _ := this.GetFloat("systolic_bp")
	diastolicBP, _ := this.GetFloat("diastolic_bp")
	BPType, _ := this.GetInt("bp_type")
	bloodFlowVolume, _ := this.GetFloat("blood_flow_volume")
	venousPressure, _ := this.GetFloat("venous_pressure")
	venousPressureType, _ := this.GetInt64("venous_pressure_type", 1)
	arterialPressure, _ := this.GetFloat("arterial_pressure")
	arterialPressureType, _ := this.GetInt64("arterial_pressure", 1)
	transmembranePressure, _ := this.GetFloat("transmembrane_pressure")
	transmembranePressureType, _ := this.GetInt64("transmembrane_pressure_type", 1)
	ultrafiltrationRate, _ := this.GetFloat("ultrafiltration_rate")
	ultrafiltrationVolume, _ := this.GetFloat("ultrafiltration_volume")
	sodiumConcentration, _ := this.GetFloat("sodium_concentration")
	dialysateTemperature, _ := this.GetFloat("dialysate_temperature")
	temperature, _ := this.GetFloat("temperature")
	replacementRate, _ := this.GetFloat("replacement_rate")
	displacementQuantity, _ := this.GetFloat("displacement_quantity")
	ktv, _ := this.GetFloat("ktv")
	symptom := this.GetString("symptom")
	dispose := this.GetString("dispose")
	result := this.GetString("result")
	blood_oxygen_saturation := this.GetString("blood_oxygen_saturation")
	monitoringNurse, _ := this.GetInt64("monitoring_nurse")
	conductivity, _ := this.GetFloat("conductivity")
	displacement_flow_quantity, _ := this.GetFloat("displacement_flow_quantity")
	heparin, _ := this.GetFloat("heparin")
	dialysate_flow, _ := this.GetFloat("dialysate_flow")
	urr := this.GetString("urr")
	blood_sugar, _ := this.GetFloat("blood_sugar")
	adminInfo := this.GetMobileAdminUserInfo()
	monitor_anticoagulant, _ := this.GetInt64("monitor_anticoagulant")
	monitor_anticoagulant_value := this.GetString("monitor_anticoagulant_value")
	monitor, err := service.GetMonitor(adminInfo.Org.Id, patientID, id)
	if err != nil {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
		return
	}
	if monitor == nil {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeMonitorNotExist)
		return
	}

	monitor.Conductivity = conductivity
	monitor.DialysisOrderId = orderID
	monitor.MonitoringDate = date
	monitor.OperateTime = operateTime
	monitor.PulseFrequency = pulseFrequency
	monitor.BreathingRate = breathingRated
	monitor.SystolicBloodPressure = systolicBP
	monitor.DiastolicBloodPressure = diastolicBP
	monitor.BloodPressureType = int64(BPType)
	monitor.BloodFlowVolume = bloodFlowVolume
	monitor.VenousPressure = venousPressure
	monitor.VenousPressureType = venousPressureType
	monitor.ArterialPressure = arterialPressure
	monitor.ArterialPressureType = arterialPressureType
	monitor.TransmembranePressure = transmembranePressure
	monitor.TransmembranePressureType = transmembranePressureType
	monitor.UltrafiltrationRate = ultrafiltrationRate
	monitor.UltrafiltrationVolume = ultrafiltrationVolume
	monitor.SodiumConcentration = sodiumConcentration
	monitor.DialysateTemperature = dialysateTemperature
	monitor.Temperature = temperature
	monitor.ReplacementRate = replacementRate
	monitor.DisplacementQuantity = displacementQuantity
	monitor.Ktv = ktv
	monitor.Symptom = symptom
	monitor.Dispose = dispose
	monitor.Result = result
	monitor.MonitoringNurse = monitoringNurse
	monitor.Status = 1
	monitor.UpdatedTime = time.Now().Unix()
	monitor.DisplacementFlowQuantity = displacement_flow_quantity
	monitor.BloodOxygenSaturation = blood_oxygen_saturation
	monitor.Modify = adminInfo.AdminUser.Id
	monitor.Heparin = heparin
	monitor.DialysateFlow = dialysate_flow
	monitor.Urr = urr
	monitor.BloodSugar = blood_sugar
	monitor.MonitorAnticoagulant = monitor_anticoagulant
	monitor.MonitorAnticoagulantValue = monitor_anticoagulant_value
	err = service.UpdateMonitor(monitor)
	if err != nil {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeMonitorUpdate)
		return
	}

	this.ServeSuccessJSON(map[string]interface{}{
		"monitor": monitor,
	})
}

// /m/api/monitor/delete [post]
// @param record_id:int
// @param patient_id:int
func (this *DialysisAPIController) DeleteMonitor() {
	recordID, _ := this.GetInt64("record_id")
	patientID, _ := this.GetInt64("patient_id")
	if recordID <= 0 || patientID <= 0 {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
		return
	}
	adminInfo := this.GetMobileAdminUserInfo()
	patient, getPatientErr := service.MobileGetPatientById(adminInfo.Org.Id, patientID)
	if getPatientErr != nil {
		this.ErrorLog("获取患者信息失败:%v", getPatientErr)
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
		return
	} else if patient == nil {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodePatientNoExist)
		return
	}

	monitor, getMonitorErr := service.GetMonitor(adminInfo.Org.Id, patientID, recordID)
	if getMonitorErr != nil {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
		return
	}
	err := service.DisableMonitor(adminInfo.Org.Id, patientID, recordID, adminInfo.AdminUser.Id)
	if err != nil {
		this.ErrorLog("删除透析监测记录失败:%v", err)
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDBDelete)
		return
	}
	this.ServeSuccessJSON(map[string]interface{}{
		"record_id": monitor.ID,
	})
}

// /m/api/schedule/urgentinit [get]
func (this *DialysisAPIController) UrgentScheduleInitData() {
	schedule_type, _ := this.GetInt("type", 0)
	adminUserInfo := this.GetMobileAdminUserInfo()
	today := utils.ZeroHourTimeOfDay(time.Now())
	//获取所有病人且没有上机记录的病人
	patients, getPatientsErr := service.MobileGetAllPatientsForUrgentSchedule(adminUserInfo.Org.Id, today.Unix())
	if getPatientsErr != nil {
		this.ErrorLog("获取所有患者失败:%v", getPatientsErr)
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
		return
	}
	modes, getModesErr := service.MobileGetAllTrearmentModesForUrgentSchedule()
	if getModesErr != nil {
		this.ErrorLog("获取所有治疗模式失败:%v", getModesErr)
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
		return
	}
	deviceNumbers, getDeviceNumbersErr := service.GetAllAvaildDeviceNumbers(adminUserInfo.Org.Id, today.Unix(), schedule_type)
	if getDeviceNumbersErr != nil {
		this.ErrorLog("获取所有床位失败:%v", getDeviceNumbersErr)
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
		return
	}
	schedules, getSchedulesErr := service.MobileGetOtherSchedulesForUrgentSchedule(adminUserInfo.Org.Id, today.Unix(), schedule_type)
	if getSchedulesErr != nil {
		this.ErrorLog("获取所有排班失败:%v", getSchedulesErr)
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
		return
	}

	this.ServeSuccessJSON(map[string]interface{}{
		"patients":       patients,
		"modes":          modes,
		"device_numbers": deviceNumbers,
		"schedules":      schedules,
	})
}

// /m/api/schedule/urgentadd [post]
// @param patient_id:int
// @param schedule_type:int
// @param mode:int
// @param bed:int
func (this *DialysisAPIController) AddUrgentSchedule() {
	patientID, _ := this.GetInt64("patient_id")
	scheduleType, _ := this.GetInt64("schedule_type")
	modeID, _ := this.GetInt64("mode")
	bedID, _ := this.GetInt64("bed")
	if patientID <= 0 || scheduleType < 1 || scheduleType > 3 || modeID < 1 || modeID > 14 || bedID <= 0 {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
		return
	}

	adminUserInfo := this.GetMobileAdminUserInfo()
	patient, getPatientErr := service.GetPatientByID(adminUserInfo.Org.Id, patientID)
	if getPatientErr != nil {
		this.ErrorLog("获取患者信息失败:%v", getPatientErr)
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
		return
	} else if patient == nil {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodePatientNoExist)
		return
	}

	deviceNumber, getDeviceNumberErr := service.GetDeviceNumberByID(adminUserInfo.Org.Id, bedID)
	if getDeviceNumberErr != nil {
		this.ErrorLog("获取床位失败:%v", getDeviceNumberErr)
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
		return
	} else if deviceNumber == nil {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDeviceNumberNotExist)
		return
	}

	scheduleDate := utils.ZeroHourTimeOfDay(time.Now())
	weekday := int64(scheduleDate.Weekday())
	if weekday == 0 {
		weekday = 7
	}

	//判断这个人今天是否有排班
	daySchedule, dayScheduleErr := service.GetDayScheduleTwo(adminUserInfo.Org.Id, scheduleDate.Unix(), patientID)

	//判断当前时段该床位是否有排班
	schedule, err := service.GetDayScheduleByBedid(adminUserInfo.Org.Id, scheduleDate.Unix(), bedID, scheduleType)
	if dayScheduleErr == gorm.ErrRecordNotFound { //今天没有排班
		if err == gorm.ErrRecordNotFound { //空床位
			// 创建排班数据
			newSchedule := &models.Schedule{
				UserOrgId:    adminUserInfo.Org.Id,
				PartitionId:  deviceNumber.ZoneID,
				BedId:        deviceNumber.ID,
				PatientId:    patientID,
				ScheduleDate: scheduleDate.Unix(),
				ScheduleType: scheduleType,
				ScheduleWeek: weekday,
				ModeId:       modeID,
				Status:       1,
				CreatedTime:  time.Now().Unix(),
				UpdatedTime:  time.Now().Unix(),
			}
			createErr := service.CreateSchedule(newSchedule)

			if createErr != nil {
				this.ErrorLog("紧急排班失败:%v", createErr)
				this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeCreateScheduleFail)
				return
			} else {
				this.ServeSuccessJSON(map[string]interface{}{
					"schedule": newSchedule,
					"patient":  patient,
				})
			}
		} else if err == nil {
			if schedule.ID > 0 && schedule.DialysisOrder.ID == 0 { //该床位有排班没上机记录
				this.ServeFailJSONWithSGJErrorCode(enums.ErrorSchedualcRepeatBed)
			} else if schedule.ID > 0 && schedule.DialysisOrder.ID > 0 { //有排班且有上机记录
				this.ServeFailJSONWithSGJErrorCode(enums.ErrorDialysisOrderRepeatBed)
				return
			}
		} else if err != nil {
			this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
			return
		}

	} else if dayScheduleErr == nil { //今天有排班

		if daySchedule.ID > 0 && daySchedule.DialysisOrder.ID <= 0 { //今天有排班但是没上机

			if err == gorm.ErrRecordNotFound { //空床位
				// 修改了床位逻辑
				daySchedule, _ := service.GetDayScheduleTwo(adminUserInfo.Org.Id, scheduleDate.Unix(), patientID)
				if daySchedule.ID > 0 {
					daySchedule.PartitionId = deviceNumber.ZoneID
					daySchedule.BedId = bedID
					daySchedule.ModeId = modeID
					daySchedule.ScheduleType = scheduleType
					daySchedule.UpdatedTime = time.Now().Unix()
					err := service.UpdateSchedule(&daySchedule)
					if err != nil {
						this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
						return
					}
					this.ServeSuccessJSON(map[string]interface{}{
						"schedule": daySchedule,
						"patient":  patient,
					})
				}
			} else if err == nil { //该床位被人霸占
				if schedule.ID > 0 && schedule.DialysisOrder.ID == 0 { //霸占该床位的病人有排班没上机记录
					this.ServeFailJSONWithSGJErrorCode(enums.ErrorSchedualcRepeatBed)
					return
				} else if schedule.ID > 0 && schedule.DialysisOrder.ID > 0 { //霸占该床位的病人有排班且有上机记录
					this.ServeFailJSONWithSGJErrorCode(enums.ErrorDialysisOrderRepeatBed)
					return
				}
			} else if err != nil {
				this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
				return
			}

		} else if daySchedule.ID > 0 && daySchedule.DialysisOrder.ID > 0 { //今天有排班且上机
			this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodePatientDialysisOrder)
			return
		}
	}

}