package schedule_dialysis

import (
	"Xcx_New/models"
	p_service "Xcx_New/service"
	"Xcx_New/utils"
	"fmt"
	"time"

	"github.com/jinzhu/gorm"
)

func GetSchedules(orgID int64, schIDs []string) ([]*ScheduleVM, error) {
	recordDateStr := time.Now().Format("2006-01-02")
	recordDate, _ := utils.ParseTimeStringToTime("2006-01-02", recordDateStr)
	var schedules []*ScheduleVM
	db := p_service.XTReadDB()
	err := db.Model(&ScheduleVM{}).
		Preload("Patient", "user_org_id = ? AND status = 1", orgID).
		Preload("DialysisOrder", func(db *gorm.DB) *gorm.DB {
			return db.Where("user_org_id = ? AND status = 1", orgID).Preload("DeviceNumber", "org_id = ? AND status = 1", orgID)
		}).
		Preload("Prescription", "user_org_id = ? AND status = 1", orgID).
		Preload("ReceiveAssessment", "user_org_id = ? AND status = 1", orgID).
		Preload("XtReceiveTreatmentAsses", "user_org_id = ? AND status = 1", orgID).
		Preload("AssessmentBeforeDislysis", func(db *gorm.DB) *gorm.DB {
			return db.Where("user_org_id = ? AND status = 1", orgID)
		}).
		Preload("AssessmentAfterDislysis", "user_org_id = ? AND status = 1", orgID).
		Preload("LastAfterWeight", func(db *gorm.DB) *gorm.DB {
			return db.Where("user_org_id = ? and status = 1 and assessment_date < ?", orgID, recordDate.Unix())
		}).Preload("MonitoringRecords", func(db *gorm.DB) *gorm.DB {
		return db.Where("user_org_id = ? AND status = 1", orgID).
			Order("operate_time asc")
	}).
		Preload("DeviceNumber", "org_id = ? AND status = 1", orgID).
		Preload("DeviceZone", "org_id = ? AND status = 1", orgID).
		Preload("DoubleCheck", "user_org_id = ? AND status = 1", orgID).
		Preload("Summer", "user_org_id = ? AND status = 1", orgID).
		Preload("Advices", func(db *gorm.DB) *gorm.DB {
			return db.Select("id, user_org_id, patient_id, advice_type, advice_date, record_date, start_time, drug_spec_unit,advice_name,advice_desc, reminder_date, drug_spec, drug_spec_unit, single_dose, single_dose_unit, prescribing_number, prescribing_number_unit, delivery_way, execution_frequency, advice_doctor, status, created_time,updated_time, advice_affirm, remark, stop_time, stop_reason, stop_doctor, stop_state, parent_id, execution_time, execution_staff, execution_state, checker, check_state, check_time, groupno, IF(parent_id > 0, parent_id, id) as advice_order").
				Where("user_org_id = ? AND advice_type = 2 AND status = 1", orgID).
				Order("start_time asc, groupno desc, advice_order desc, id asc")
		}).
		Preload("HisAdvices", func(db *gorm.DB) *gorm.DB {
			return db.Select("id, user_org_id, patient_id, advice_type, advice_date, record_date, start_time, drug_spec_unit,advice_name,advice_desc, reminder_date, drug_spec, drug_spec_unit, single_dose, single_dose_unit, prescribing_number, prescribing_number_unit, delivery_way, execution_frequency, advice_doctor, status, created_time,updated_time, advice_affirm, remark, stop_time, stop_reason, stop_doctor, stop_state, parent_id, execution_time, execution_staff, execution_state, checker, check_state, check_time, groupno, IF(parent_id > 0, parent_id, id) as advice_order").
				Where("user_org_id = ? AND status = 1", orgID).
				Order("start_time asc, groupno desc, advice_order desc, id asc")
		}).
		Preload("HisPrescriptionProject", func(db *gorm.DB) *gorm.DB {
			return db.Where("user_org_id = ? AND status = 1", orgID).Preload("HisProject").Preload("GoodInfo", "status=1")
		}).
		Where("user_org_id = ? AND status = 1 AND id in (?)", orgID, schIDs).Order("schedule_date desc").
		Find(&schedules).
		Error
	if err != nil {
		return nil, err
	}
	for _, item := range schedules {
		dialysis_count, _ := GetDialysisOrderCount(orgID, item.PatientID, item.ScheduleDate)
		fmt.Println(dialysis_count)
		item.Patient.TotalDialysis = dialysis_count
		fmt.Println(item.Patient.TotalDialysis)

	}
	return schedules, nil
}

func GetMedicalStaffs(orgID int64, appID int64) ([]*MedicalStaffVM, error) {
	var staffs []*MedicalStaffVM
	db := p_service.UserReadDB()
	// err := db.Table("sgj_user_admin_role as uar").
	// 	Joins("JOIN sgj_user_admin as ua ON ua.id = uar.admin_user_id").
	// 	Joins("LEFT JOIN sgj_user_admin_electronic_signature as es ON es.creator = uar.admin_user_id and es.status = 1").
	// 	Where("uar.status = 1 and uar.org_id = ? and uar.app_id = ? and uar.user_type IN (2,3) and ua.status = 1", orgID, appID).
	// 	Where("uar.status = 1 and uar.org_id = ? and uar.app_id = ? and ua.status = 1", orgID, appID).
	// 	Select("ua.id, uar.user_name as name, uar.user_type, es.url as es_url").
	// 	Scan(&staffs).
	// 	Error

	err := db.Table("sgj_user_admin_electronic_signature").
		Where("org_id=? and app_id=? and status=1", orgID, appID).
		Select("creator as id, url as es_url").Scan(&staffs).Error

	if err != nil {
		return nil, err
	}
	return staffs, nil
}

type AdminUserList struct {
	Id       int64  `json:"id"`
	Name     string `json:"name"`
	UserType int64  `json:"user_type"`
}
type AdminUserListTwo struct {
	Id       int64  `json:"id"`
	Name     string `json:"name"`
	UserType int64  `json:"user_type"`
	Url      string `json:"url"`
}

func GetAllAdminUsers(orgId int64, appid int64) (list []*AdminUserList, err error) {
	db := p_service.UserReadDB()
	err = db.Table("sgj_user_admin_role as uar").Joins("JOIN sgj_user_admin as ua ON ua.id = uar.admin_user_id").Where("uar.status=1 and uar.org_id=? and uar.app_id =? and ua.status=1", orgId, appid).Select("ua.id, uar.user_name as name, uar.user_type").Scan(&list).Error
	return
}

func GetAllName(orgId int64, appid int64) (list []AdminUserListTwo, err error) {
	db := p_service.UserReadDB()
	err = db.Table("sgj_user_admin_role as uar").Joins("left join sgj_user_admin as ua on ua.id = uar.admin_user_id").Joins("left join sgj_user_admin_electronic_signature  as e on e.creator = uar.admin_user_id").Where("uar.status=1 and uar.org_id=? and uar.app_id =? and ua.status=1 and e.status = 1 and e.org_id = ? and e.app_id = ?", orgId, appid, orgId, appid).Select("ua.id, uar.user_name as name, uar.user_type,e.url").Scan(&list).Error
	return
}

func GetPatientCoursesRecords(orgID int64, id int64) (records models.PatientDiseaseCourse, err error) {
	db := p_service.XTReadDB()
	err = db.Model(&models.PatientDiseaseCourse{}).Where("org_id = ? and id = ? and status = 1", orgID, id).Find(&records).Error
	return
}

func FindPatientWithDeviceById(orgID int64, patient_id int64, time int64) (patient models.SchedualPatient2, err error) {
	db := p_service.XTReadDB()

	err = db.Preload("DialysisSchedule", func(db *gorm.DB) *gorm.DB {
		return db.Preload("DeviceNumber", "status = 1 AND org_id = ?", orgID).
			Preload("DeviceZone", "status = 1 AND org_id = ?", orgID).
			Where("user_org_id = ? AND schedule_date = ? ", orgID, time)
	}).Where("user_org_id=? and id = ? and status=1", orgID, patient_id).First(&patient).Error
	return
}

func GetLastAfterWeight(orgID int64, patientID int64, maxDate int64) (*models.AssessmentAfterDislysis, error) {
	var record models.AssessmentAfterDislysis
	err := p_service.XTReadDB().Model(&models.AssessmentAfterDislysis{}).Where("patient_id = ? and user_org_id = ? and status = 1 and assessment_date < ?", patientID, orgID, maxDate).Order("assessment_date desc").First(&record).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		} else {
			return nil, err
		}
	}
	return &record, nil
}

//func GetAllName(orgid int64,appid int64)(sign,err error){
//
//  p_service.XTReadDB().Model(&sign).Where("org_id = ? and app_id =? and status = 1")
//
//}

func FindPrintStockGoodInfoByType(types int, startTime int64, end_time int64, orgId int64) (list []*models.StockInfo, err error) {
	db := p_service.XTReadDB()
	db = db.Model(&models.StockInfo{})
	db = db.Where("xt_good_information.org_id = ? AND xt_good_information.status = 1", orgId)
	if types == 1 {
		db = db.Joins("JOIN xt_warehouse_info AS info ON info.good_id=xt_good_information.id AND info.status = 1 AND info.org_id = ?", orgId).Group("xt_good_information.id")
		db = db.Preload("QueryWarehousingInfo", func(db *gorm.DB) *gorm.DB {
			return db.Where("xt_warehouse_info.org_id = ? AND xt_warehouse_info.status = 1", orgId).Joins("JOIN xt_warehouse AS warehouse ON warehouse.id = xt_warehouse_info.warehousing_id AND warehouse.status = 1 AND warehouse.warehousing_time >=? AND warehouse.warehousing_time<= ? AND warehouse.org_id = ?", startTime, end_time, orgId)
		})
	} else if types == 2 {
		db = db.Joins("JOIN xt_sales_return_info AS info ON info.good_id=xt_good_information.id AND info.status = 1 AND info.org_id = ?", orgId).Group("xt_good_information.id")
		db = db.Preload("QuerySalesReturnInfo", func(db *gorm.DB) *gorm.DB {
			return db.Where("xt_sales_return_info.org_id = ? AND xt_sales_return_info.status = 1", orgId).Joins("JOIN xt_sales_return AS sales ON sales.id = xt_sales_return_info.sales_return_id AND sales.status = 1 AND sales.return_time >=? AND sales.return_time<= ? AND sales.org_id = ?", startTime, end_time, orgId)
		})

	} else if types == 3 {
		db = db.Joins("JOIN xt_warehouse_out_info AS info ON info.good_id=xt_good_information.id AND info.status = 1 AND info.org_id = ?", orgId).Group("xt_good_information.id")
		db = db.Preload("QueryWarehouseOutInfo", func(db *gorm.DB) *gorm.DB {
			return db.Where("xt_warehouse_out_info.org_id = ? AND xt_warehouse_out_info.status = 1", orgId).Joins("JOIN xt_warehouse_out ON xt_warehouse_out.id = xt_warehouse_out_info.warehouse_out_id AND xt_warehouse_out.status = 1 AND xt_warehouse_out.warehouse_out_time >=? AND xt_warehouse_out.warehouse_out_time<= ? AND xt_warehouse_out.org_id = ? ", startTime, end_time, orgId)
		})

	} else if types == 4 {

		db = db.Joins("JOIN xt_cancel_stock_info AS info ON info.good_id=xt_good_information.id AND info.status = 1 AND info.org_id = ?", orgId).Group("xt_good_information.id")
		db = db.Preload("QueryCancelStockInfo", func(db *gorm.DB) *gorm.DB {
			return db.Where("xt_cancel_stock_info.org_id = ? AND xt_cancel_stock_info.status = 1", orgId).Joins("JOIN xt_cancel_stock AS cancel ON cancel.id = xt_cancel_stock_info.cancel_stock_id AND cancel.status = 1 AND cancel.return_time >=? AND cancel.return_time<= ? AND cancel.org_id = ?", startTime, end_time, orgId)
		})

	}
	db = db.Preload("GoodsType", "org_id = ? AND status = 1", orgId)
	err = db.Order("ctime desc").Find(&list).Error
	return
}

func GetOrgInfoTemplate(orgID int64) (models.GobalTemplate, error) {

	var templateInfo models.GobalTemplate
	var err error
	err = p_service.XTReadDB().Model(&models.GobalTemplate{}).Where("org_id=? and status=1", orgID).First(&templateInfo).Error
	return templateInfo, err
}

func GetDialysisOrderCount(orgID int64, patient_id int64, recordDate int64) (count int64, err error) {
	err = p_service.XTReadDB().Model(&models.DialysisOrder{}).Where("dialysis_date <= ? AND status = 1 AND stage = 2 AND user_org_id = ? AND patient_id = ?", recordDate, orgID, patient_id).Count(&count).Error
	return
}

func GetOutStockTotalCountTwo(startime int64, endtime int64, orgid int64) (autoMatic []*models.NewXtAutomaticReduceDetail, err error) {

	err = p_service.XTReadDB().Raw("SELECT good_id,SUM(b.count) as count FROM (SELECT DISTINCT x.patient_id,x.good_id,x.record_time,x.count FROM xt_automatic_reduce_detail as x WHERE x.org_id = ? and x.record_time >= ? and x.record_time<=? and `status` = 1)  as b GROUP BY good_id", orgid, startime, endtime).Scan(&autoMatic).Error

	return autoMatic, err
}

func GetCoutWareseOutInfo(startime int64, endtime int64, orgid int64) (houseOutInfo []*models.VmWarehouseOutInfo, err error) {

	db := p_service.XTReadDB().Table("xt_warehouse_out_info as x").Where("x.status  =1")
	err = db.Select("x.good_id,Sum(x.count) as count,x.remark,x.price,x.org_id").Where("x.ctime >=? and x.ctime<=? and x.org_id = ?", startime, endtime, orgid).Group("x.good_id").Scan(&houseOutInfo).Error
	return houseOutInfo, err
}

func GetGoodInfomationList(orgid int64) (goodInfo []*models.GoodInfo, err error) {

	err = p_service.XTReadDB().Where("org_id = ? and status = 1", orgid).Find(&goodInfo).Error
	return goodInfo, err
}

func GetWarehouseInfoGoodDetailPrintList(orgid int64, startime int64, endtime int64, limit int64, page int64) (info []*models.VmWarehousingInfo, err error) {
	//offset := (page - 1) * limit
	db := p_service.XTReadDB().Table("xt_warehouse_info as x").Where("x.status = 1")
	table := p_service.XTReadDB().Table("xt_good_information as t").Where("t.status = 1")
	fmt.Println(table)
	if orgid > 0 {
		db = db.Where("x.org_id = ?", orgid)
	}
	if startime > 0 {
		db = db.Where("x.ctime>=?", startime)
	}

	if endtime > 0 {
		db = db.Where("x.ctime<=?", endtime)
	}

	err = db.Select("x.id,x.warehousing_id,x.good_id,x.good_type_id,x.number,x.product_date,x.expiry_date,sum(x.warehousing_count) as warehousing_count,x.warehousing_unit,x.stock_count,x.price,x.total_price,x.dealer,x.manufacturer,x.remark,x.is_return,x.warehousing_order,x.type,x.license_number,t.good_name,t.specification_name,t.min_number,t.packing_unit").Joins("left join xt_good_information as t on t.id = x.good_id").Group("x.good_id").Scan(&info).Error
	return info, err
}

func GetWarehouseOutInfoGoodDetailPrintList(orgid int64, startime int64, endtime int64, limit int64, page int64) (auto []*models.SgjAutomaticReduceDetail, err error) {

	db := p_service.XTReadDB().Table("xt_automatic_reduce_detail as x").Where("x.status = 1")
	table := p_service.XTReadDB().Table("xt_good_information as t").Where("t.status = 1")
	fmt.Println(table)
	if orgid > 0 {
		db = db.Where("x.org_id = ?", orgid)
	}
	if startime > 0 {
		db = db.Where("x.ctime >= ?", startime)
	}
	if endtime > 0 {
		db = db.Where("x.ctime<=?", endtime)
	}
	err = db.Select("x.patient_id,x.record_time,x.good_id,sum(x.count) as count,t.good_name,t.specification_name,t.packing_unit,t.retail_price,t.packing_price").Joins("left join xt_good_information as t on t.id = x.good_id").Group("x.good_id").Scan(&auto).Error
	return auto, err

}
