package controllers

import (
	"XT_New/enums"
	"XT_New/models"
	"XT_New/service"
	"XT_New/utils"
	"encoding/json"
	"fmt"
	"github.com/astaxie/beego"
	"strconv"
	"strings"
	"time"
)

type InspectionApiController struct {
	BaseAuthAPIController
}

func InspectionApiRegistRouters() {
	beego.Router("/api/patient/inspection/list", &InspectionApiController{}, "Get:GetPatientInspections")
	beego.Router("/api/patient/inspection/reference", &InspectionApiController{}, "Get:PatientInspectionReference")
	beego.Router("/api/patient/inspection/create", &InspectionApiController{}, "Post:CreatePatientInspection")
	beego.Router("/api/patient/inspection/edit", &InspectionApiController{}, "Put:EditPatientInspection")
	beego.Router("/api/patient/inspection/delete", &InspectionApiController{}, "Delete:DeletePatientInspection")

	beego.Router("/api/patient/inspection/get", &InspectionApiController{}, "Get:GetAllPatientInspection")
	beego.Router("/api/patient/inspectioninit/get", &InspectionApiController{}, "Get:GetInitInsepction")

}

//PatientInspectionReference 请求检验检查大小项目
//[get]: /api/patient/inspection/reference
func (c *InspectionApiController) PatientInspectionReference() {
	patient, _ := c.GetInt64("patient")
	if patient <= 0 {
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
		return
	}

	adminUserInfo := c.GetAdminUserInfo()

	references, err := service.GetInspectionReference(adminUserInfo.CurrentOrgId)
	if err != nil {
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
		return
	}

	patient_info, _ := service.GetPatientByID(adminUserInfo.CurrentOrgId, patient)

	counts, err := service.GetPatientInspectionProjectCount(adminUserInfo.CurrentOrgId, patient)
	if err != nil {
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
		return
	}
	countsMap := make(map[int64]int64, 0)
	for _, count := range counts {
		countsMap[count.ProjectId] = count.Count
	}

	referenceMap := make(map[string]*models.InspectionReferenceMap, 0)

	for _, reference := range references {
		if _, exist := referenceMap[reference.Project]; !exist {
			referenceMap[reference.Project] = new(models.InspectionReferenceMap)
			referenceMap[reference.Project].Project = reference.Project
			referenceMap[reference.Project].ProjectId = reference.ProjectId
			referenceMap[reference.Project].ProjectName = reference.ProjectName
			if _, cexit := countsMap[reference.ProjectId]; cexit {
				referenceMap[reference.Project].Count = countsMap[reference.ProjectId]
			}
			referenceMap[reference.Project].InspectionReference = make([]models.InspectionReference, 0)
		}
		referenceMap[reference.Project].InspectionReference = append(referenceMap[reference.Project].InspectionReference, *reference)

	}

	reference := make([]*models.InspectionReferenceMap, 0)
	for _, item := range referenceMap {
		reference = append(reference, item)
	}

	rl := len(reference)
	for index := 0; index < rl-1; index++ {
		for jndex := 0; jndex < rl-1-index; jndex++ {
			if reference[jndex].ProjectId > reference[jndex+1].ProjectId {
				var item models.InspectionReferenceMap
				item = *reference[jndex]
				reference[jndex] = reference[jndex+1]
				reference[jndex+1] = &item
			}
		}
	}

	c.ServeSuccessJSON(map[string]interface{}{
		"reference":    reference,
		"patient_info": patient_info,
	})
	return

}

func (c *InspectionApiController) CreatePatientInspection() {
	patient, _ := c.GetInt64("patient", 0)
	remind_cycle, _ := c.GetInt64("remind_cycle", 0)

	if patient <= 0 {
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
		return
	}

	adminUserInfo := c.GetAdminUserInfo()
	patientInfo, _ := service.FindPatientById(adminUserInfo.CurrentOrgId, patient)
	if patientInfo.ID == 0 {
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodePatientNoExist)
		return
	}

	var from models.InepectionForm
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &from)
	if err != nil {
		utils.ErrorLog("%v", err)
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
		return
	}

	timeLayout := "2006-01-02 15:04:05"
	loc, _ := time.LoadLocation("Local")

	theTime, err := time.ParseInLocation(timeLayout, from.InspectDate+" 00:00:00", loc)
	if err != nil {
		utils.ErrorLog(err.Error())
		c.ServeFailJsonSend(enums.ErrorCodeParamWrong, "检验日期不正确")
		return
	}

	if len(from.FormItem) == 0 {
		c.ServeFailJsonSend(enums.ErrorCodeParamWrong, "未填写项目")
		return
	}

	date := theTime.Unix()
	insp, err := service.GetPatientInspectionByDate(adminUserInfo.CurrentOrgId, patient, date, from.ProjectId)
	if err != nil {
		utils.ErrorLog("%v", err)
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
		return
	}
	if len(insp) > 0 {
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeInspectionDateExit)
		return
	}

	inspections := make([]models.Inspection, 0)
	for _, item := range from.FormItem {
		var inspection models.Inspection
		inspection.OrgId = adminUserInfo.CurrentOrgId
		inspection.PatientId = patient
		inspection.ProjectId = from.ProjectId
		inspection.ItemId = item.ItemId
		inspection.ItemName = item.ItemName
		inspection.ProjectName = item.ProjectName
		inspection.InspectType = item.RangeType
		inspection.InspectValue = item.Value
		inspection.InspectDate = date
		inspection.Status = 1
		inspection.CreatedTime = time.Now().Unix()
		inspection.UpdatedTime = time.Now().Unix()
		inspections = append(inspections, inspection)
	}

	err = service.CreatePatientInspection(inspections)
	if err != nil {
		utils.ErrorLog("%v", err)
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeInspectionAddFail)
		return
	}

	if remind_cycle > 0 {
		infectiousRecord, _ := service.FindLastRecordDate(adminUserInfo.CurrentOrgId, patient, 14)
		fmt.Println(infectiousRecord.InspectDate)
		var record_time int64
		switch remind_cycle {
		case 1: //1个月
			ts := time.Unix(infectiousRecord.InspectDate, 0)
			record_time = ts.AddDate(0, 1, 0).Unix()
			fmt.Println(record_time)
			break
		case 2: //2个月
			ts := time.Unix(infectiousRecord.InspectDate, 0)
			record_time = ts.AddDate(0, 2, 0).Unix()
			fmt.Println(record_time)

			break
		case 3: //3个月
			ts := time.Unix(infectiousRecord.InspectDate, 0)
			record_time = ts.AddDate(0, 3, 0).Unix()
			fmt.Println(record_time)

			break
		case 4: //6个月
			ts := time.Unix(infectiousRecord.InspectDate, 0)
			record_time = ts.AddDate(0, 6, 0).Unix()
			fmt.Println(record_time)

			break
		case 5: //12个月
			ts := time.Unix(infectiousRecord.InspectDate, 0)
			record_time = ts.AddDate(0, 12, 0).Unix()
			fmt.Println(record_time)

			break
		}

		errs := service.UpDateInfectiousRecordTime(adminUserInfo.CurrentOrgId, patient, record_time, remind_cycle)
		if errs != nil {
			utils.ErrorLog("更新日期出错：%v", errs)
		}
	}

	c.ServeSuccessJSON(map[string]interface{}{
		"inspections":  inspections,
		"remind_cycle": remind_cycle,
	})
	return
}

func (c *InspectionApiController) EditPatientInspection() {
	patient, _ := c.GetInt64("patient", 0)
	remind_cycle, _ := c.GetInt64("remind_cycle", 0)

	if patient <= 0 {
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
		return
	}

	adminUserInfo := c.GetAdminUserInfo()
	patientInfo, _ := service.FindPatientById(adminUserInfo.CurrentOrgId, patient)
	if patientInfo.ID == 0 {
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodePatientNoExist)
		return
	}

	var from models.InepectionForm
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &from)
	if err != nil {
		utils.ErrorLog("%v", err)
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
		return
	}

	timeLayout := "2006-01-02 15:04:05"
	loc, _ := time.LoadLocation("Local")

	theTime, err := time.ParseInLocation(timeLayout, from.InspectDate+" 00:00:00", loc)
	if err != nil {
		utils.ErrorLog(err.Error())
		c.ServeFailJsonSend(enums.ErrorCodeParamWrong, "检验日期不正确")
		return
	}

	if len(from.FormItem) == 0 {
		c.ServeFailJsonSend(enums.ErrorCodeParamWrong, "未填写项目")
		return
	}

	date := theTime.Unix()
	insp, err := service.GetPatientInspectionByDate(adminUserInfo.CurrentOrgId, patient, date, from.ProjectId)
	if err != nil {
		utils.ErrorLog("%v", err)
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
		return
	}
	if len(insp) == 0 {
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeInspectionDateNotExit)
		return
	}
	inspMap := make(map[int64]*models.Inspection)
	for _, item := range insp {
		inspMap[item.ID] = item
	}

	addinsp := make([]models.Inspection, 0)
	editinsp := make([]models.Inspection, 0)
	noMap := make([]int64, 0)
	fmt.Println(from.FormItem)

	for _, item := range from.FormItem {
		fmt.Println(item.ID)
		if item.ID == 0 {
			var inspection models.Inspection
			inspection.OrgId = adminUserInfo.CurrentOrgId
			inspection.PatientId = patient
			inspection.ProjectId = from.ProjectId
			inspection.ItemId = item.ItemId
			inspection.ItemName = item.ItemName
			inspection.ProjectName = item.ProjectName
			inspection.InspectType = item.RangeType
			inspection.InspectValue = item.Value
			inspection.InspectDate = date
			inspection.Status = 1
			inspection.CreatedTime = time.Now().Unix()
			inspection.UpdatedTime = time.Now().Unix()
			addinsp = append(addinsp, inspection)
		} else if _, exi := inspMap[item.ID]; exi {
			fmt.Println("2222222222")
			inspection := *inspMap[item.ID]
			inspection.InspectValue = item.Value
			inspection.UpdatedTime = time.Now().Unix()
			editinsp = append(editinsp, inspection)
			noMap = append(noMap, item.ID)
		}

	}

	err = service.EditPatientInspection(addinsp, editinsp, noMap, patient, adminUserInfo.CurrentOrgId, from.ProjectId, date)
	if err != nil {
		utils.ErrorLog("%v", err)
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeInspectionEditFail)
		return
	}

	inspections := make([]models.Inspection, 0)
	inspections = append(inspections, editinsp...)
	inspections = append(inspections, addinsp...)

	if remind_cycle > 0 {
		infectiousRecord, _ := service.FindLastRecordDate(adminUserInfo.CurrentOrgId, patient, 14)
		fmt.Println(infectiousRecord.InspectDate)
		var record_time int64
		switch remind_cycle {
		case 1: //1个月
			ts := time.Unix(infectiousRecord.InspectDate, 0)
			record_time = ts.AddDate(0, 1, 0).Unix()

			break
		case 2: //2个月
			ts := time.Unix(infectiousRecord.InspectDate, 0)
			record_time = ts.AddDate(0, 2, 0).Unix()
			break
		case 3: //3个月
			ts := time.Unix(infectiousRecord.InspectDate, 0)
			record_time = ts.AddDate(0, 3, 0).Unix()
			break
		case 4: //6个月
			ts := time.Unix(infectiousRecord.InspectDate, 0)
			record_time = ts.AddDate(0, 6, 0).Unix()
			break
		case 5: //12个月
			ts := time.Unix(infectiousRecord.InspectDate, 0)
			record_time = ts.AddDate(0, 12, 0).Unix()
			break
		}
		fmt.Println(record_time)
		errs := service.UpDateInfectiousRecordTime(adminUserInfo.CurrentOrgId, patient, record_time, remind_cycle)
		if errs != nil {
			utils.ErrorLog("更新日期出错：%v", errs)
		}
	}

	c.ServeSuccessJSON(map[string]interface{}{
		"inspections":  inspections,
		"remind_cycle": remind_cycle,
	})
	return
}

func (c *InspectionApiController) DeletePatientInspection() {
	patient, _ := c.GetInt64("patient", 0)
	ProjectId, _ := c.GetInt64("project_id", 0)
	InspectDate := c.GetString("date")
	if patient <= 0 || ProjectId <= 0 || len(InspectDate) != 10 {
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
		return
	}

	timeLayout := "2006-01-02 15:04:05"
	loc, _ := time.LoadLocation("Local")

	theTime, err := time.ParseInLocation(timeLayout, InspectDate+" 00:00:00", loc)
	if err != nil {
		utils.ErrorLog(err.Error())
		c.ServeFailJsonSend(enums.ErrorCodeParamWrong, "检验日期不正确")
		return
	}

	adminUserInfo := c.GetAdminUserInfo()

	date := theTime.Unix()
	insp, err := service.GetPatientInspectionByDate(adminUserInfo.CurrentOrgId, patient, date, ProjectId)
	if err != nil {
		utils.ErrorLog("%v", err)
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
		return
	}
	if len(insp) == 0 {
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeInspectionDateNotExit)
		return
	}

	err = service.DeletePatientInspection(adminUserInfo.CurrentOrgId, patient, ProjectId, date)
	if err != nil {
		utils.ErrorLog("%v", err)
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeInspectionDeleteFail)
		return
	}

	c.ServeSuccessJSON(map[string]interface{}{
		"msg": "ok",
	})
	return
}

func (c *InspectionApiController) GetPatientInspections() {
	patient, _ := c.GetInt64("patient", 0)
	projectId, _ := c.GetInt64("project_id", 0)
	if patient <= 0 || projectId <= 0 {
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
		return
	}
	page, _ := c.GetInt64("page", 0)
	if page <= 0 {
		page = 1
	}

	adminUserInfo := c.GetAdminUserInfo()
	inspections, total, dateTime, err := service.GetPatientInspections(adminUserInfo.CurrentOrgId, patient, projectId, page)
	if err != nil {
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
		return
	}

	date := ""
	if len(inspections) > 0 {
		date = time.Unix(dateTime, 0).Format("2006-01-02 15:04")
	}

	c.ServeSuccessJSON(map[string]interface{}{
		"inspections": inspections,
		"total":       total,
		"date":        date,
	})
	return

}

func (c *InspectionApiController) GetAllPatientInspection() {
	patient, _ := c.GetInt64("patient", 0)
	projectStr := c.GetString("project")
	start_time, _ := c.GetInt64("start_time")
	end_time, _ := c.GetInt64("end_time")
	upload_type, _ := c.GetInt64("type")

	ids := strings.Split(projectStr, "-")

	if patient <= 0 {
		c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
		return
	}
	page, _ := c.GetInt64("page", 0)
	if page <= 0 {
		page = 1
	}

	adminUserInfo := c.GetAdminUserInfo()

	switch upload_type {
	case 1:
		var inspections []*models.Inspection

		for _, item := range ids {
			id, _ := strconv.ParseInt(item, 10, 64)
			inspection, _, _ := service.GetAllPatientInspection(adminUserInfo.CurrentOrgId, patient, page, id, start_time, end_time)
			//fmt.Println(err)
			//if err != nil {
			//	c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
			//	return
			//}
			for _, inspection_item := range inspection {
				inspections = append(inspections, inspection_item)
			}
		}

		c.ServeSuccessJSON(map[string]interface{}{
			"inspections": inspections,
			"type":        upload_type,
		})
		break

	case 2:
		id_one, _ := strconv.ParseInt(ids[0], 10, 64)
		id_two, _ := strconv.ParseInt(ids[1], 10, 64)
		id_three, _ := strconv.ParseInt(ids[2], 10, 64)
		inspection_one, _, _ := service.GetAllPatientInspection(adminUserInfo.CurrentOrgId, patient, page, id_one, start_time, end_time)
		inspection_two, _, _ := service.GetAllPatientInspection(adminUserInfo.CurrentOrgId, patient, page, id_two, start_time, end_time)
		inspection_three, _, _ := service.GetAllPatientInspection(adminUserInfo.CurrentOrgId, patient, page, id_three, start_time, end_time)

		c.ServeSuccessJSON(map[string]interface{}{
			"inspections_one":   inspection_one,
			"inspections_two":   inspection_two,
			"inspections_three": inspection_three,
			"type":              upload_type,
		})

		break
	case 3:
		var inspections []*models.Inspection

		for _, item := range ids {
			id, _ := strconv.ParseInt(item, 10, 64)
			inspection, _, _ := service.GetAllPatientInspection(adminUserInfo.CurrentOrgId, patient, page, id, start_time, end_time)
			//fmt.Println(err)
			//if err != nil {
			//	c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
			//	return
			//}
			for _, inspection_item := range inspection {
				inspections = append(inspections, inspection_item)
			}
		}

		c.ServeSuccessJSON(map[string]interface{}{
			"inspections": inspections,
			"type":        upload_type,
		})

		break
	case 4:
		id_one, _ := strconv.ParseInt(ids[0], 10, 64)
		id_two, _ := strconv.ParseInt(ids[1], 10, 64)
		id_three, _ := strconv.ParseInt(ids[2], 10, 64)
		id_four, _ := strconv.ParseInt(ids[3], 10, 64)
		id_five, _ := strconv.ParseInt(ids[4], 10, 64)

		inspection_one, _, _ := service.GetAllPatientInspection(adminUserInfo.CurrentOrgId, patient, page, id_one, start_time, end_time)
		inspection_two, _, _ := service.GetAllPatientInspection(adminUserInfo.CurrentOrgId, patient, page, id_two, start_time, end_time)
		inspection_three, _, _ := service.GetAllPatientInspection(adminUserInfo.CurrentOrgId, patient, page, id_three, start_time, end_time)
		inspection_four, _, _ := service.GetAllPatientInspection(adminUserInfo.CurrentOrgId, patient, page, id_four, start_time, end_time)
		inspection_five, _, _ := service.GetAllPatientInspection(adminUserInfo.CurrentOrgId, patient, page, id_five, start_time, end_time)

		c.ServeSuccessJSON(map[string]interface{}{
			"inspections_one":   inspection_one,
			"inspections_two":   inspection_two,
			"inspections_three": inspection_three,
			"inspections_four":  inspection_four,
			"inspections_five":  inspection_five,
			"type":              upload_type,
		})

		break
	case 5:
		id_one, _ := strconv.ParseInt(ids[0], 10, 64)
		id_two, _ := strconv.ParseInt(ids[1], 10, 64)
		inspection_one, _, _ := service.GetAllPatientInspection(adminUserInfo.CurrentOrgId, patient, page, id_one, start_time, end_time)
		inspection_two, _, _ := service.GetAllPatientInspection(adminUserInfo.CurrentOrgId, patient, page, id_two, start_time, end_time)

		c.ServeSuccessJSON(map[string]interface{}{
			"inspections_one": inspection_one,
			"inspections_two": inspection_two,
			"type":            upload_type,
		})

		break
	case 6:
		var inspections []*models.Inspection

		for _, item := range ids {
			id, _ := strconv.ParseInt(item, 10, 64)
			inspection, _, _ := service.GetAllPatientInspection(adminUserInfo.CurrentOrgId, patient, page, id, start_time, end_time)
			//fmt.Println(err)
			//if err != nil {
			//	c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
			//	return
			//}
			for _, inspection_item := range inspection {
				inspections = append(inspections, inspection_item)
			}
		}

		c.ServeSuccessJSON(map[string]interface{}{
			"inspections": inspections,
			"type":        upload_type,
		})

		break
	case 7:
		var inspections []*models.Inspection

		for _, item := range ids {
			id, _ := strconv.ParseInt(item, 10, 64)
			inspection, _, _ := service.GetAllPatientInspection(adminUserInfo.CurrentOrgId, patient, page, id, start_time, end_time)
			//fmt.Println(err)
			//if err != nil {
			//	c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
			//	return
			//}
			for _, inspection_item := range inspection {
				inspections = append(inspections, inspection_item)
			}
		}

		c.ServeSuccessJSON(map[string]interface{}{
			"inspections": inspections,
			"type":        upload_type,
		})

		break

	}

	return

}

func (c *InspectionApiController) GetInitInsepction() {
	references, _ := service.GetAllInspectionReference(0)
	c.ServeSuccessJSON(map[string]interface{}{
		"references": references,
	})
	return

}
