// 统计后台的 service

package service

import (
	"XT_New/models"
	"XT_New/models/admin_models"
	"time"

	"github.com/jinzhu/gorm"
)

func GetAdminAccount(account string, password string) (*admin_models.AdminAccount, error) {
	var model admin_models.AdminAccount
	err := readUserDb.Where("account = ? AND pwd = ? AND status = 1", account, password).First(&model).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		}
		return nil, err
	}
	return &model, nil
}

// 获取总机构数
func GetTotalOrgCount() (int, error) {
	var count int
	err := readUserDb.Model(&models.Org{}).Where("status <> 0").Count(&count).Error
	if err != nil {
		return 0, err
	}
	return count, nil
}

// 获取一段时间内注册的机构数量
func GetRegistedOrgCountFromDayToDay(from time.Time, to time.Time) (int, error) {
	var count int
	err := readUserDb.Model(&models.Org{}).Where("status <> 0 AND ctime >= ? AND ctime <= ?", from.Unix(), to.Unix()).Count(&count).Error
	if err != nil {
		return 0, err
	}
	return count, nil
}

// 获取一段时间内注册的机构
func GetRegistedOrgsFromDayToDay(from time.Time, to time.Time) ([]*models.Org, error) {
	var orgs []*models.Org
	err := readUserDb.Model(&models.Org{}).Where("status <> 0 AND ctime >= ? AND ctime <= ?", from.Unix(), to.Unix()).Find(&orgs).Error
	if err != nil {
		return nil, err
	}
	return orgs, nil
}

// 获取一段时间内的活跃机构数
func GetActiveOrgCountFromDayToDay(from time.Time, to time.Time) (int, error) {
	var count int
	rows, err := readUserDb.Raw("SELECT COUNT(DISTINCT org_id) AS count FROM sgj_user_admin_login_log WHERE ctime >= ? AND ctime <= ?", from.Unix(), to.Unix()).Rows()
	if err != nil {
		return 0, err
	}
	if rows.Next() {
		rows.Scan(&count)
	}
	return count, nil
}

type ActiveOrgListVM struct {
	models.Org
	ActiveTime int64 `gorm:"column:active_time" json:"active_time"`
}

// 获取一段时间内的活跃机构
func GetActiveOrgsFromDayToDay(from time.Time, to time.Time) ([]*ActiveOrgListVM, error) {
	var orgs []*ActiveOrgListVM
	err := readUserDb.Raw("select * from (select log.org_id, org.*, log.ctime as active_time from sgj_user_admin_login_log as log left join sgj_user_org as org on log.org_id = org.id where log.ctime >= ? AND log.ctime <= ? AND org.status <> 0 order by log.ctime desc) as t group by t.org_id;", from.Unix(), to.Unix()).Scan(&orgs).Error
	if err != nil {
		return nil, err
	}
	return orgs, nil
}

// 获取一段时间内的活跃账户数
func GetActiveAdminUserCountFromDayToDay(from time.Time, to time.Time) (int, error) {
	var count int
	rows, err := readUserDb.Raw("SELECT COUNT(DISTINCT admin_user_id) AS count FROM sgj_user_admin_login_log WHERE ctime >= ? AND ctime <= ? AND operate_type = 1", from.Unix(), to.Unix()).Rows()
	if err != nil {
		return 0, err
	}
	if rows.Next() {
		rows.Scan(&count)
	}
	return count, nil
}

type ActiveAdminUserListVM struct {
	models.App_Role
	OrgName    string `gorm:"column:org_name" json:"org_name"`
	ActiveTime int64  `gorm:"column:active_time" json:"active_time"`
}

// 获取一段时间内的活跃账户
func GetActiveAdminUsersFromDayToDay(from time.Time, to time.Time) ([]*ActiveAdminUserListVM, error) {
	var users []*ActiveAdminUserListVM
	err := readUserDb.Raw("select * from (select log.admin_user_id as uid, admin.*, org.org_name, log.ctime as active_time from sgj_user_admin_login_log as log left join sgj_user_admin_role as admin on log.admin_user_id = admin.admin_user_id left join sgj_user_org as org on log.org_id = org.id where log.ctime >= ? AND log.ctime <= ? AND log.operate_type = 1 AND admin.status > 0 order by log.ctime desc) as t group by t.uid;", from.Unix(), to.Unix()).Scan(&users).Error
	if err != nil {
		return nil, err
	}
	return users, nil
}

// 获取即将到期机构数
func GetWillExpireOrgCountFromDayToDay(from time.Time, to time.Time) (int, error) {
	var count int
	rows, err := readUserDb.Raw("SELECT COUNT(DISTINCT org_id) AS count FROM sgj_serve_subscibe WHERE period_end >= ? AND period_end <= ? AND state <> 9 GROUP BY org_id;", from.Unix(), to.Unix()).Rows()
	if err != nil {
		return 0, err
	}
	if rows.Next() {
		rows.Scan(&count)
	}
	return count, nil
}

// 获取已到期机构数
func GetDidExpiredOrgCountFromDayToDay(from time.Time, to time.Time) (int, error) {
	var count int
	rows, err := readUserDb.Raw("SELECT COUNT(DISTINCT org_id) AS count FROM sgj_serve_subscibe WHERE period_end >= ? AND period_end <= ? AND state <> 9 GROUP BY org_id;", from.Unix(), to.Unix()).Rows()
	if err != nil {
		return 0, err
	}
	if rows.Next() {
		rows.Scan(&count)
	}
	return count, nil
}

type ExpireOrgListVM struct {
	OrgID      int64  `gorm:"column:org_id" json:"org_id"`
	OrgName    string `gorm:"column:org_name" json:"org_name"`
	PeriodEnd  int64  `gorm:"column:period_end" json:"period_end"`
	Telephone  string `gorm:"column:telephone" json:"telephone"`
	ExpireDays int    `gorm:"-" json:"expire_days"`
}

// 获取即将到期机构
func GetWillExpireOrgsFromDayToDay(from time.Time, to time.Time) ([]*ExpireOrgListVM, error) {
	var vms []*ExpireOrgListVM
	err := readUserDb.Raw("select s_o.org_id, s_o.period_end, o.org_name, o.telephone from (select ss.* from (select s.org_id as org_id, s.id as sid, s.period_end from sgj_serve_subscibe as s where s.period_end <= ? AND s.period_end >= ? AND s.state <> 9 order by s.id desc) as ss group by ss.org_id) as s_o left join sgj_user_org as o on o.id = s_o.org_id", to.Unix(), from.Unix()).Scan(&vms).Error
	if err != nil {
		return nil, err
	}
	for _, vm := range vms {
		vm.ExpireDays = time.Unix(vm.PeriodEnd, 0).Day() - from.Day()
	}
	return vms, nil
}

// 获取已到期机构
func GetDidExpireOrgsFromDayToDay(from time.Time, to time.Time) ([]*ExpireOrgListVM, error) {
	var vms []*ExpireOrgListVM
	err := readUserDb.Raw("select s_o.org_id, s_o.period_end, o.org_name, o.telephone from (select ss.* from (select s.org_id as org_id, s.id as sid, s.period_end from sgj_serve_subscibe as s where s.period_end >= ? AND s.period_end <= ? AND s.state <> 9 order by s.id desc) as ss group by ss.org_id) as s_o left join sgj_user_org as o on o.id = s_o.org_id", from.Unix(), to.Unix()).Scan(&vms).Error
	if err != nil {
		return nil, err
	}
	for _, vm := range vms {
		vm.ExpireDays = to.Day() - time.Unix(vm.PeriodEnd, 0).Day()
	}
	return vms, nil
}

// 获取一段时间内的透析次数
func GetDialysisTimesFromDayToDay(from time.Time, to time.Time) (int, error) {
	var count int
	err := readDb.Model(&models.DialysisOrder{}).Where("status > 0 AND dialysis_date >= ? AND dialysis_date <= ?", from.Unix(), to.Unix()).Count(&count).Error
	if err != nil {
		return 0, err
	}
	return count, nil
}

// 获取一段时间内的监控次数
func GetMonitoringTimesFromDayToDay(from time.Time, to time.Time) (int, error) {
	var count int
	err := readDb.Model(&models.MonitoringRecord{}).Where("status > 0 AND monitoring_date >= ? AND monitoring_date <= ?", from.Unix(), to.Unix()).Count(&count).Error
	if err != nil {
		return 0, err
	}
	return count, nil
}

// 获取一段时间内新增病人数量
func GetNewPatientCountFromDayToDay(from time.Time, to time.Time) (int, error) {
	var count int
	err := readDb.Model(&models.Patients{}).Where("status > 0 AND created_time >= ? AND created_time <= ?", from.Unix(), to.Unix()).Count(&count).Error
	if err != nil {
		return 0, err
	}
	return count, nil
}

// 获取病人性别分布
func GetPatientGenderDistribution() (int, int, int, error) {
	var maleCount, femaleCount, unknowGenderCount int
	rows, err := readDb.Raw("SELECT count(id), gender FROM xt_patients WHERE (status > 0) group by gender;").Rows()
	if err != nil {
		return 0, 0, 0, err
	}
	for rows.Next() {
		var gender, count int
		rows.Scan(&count, &gender)
		if gender == 1 {
			maleCount = count
		} else if gender == 2 {
			femaleCount = count
		} else {
			unknowGenderCount = count
		}
	}
	return maleCount, femaleCount, unknowGenderCount, nil
}

// 获取某种传染病的病人数，diseaseType = 0时为没有传染病
// 1乙肝 2丙肝 3艾滋病 4肺结核 5梅毒
func GetInfectiousDiseasePatientCount(diseaseType int) (int, error) {
	if diseaseType == 0 {
		var count int
		rows, err := readDb.Raw("select count(p.id) from xt_patients as p where id not in (select p_d.patient_id from xt_patients_infectious_diseases as p_d where status = 1 group by p_d.patient_id) and status = 1;").Rows()
		if err != nil {
			return 0, err
		}
		if rows.Next() {
			rows.Scan(&count)
		}
		return count, nil

	} else {
		var count int
		rows, err := readDb.Raw("select count(distinct patient_id) from xt_patients_infectious_diseases where status = 1 and disease_id = ?;", diseaseType).Rows()
		if err != nil {
			return 0, err
		}
		if rows.Next() {
			rows.Scan(&count)
		}
		return count, nil
	}
}

// 获取患者年龄分布
func GetPatientAgeDistribution() ([]*PatientAgeCountStruct, error) {
	var counts []*PatientAgeCountStruct
	err := readDb.Raw(`SELECT nnd AS 'age',COUNT(*) AS 'count' FROM (
		SELECT
			CASE
				WHEN (YEAR(NOW())-DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y')-1) + (DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%m%d') <= DATE_FORMAT(NOW(), '%m%d'))<10 THEN '10'
				WHEN (YEAR(NOW())-DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y')-1) + (DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%m%d') <= DATE_FORMAT(NOW(), '%m%d') )>=10 AND (YEAR(NOW())-DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y')-1) + (DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%m%d') <= DATE_FORMAT(NOW(), '%m%d') )<20 THEN '20'
				WHEN (YEAR(NOW())-DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y')-1) + (DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%m%d') <= DATE_FORMAT(NOW(), '%m%d') )>=20 AND (YEAR(NOW())-DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y')-1) + (DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%m%d') <= DATE_FORMAT(NOW(), '%m%d') )<30 THEN '30'
				WHEN (YEAR(NOW())-DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y')-1) + (DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%m%d') <= DATE_FORMAT(NOW(), '%m%d') )>=30 AND (YEAR(NOW())-DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y')-1) + (DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%m%d') <= DATE_FORMAT(NOW(), '%m%d') )<40 THEN '40'
				WHEN (YEAR(NOW())-DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y')-1) + (DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%m%d') <= DATE_FORMAT(NOW(), '%m%d') )>=40 AND (YEAR(NOW())-DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y')-1) + (DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%m%d') <= DATE_FORMAT(NOW(), '%m%d') )<50 THEN '50'
				WHEN (YEAR(NOW())-DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y')-1) + (DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%m%d') <= DATE_FORMAT(NOW(), '%m%d') )>=50 AND (YEAR(NOW())-DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y')-1) + (DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%m%d') <= DATE_FORMAT(NOW(), '%m%d') )<60 THEN '60'
				WHEN (YEAR(NOW())-DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y')-1) + (DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%m%d') <= DATE_FORMAT(NOW(), '%m%d') )>=60 AND (YEAR(NOW())-DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y')-1) + (DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%m%d') <= DATE_FORMAT(NOW(), '%m%d') )<70 THEN '70'
				WHEN (YEAR(NOW())-DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y')-1) + (DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%m%d') <= DATE_FORMAT(NOW(), '%m%d') )>=70 AND (YEAR(NOW())-DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y')-1) + (DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%m%d') <= DATE_FORMAT(NOW(), '%m%d') )<80 THEN '80'
				WHEN (YEAR(NOW())-DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y')-1) + (DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%m%d') <= DATE_FORMAT(NOW(), '%m%d') )>=80 AND (YEAR(NOW())-DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y')-1) + (DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%m%d') <= DATE_FORMAT(NOW(), '%m%d') )<90 THEN '90'
				WHEN (YEAR(NOW())-DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y')-1) + (DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%m%d') <= DATE_FORMAT(NOW(), '%m%d') )>=90 AND (YEAR(NOW())-DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y')-1) + (DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%m%d') <= DATE_FORMAT(NOW(), '%m%d') )<100 THEN '100'
				ELSE '-1'
			END
		AS nnd FROM xt_patients where status=1
	) a GROUP BY nnd;`).Scan(&counts).Error
	if err != nil {
		return nil, err
	}
	return counts, nil
}

func GetAdminUserElectronicSignature(orgID int64, appID int64, userID int64) (*models.AdminUserElectronicSignature, error) {
	var es models.AdminUserElectronicSignature
	err := readUserDb.Model(&models.AdminUserElectronicSignature{}).Where("org_id=? and app_id=? and creator=? and status=1", orgID, appID, userID).First(&es).Error

	if err == gorm.ErrRecordNotFound {
		return nil, nil
	}
	if err != nil {
		return nil, err
	}
	return &es, nil
}

func CreateAdminUserElectronicSignature(es *models.AdminUserElectronicSignature) error {
	err := writeUserDb.Create(es).Error
	return err
}

func SaveAdminUserElectronicSignature(es *models.AdminUserElectronicSignature) error {
	err := writeUserDb.Save(es).Error
	return err
}

func GetAdminUserSpecialPermission(orgID int64, appID int64, adminUserID int64, permissionType models.SpecialPermissionType) (*models.AdminUserSpecialPermission, error) {
	var record models.AdminUserSpecialPermission
	err := readDb.Model(&models.AdminUserSpecialPermission{}).Where("org_id = ? AND app_id = ? AND admin_user_id = ? AND permission = ? AND status = 1", orgID, appID, adminUserID, permissionType).First(&record).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		} else {
			return nil, err
		}
	}
	return &record, nil
}

func SaveAdminUserSpecialPermission(permission *models.AdminUserSpecialPermission) error {
	err := writeDb.Save(permission).Error
	return err
}

func GetAllValidAdminUsersWithSpecialPermission(orgID int64, appID int64, permissionType models.SpecialPermissionType) ([]*models.AdminUserSpecialPermission, error) {
	var records []*models.AdminUserSpecialPermission
	err := readDb.Model(&models.AdminUserSpecialPermission{}).Where("org_id = ? AND app_id = ? AND permission = ? AND status = 1", orgID, appID, permissionType).Find(&records).Error
	if err != nil {
		return nil, err
	}
	return records, nil
}

func GetAllSpecialPermissionAdminUsersWithoutStatus(orgID int64, appID int64, permissionType models.SpecialPermissionType) ([]*models.AdminUserSpecialPermission, error) {
	var records []*models.AdminUserSpecialPermission
	err := readDb.Model(&models.AdminUserSpecialPermission{}).Where("org_id = ? AND app_id = ? AND permission = ?", orgID, appID, permissionType).Find(&records).Error
	if err != nil {
		return nil, err
	}
	return records, nil
}

func CancelAllSpecialPermissionAdminUsers(orgID int64, appID int64, permissionType models.SpecialPermissionType) error {
	tx := writeDb.Begin()
	updateTime := time.Now().Unix()
	err := tx.Model(&models.AdminUserSpecialPermission{}).Where("org_id = ? AND app_id = ? AND status = 1 AND permission = ?", orgID, appID, permissionType).Updates(map[string]interface{}{"status": 0, "mtime": updateTime}).Error
	if err != nil {
		tx.Rollback()
		return err
	}
	tx.Commit()
	return nil
}

func BatchSaveSpecialPermissionAdminUsers(users []*models.AdminUserSpecialPermission) error {
	tx := writeDb.Begin()
	for _, user := range users {
		tx.Save(user)
	}
	return tx.Commit().Error
}

func ModifyAdminUserName(name string, id int64) error {
	tx := writeUserDb.Begin()
	updateTime := time.Now().Unix()
	err := tx.Model(&models.AdminUser{}).Where("id = ?", id).Updates(map[string]interface{}{"name": name, "mtime": updateTime}).Error
	if err != nil {
		tx.Rollback()
		return err
	}
	tx.Commit()
	return nil

}
