package controllers

import (
	"Data_Upload_Api/enums"
	"Data_Upload_Api/models/sz"
	"Data_Upload_Api/service"
	"Data_Upload_Api/utils"
	"github.com/astaxie/beego"
	"github.com/jinzhu/gorm"
	"math"
	"strconv"
	"strings"
	_ "strings"
	"time"
)

type SyncController struct {
	BaseAPIController
}

func (c *SyncController) SyncToSZIC() {
	// 第一步：到上报配置表中找到深圳需要上报的机构
	sz_province, _ := beego.AppConfig.Int64("sz_province")
	sz_city, _ := beego.AppConfig.Int64("sz_city")
	configs, _ := service.FindAllDataUploadConfigOrgInfo(sz_province, sz_city, 3)
	for _, org := range configs {
		// 第二步：跟进配置，创建数据库连接
		if len(org.DbHost) > 0 && len(org.DbUser) > 0 && len(org.DbPort) > 0 && len(org.DbPass) > 0 && len(org.DbName) > 0 {
			orgDb, err := service.CreateDB(org.DbHost, org.DbPort, org.DbUser, org.DbPass, org.DbName)
			if err != nil {
				utils.ErrorLog("创建数据库连接失败:%v", err)
				c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
				return
			}
			// 第三步：开始同步数据
			c.SyncHospital(orgDb, org.OrgId, org.HospitalId, org.InstType, org.DepartmentName)

			// 第四步：关闭数据库连接
			service.CloseDB(orgDb)
		}
	}
}

// 同步医院信息
func (c *SyncController) SyncHospital(rdb *gorm.DB, org_id int64, hospital_id int64, inst_type int64, department_name string) {
	// 第一步：根据机构id获取上次同步时间
	syncLastInfo, _ := service.GetSyncTimeByOrgId(org_id, 1)
	var sync_time int64
	if syncLastInfo.ID > 0 {
		sync_time = syncLastInfo.SyncTime
	} else {
		sync_time = 0
	}

	// 第二步：跟进上次同步时间找出这个时间段内增加的数据
	org, _ := service.FindOrgData(org_id, sync_time)
	if org.ID > 0 {
		hospital := &sz.TempHdHospital{
			HospitalId:     strconv.FormatInt(hospital_id, 10),
			InstType:       strconv.FormatInt(inst_type, 10),
			DepartMentName: department_name,
			AuthorizedBeds: int64(len(org.DeviceNumber)),
			CreateTime:     time.Now(),
			UpdateTime:     time.Now(),
			Sjscsj:         time.Now(),
			Xgbz:           0,
		}
		err := service.CreateOrgRecord(hospital)
		if err == nil {
			// 第三步：同步成功后，添加同步记录
			upload := &sz.DataUpload{
				SyncType:       1,
				OrgId:          org_id,
				SyncTime:       time.Now().Unix(),
				SyncResultType: 1,
				CreateTime:     time.Now().Unix(),
				UpdateTime:     time.Now().Unix(),
			}
			err := service.CreateUploadRecord(upload)
			if err != nil {
				utils.ErrorLog("%v", err)
			}
		}
	}

}

// 同步水处理器
func (c *SyncController) SyncWMS(rdb *gorm.DB, org_id int64, hospital_id int64) {
	// 第一步：根据机构id获取上次同步时间
	syncLastInfo, _ := service.GetSyncTimeByOrgId(org_id, 22)
	var sync_time int64
	if syncLastInfo.ID > 0 {
		sync_time = syncLastInfo.SyncTime
	} else {
		sync_time = 0
	}

	//同步水处理机
	waterMachine, _ := service.FindOrgWaterMachineData(org_id, sync_time, time.Now().Unix())
	var wms []*sz.TempHdWm
	for _, item := range waterMachine {
		wm := &sz.TempHdWm{
			HospitalId:     strconv.FormatInt(hospital_id, 10),
			EquipmentId:    strconv.FormatInt(item.ID, 10),
			EquipmentBrand: item.ManufactureFactory,
			EquipmentModel: strconv.FormatInt(item.UnitType, 10),
			EnableTime:     time.Unix(item.StartDate, 0),
			DiscardedTime:  time.Unix(item.RubbishDate, 0),
			EquipmentType:  strconv.FormatInt(item.DeviceType, 10),
			CreateTime:     time.Now(),
			UpdateTime:     time.Now(),
			Sjscsj:         time.Now(),
			Xgbz:           strconv.FormatInt(0, 10),
		}

		wms = append(wms, wm)
	}

	err := service.BatchCreateWMsRecord(wms, rdb)
	if err == nil {
		// 第三步：同步成功后，添加同步记录
		upload := &sz.DataUpload{
			SyncType:       22,
			OrgId:          org_id,
			SyncTime:       time.Now().Unix(),
			SyncResultType: 1,
			CreateTime:     time.Now().Unix(),
			UpdateTime:     time.Now().Unix(),
		}
		err := service.CreateUploadRecord(upload)
		if err != nil {
			utils.ErrorLog("%v", err)
		}
	} else {
		//错误处理

	}

}

// 同步员工
func (c *SyncController) SyncStaff(rdb *gorm.DB, org_id int64, hospital_id int64) {
	// 第一步：根据机构id获取上次同步时间
	syncLastInfo, _ := service.GetSyncTimeByOrgId(org_id, 21)
	var sync_time int64
	if syncLastInfo.ID > 0 {
		sync_time = syncLastInfo.SyncTime
	} else {
		sync_time = 0
	}

	//同步员工信息
	roles, _ := service.FindOrgRolesData(org_id, sync_time, time.Now().Unix())

	//waterMachine, _ := service.FindOrgWaterMachineData(org_id, sync_time, time.Now().Unix())
	var staffs []*sz.TempHdStaff
	for _, role := range roles {
		var title string
		switch role.UserType {
		case 2:
			title = strconv.FormatInt(1, 10)
			break
		case 3:
			title = strconv.FormatInt(2, 10)
			break
		}

		staff := &sz.TempHdStaff{
			HospitalId:    strconv.FormatInt(hospital_id, 10),
			StaffId:       strconv.FormatInt(role.ID, 10),
			StaffName:     role.UserName,
			Position:      title,
			PermanentType: strconv.FormatInt(1, 10),
			CreateTime:    time.Now(),
			UpdateTime:    time.Now(),
			Sjscsj:        time.Now(),
			Xgbz:          strconv.FormatInt(0, 10),
		}
		staffs = append(staffs, staff)

	}

	err := service.BatchCreateStaffRecord(staffs, rdb)
	if err == nil {
		// 第三步：同步成功后，添加同步记录
		upload := &sz.DataUpload{
			SyncType:       21,
			OrgId:          org_id,
			SyncTime:       time.Now().Unix(),
			SyncResultType: 1,
			CreateTime:     time.Now().Unix(),
			UpdateTime:     time.Now().Unix(),
		}
		err := service.CreateUploadRecord(upload)
		if err != nil {
			utils.ErrorLog("%v", err)
		}
	} else {
		//错误处理

	}

}

// 同步病人
func (c *SyncController) SyncPatient(rdb *gorm.DB, org_id int64, hospital_id int64) {
	// 第一步：根据机构id获取上次同步时间
	syncLastInfo, _ := service.GetSyncTimeByOrgId(org_id, 15)
	var sync_time int64
	if syncLastInfo.ID > 0 {
		sync_time = syncLastInfo.SyncTime
	} else {
		sync_time = 0
	}

	//同步员工信息
	patients, _ := service.FindOrgPatientData(org_id, sync_time, time.Now().Unix())

	//waterMachine, _ := service.FindOrgWaterMachineData(org_id, sync_time, time.Now().Unix())
	var hdPatients []*sz.TempHdPatient
	for _, patient := range patients {

		idcard_year, _ := strconv.Atoi(Substr(patient.IdCardNo, 6, 4)) // 年
		idcard_mo, _ := strconv.Atoi(Substr(patient.IdCardNo, 10, 2))  // 月
		idcard_day, _ := strconv.Atoi(Substr(patient.IdCardNo, 12, 2)) // 日

		date := strconv.Itoa(idcard_year) + "-" + strconv.Itoa(idcard_mo) + "-" + strconv.Itoa(idcard_day)

		local, _ := time.LoadLocation("Local")
		birthday, _ := time.ParseInLocation("2006-01-02", date, local)

		var isCKD int

		value := strings.Index(patient.Diagnose, "慢性肾脏病")
		value2 := strings.Index(patient.Diagnose, "CKD")
		value3 := strings.Index(patient.Diagnose, "慢性肾衰竭")

		if value != -1 || value2 != -1 || value3 != -1 {
			isCKD = 1
		} else {
			isCKD = 0
		}

		p := &sz.TempHdPatient{
			HospitalId:       strconv.FormatInt(hospital_id, 10),
			PatientNk:        strconv.FormatInt(patient.ID, 10),
			CardNo:           "000000000000000000",
			CardType:         "01",
			IdNo:             patient.IdCardNo,
			IdType:           "01",
			PatientName:      patient.Name,
			Gender:           strconv.FormatInt(patient.Gender, 10),
			BornDate:         birthday,
			DiagnosisSummary: patient.Diagnose,
			IsCrf:            strconv.Itoa(isCKD),
			CreatedTime:      time.Now(),
			UpdateTime:       time.Now(),
			Sjscsj:           time.Now(),
			Xgbz:             strconv.FormatInt(0, 10),
		}

		if patient.FirstDialysisDate != 0 {
			p.DialysisStartTime = time.Unix(patient.FirstDialysisDate, 0)
		}
		if patient.HospitalFirstDialysisDate != 0 {
			p.LocalStartTime = time.Unix(patient.HospitalFirstDialysisDate, 0)
		}

		hdPatients = append(hdPatients, p)
	}

	err := service.BatchCreatePatinet(hdPatients, rdb)
	if err == nil {
		// 第三步：同步成功后，添加同步记录
		upload := &sz.DataUpload{
			SyncType:       15,
			OrgId:          org_id,
			SyncTime:       time.Now().Unix(),
			SyncResultType: 1,
			CreateTime:     time.Now().Unix(),
			UpdateTime:     time.Now().Unix(),
		}
		err := service.CreateUploadRecord(upload)
		if err != nil {
			utils.ErrorLog("%v", err)
		}
	} else {
		//错误处理

	}

}

func Substr(str string, start, length int) string {
	rs := []rune(str)
	rl := len(rs)
	end := 0
	if start < 0 {
		start = rl - 1 + start
	}
	end = start + length
	if start > end {
		start, end = end, start
	}
	if start < 0 {
		start = 0
	}
	if start > rl {
		start = rl
	}
	if end < 0 {
		end = 0
	}
	if end > rl {
		end = rl
	}
	return string(rs[start:end])

}

// 同步排班
func (c *SyncController) SyncShift(rdb *gorm.DB, org_id int64, hospital_id int64) {
	// 第一步：根据机构id获取上次同步时间
	syncLastInfo, _ := service.GetSyncTimeByOrgId(org_id, 19)
	var sync_time int64
	if syncLastInfo.ID > 0 {
		sync_time = syncLastInfo.SyncTime
	} else {
		sync_time = 0
	}

	var hdShift []*sz.TempHdShift
	schs, _ := service.FindOrgScheduleData(org_id, sync_time, time.Now().Unix())

	for _, sch := range schs {
		shift := &sz.TempHdShift{
			PsId:           strconv.FormatInt(sch.ID, 10),
			HospitalId:     strconv.FormatInt(sch.UserOrgId, 10),
			PatientNk:      strconv.FormatInt(sch.PatientId, 10),
			ScheduleDate:   time.Unix(sch.ScheduleDate, 0),
			ShiftType:      strconv.FormatInt(sch.ScheduleType, 10),
			SickbedNo:      sch.DeviceNumber.Number,
			ScheduleStatus: "1",
			CreateTime:     time.Now(),
			Sjscsj:         time.Now(),
			Xgbz:           0,
		}

		hdShift = append(hdShift, shift)
	}
	err := service.BatchCreateSchedual(hdShift, rdb)
	if err == nil {
		// 第三步：同步成功后，添加同步记录
		upload := &sz.DataUpload{
			SyncType:       19,
			OrgId:          org_id,
			SyncTime:       time.Now().Unix(),
			SyncResultType: 1,
			CreateTime:     time.Now().Unix(),
			UpdateTime:     time.Now().Unix(),
		}
		err := service.CreateUploadRecord(upload)
		if err != nil {
			utils.ErrorLog("%v", err)
		}
	} else {
		//错误处理

	}

}

// 同步处方
func (c *SyncController) SyncPs(rdb *gorm.DB, org_id int64, hospital_id int64) {
	// 第一步：根据机构id获取上次同步时间
	syncLastInfo, _ := service.GetSyncTimeByOrgId(org_id, 17)
	var sync_time int64
	if syncLastInfo.ID > 0 {
		sync_time = syncLastInfo.SyncTime
	} else {
		sync_time = 0
	}

	var hdPrescription []*sz.TempHdPs
	prescriptions, _ := service.FindOrgDialysisPrescriptionData(org_id, sync_time, time.Now().Unix())
	for _, item := range prescriptions {

		ps := &sz.TempHdPs{
			PrescribeId:   strconv.FormatInt(item.ID, 10),
			HospitalId:    strconv.FormatInt(hospital_id, 10),
			PatientNk:     strconv.FormatInt(item.PatientId, 10),
			K:             item.Kalium,
			Ca:            item.Calcium,
			Na:            item.Sodium,
			CreateTime:    time.Now(),
			Sjscsj:        time.Now(),
			Xgbz:          0,
			PrescribeTime: time.Unix(item.RecordDate, 0),
		}

		switch item.ModeId {
		case 1:
			ps.DialysisFrequency = item.AssessmentBeforeDislysis.DialysisCount
			ps.FrequencyUnit = 1
			ps.DialysisDuration = item.DialysisDuration
			ps.Hdf = "0"
			ps.Hp = "0"

			break
		case 2:
			ps.Hdf = "1"
			ps.Hp = "0"
			ps.HdfFrequency = item.AssessmentBeforeDislysis.DialysisCount
			ps.HdfFrequencyUnit = 1
			ps.HpDuration = item.DialysisDuration
			break
		case 4:
			ps.Hdf = "0"
			ps.Hp = "1"
			ps.HpFrequency = item.AssessmentBeforeDislysis.DialysisCount
			ps.HpFrequencyUnit = 1
			ps.HpDuration = item.DialysisDuration
			break
		}

		hdPrescription = append(hdPrescription, ps)
	}

	err := service.BatchCreatePs(hdPrescription, rdb)

	if err == nil {
		// 第三步：同步成功后，添加同步记录
		upload := &sz.DataUpload{
			SyncType:       17,
			OrgId:          org_id,
			SyncTime:       time.Now().Unix(),
			SyncResultType: 1,
			CreateTime:     time.Now().Unix(),
			UpdateTime:     time.Now().Unix(),
		}
		err := service.CreateUploadRecord(upload)
		if err != nil {
			utils.ErrorLog("%v", err)
		}
	} else {
		//错误处理

	}

}

// 同步处方药物
func (c *SyncController) SyncPsMedicine(rdb *gorm.DB, org_id int64, hospital_id int64) {
	// 第一步：根据机构id获取上次同步时间
	syncLastInfo, _ := service.GetSyncTimeByOrgId(org_id, 18)
	var sync_time int64
	if syncLastInfo.ID > 0 {
		sync_time = syncLastInfo.SyncTime
	} else {
		sync_time = 0
	}

	var tempPsmedicine []*sz.TempHdPsMedicine
	prescriptions, _ := service.FindOrgDialysisPrescriptionData(org_id, sync_time, time.Now().Unix())

	for _, item := range prescriptions {

		psm := &sz.TempHdPsMedicine{
			PrescribeId:    strconv.FormatInt(item.ID, 10),
			HospitalId:     strconv.FormatInt(item.UserOrgId, 10),
			MedicineTypeId: "2",
			CreatedTime:    time.Now(),
			Sjscsj:         time.Now(),
			Xgbz:           0,
		}

		switch item.Anticoagulant {
		case 1:
			psm.MedicineId = "3"

			break
		case 2:
			psm.MedicineId = "1"

			break
		case 3:
			psm.MedicineId = "2"

			break
		case 4:
			psm.MedicineId = "5"

			break
		case 5:
			psm.MedicineId = "4"

			break
		}

		tempPsmedicine = append(tempPsmedicine, psm)
	}

	err := service.BatchCreatePsm(tempPsmedicine, rdb)

	if err == nil {
		// 第三步：同步成功后，添加同步记录
		upload := &sz.DataUpload{
			SyncType:       18,
			OrgId:          org_id,
			SyncTime:       time.Now().Unix(),
			SyncResultType: 1,
			CreateTime:     time.Now().Unix(),
			UpdateTime:     time.Now().Unix(),
		}
		err := service.CreateUploadRecord(upload)
		if err != nil {
			utils.ErrorLog("%v", err)
		}
	} else {
		//错误处理

	}

}

// 同步转院信息
func (c *SyncController) SyncPatientOut(rdb *gorm.DB, org_id int64, hospital_id int64) {
	// 第一步：根据机构id获取上次同步时间
	syncLastInfo, _ := service.GetSyncTimeByOrgId(org_id, 16)
	var sync_time int64
	if syncLastInfo.ID > 0 {
		sync_time = syncLastInfo.SyncTime
	} else {
		sync_time = 0
	}

	var hdPatientOuts []*sz.TempHdPatientOut
	patients, _ := service.FindOrgPatientOutData(org_id, sync_time, time.Now().Unix())
	//
	for _, patient := range patients {

		p := &sz.TempHdPatientOut{
			HospitalId:   strconv.FormatInt(patient.UserOrgId, 10),
			PatientNk:    strconv.FormatInt(patient.ID, 10),
			SequelaeType: "99",
			CreateTime:   time.Now(),
			Sjscsj:       time.Now(),
			Xgbz:         0,
		}

		if len(patient.PatientLapseto) > 0 {
			p.SequelaeDate = time.Unix(patient.PatientLapseto[len(patient.PatientLapseto)].LapsetoTime, 0)
		}

		hdPatientOuts = append(hdPatientOuts, p)
	}

	err := service.BatchCreatePatientOut(hdPatientOuts, rdb)

	if err == nil {
		// 第三步：同步成功后，添加同步记录
		upload := &sz.DataUpload{
			SyncType:       16,
			OrgId:          org_id,
			SyncTime:       time.Now().Unix(),
			SyncResultType: 1,
			CreateTime:     time.Now().Unix(),
			UpdateTime:     time.Now().Unix(),
		}
		err := service.CreateUploadRecord(upload)
		if err != nil {
			utils.ErrorLog("%v", err)
		}
	} else {
		//错误处理

	}

}

// 同步处方信息
func (c *SyncController) SyncDoctorAdvice(rdb *gorm.DB, org_id int64, hospital_id int64) {
	// 第一步：根据机构id获取上次同步时间
	syncLastInfo, _ := service.GetSyncTimeByOrgId(org_id, 6)
	var sync_time int64
	if syncLastInfo.ID > 0 {
		sync_time = syncLastInfo.SyncTime
	} else {
		sync_time = 0
	}

	var hdDoctorAdvices []*sz.TempHdDoctorsAdvice
	dialysisPrescriptions, _ := service.FindOrgDialysisPrescriptionData(org_id, sync_time, time.Now().Unix())

	for _, dp := range dialysisPrescriptions {
		advice := &sz.TempHdDoctorsAdvice{
			MedicalOrDerId:   strconv.FormatInt(dp.ID, 10),
			HospitalId:       strconv.FormatInt(dp.UserOrgId, 10),
			DialysisId:       strconv.FormatInt(dp.DialysisOrder.ID, 10),
			OrderType:        "1",
			PatientNk:        strconv.FormatInt(dp.PatientId, 10),
			DialysisDuration: dp.DialysisDurationHour*60 + dp.DialysisDurationMinute,
			BloodVol:         int64(math.Floor(dp.BloodFlowVolume + 0/5)),
			CreateTime:       time.Now(),
			Sjscsj:           time.Now(),
			Xgbz:             0,
		}
		hdDoctorAdvices = append(hdDoctorAdvices, advice)

	}

	err := service.BatchCreateDoctorsAdvice(hdDoctorAdvices, rdb)

	if err == nil {
		// 第三步：同步成功后，添加同步记录
		upload := &sz.DataUpload{
			SyncType:       6,
			OrgId:          org_id,
			SyncTime:       time.Now().Unix(),
			SyncResultType: 1,
			CreateTime:     time.Now().Unix(),
			UpdateTime:     time.Now().Unix(),
		}
		err := service.CreateUploadRecord(upload)
		if err != nil {
			utils.ErrorLog("%v", err)
		}
	} else {
		//错误处理

	}

}

//
func (c *SyncController) SyncMiddle(rdb *gorm.DB, org_id int64, hospital_id int64) {
	// 第一步：根据机构id获取上次同步时间
	syncLastInfo, _ := service.GetSyncTimeByOrgId(org_id, 6)
	var sync_time int64
	if syncLastInfo.ID > 0 {
		sync_time = syncLastInfo.SyncTime
	} else {
		sync_time = 0
	}

	var hdMiddle []*sz.TempHdMiddle
	monitors, _ := service.FindOrgMonitorRecordData(org_id, sync_time, time.Now().Unix())

	for _, item := range monitors {

		mid := &sz.TempHdMiddle{
			HospitalId:  strconv.FormatInt(hospital_id, 10),
			DialysisId:  strconv.FormatInt(item.DialysisOrder.ID, 10),
			MonitorTime: time.Unix(item.OperateTime, 0),
			Sbp:         int64(math.Floor(item.SystolicBloodPressure + 0/5)),
			Dbp:         int64(math.Floor(item.DiastolicBloodPressure + 0/5)),
			PatientNk:   strconv.FormatInt(item.PatientId, 10),
			CreateTime:  time.Now(),
			Sjscsj:      time.Now(),
			Xgbz:        0,
		}

		hdMiddle = append(hdMiddle, mid)

	}

	err := service.BatchCreateMonitor(hdMiddle, rdb)

	if err == nil {
		// 第三步：同步成功后，添加同步记录
		upload := &sz.DataUpload{
			SyncType:       6,
			OrgId:          org_id,
			SyncTime:       time.Now().Unix(),
			SyncResultType: 1,
			CreateTime:     time.Now().Unix(),
			UpdateTime:     time.Now().Unix(),
		}
		err := service.CreateUploadRecord(upload)
		if err != nil {
			utils.ErrorLog("%v", err)
		}
	} else {
		//错误处理

	}

}
