package service

import (
	"designs/global"
	"designs/model"
	"designs/utils"
	"time"
)

var timeDuration = []string{
	"00.00",
	"01.00",
	"02.00",
	"03.00",
	"04.00",
	"05.00",
	"06.00",
	"07.00",
	"08.00",
	"09.00",
	"10.00",
	"11.00",
	"12.00",
	"13.00",
	"14.00",
	"15.00",
	"16.00",
	"17.00",
	"18.00",
	"19.00",
	"20.00",
	"21.00",
	"22.00",
	"23.00",
}

// 获取新增用户的时段信息
func GetRegisterTimeDistribution(pf string, gid string) (map[string]int, map[string]int, int64, int64, int64, error) {
	now := time.Now()
	today := now.Format("2006-01-02")

	hours := utils.GetDayHour(now)
	var todayRegister []time.Time

	//计算今日曲线
	err := global.App.DB.Table("user").
		Where("pf", pf).
		Where("gid", gid).
		Where("createdAt", ">", today).
		Pluck("createdAt", &todayRegister).Error
	if err != nil {
		global.App.Log.Error(err.Error())
		return nil, nil, 0, 0, 0, err
	}

	todayCount := len(todayRegister)

	todayTimeDistribution := getTimeDistribution(todayRegister, hours)

	//计算昨日曲线
	var yesterdayRegister []time.Time
	yesterdayHours := utils.GetDayHour(now.AddDate(0, 0, -1))
	yesterday := now.AddDate(0, 0, -1).Format("2006-01-02")
	yesterdayThisTime := now.AddDate(0, 0, -1).Format("2006-01-02 15:04:05")
	err = global.App.DB.Table("user").
		Where("pf", pf).
		Where("gid", gid).
		Where("createdAt", ">", yesterday).
		Where("createdAt", "<=", today).
		Pluck("createdAt", &yesterdayRegister).Error
	if err != nil {
		global.App.Log.Error(err.Error())
		return nil, nil, 0, 0, 0, err
	}
	yesterdayCount := len(yesterdayRegister)
	yesterdayTimeDistribution := getTimeDistribution(yesterdayRegister, yesterdayHours)
	var yesterdayThisTimeCount int64
	err = global.App.DB.Table("user").
		Where("pf", pf).
		Where("gid", gid).
		Where("createdAt", ">", yesterday).
		Where("createdAt", "<=", yesterdayThisTime).
		Count(&yesterdayThisTimeCount).Error
	if err != nil {
		global.App.Log.Error(err.Error())
		return nil, nil, 0, 0, 0, err
	}
	todayTimeDistributionRes := make(map[string]int)
	for k, v := range todayTimeDistribution {
		todayTimeDistributionRes[timeDuration[k]] = v
	}

	yesterdayTimeDistributionRes := make(map[string]int)
	for k, v := range yesterdayTimeDistribution {
		yesterdayTimeDistributionRes[timeDuration[k]] = v
	}

	return todayTimeDistributionRes, yesterdayTimeDistributionRes, int64(yesterdayCount), int64(todayCount), yesterdayThisTimeCount, nil
}

// 活跃用户的时段信息
func GetActiveTimeDistribution(pf string, gid string) (map[string]int, map[string]int, int64, int64, int64, error) {
	now := time.Now()
	today := now.Format("2006-01-02")

	hours := utils.GetDayHour(now)
	var todayRegisterModel []model.UserLogin

	//计算今日曲线
	err := global.App.DB.Table("user_login").
		Where("pf", pf).
		Where("gid", gid).
		Where("loginTime", ">", today).
		Select("userId", "loginTime").
		Scan(&todayRegisterModel).Error
	if err != nil {
		global.App.Log.Error(err.Error())
		return nil, nil, 0, 0, 0, err
	}

	todayRegister := distinctUserHour(todayRegisterModel)

	var todayCount int64
	err = global.App.DB.Table("user_login").
		Where("pf", pf).
		Where("gid", gid).
		Where("loginTime", ">", today).
		Group("userId").Count(&todayCount).Error
	if err != nil {
		global.App.Log.Error(err.Error())
		return nil, nil, 0, 0, 0, err
	}
	todayTimeDistribution := getTimeDistribution(todayRegister, hours)

	//计算昨日曲线
	//var yesterdayRegister []time.Time
	var yesterdayRegisterModel []model.UserLogin

	yesterdayHours := utils.GetDayHour(now.AddDate(0, 0, -1))
	yesterday := now.AddDate(0, 0, -1).Format("2006-01-02")
	yesterdayThisTime := now.AddDate(0, 0, -1).Format("2006-01-02 15:04:05")
	err = global.App.DB.Table("user_login").
		Where("pf", pf).
		Where("gid", gid).
		Where("loginTime", ">", yesterday).
		Where("loginTime", "<=", today).
		Select("userId", "loginTime").
		Scan(&yesterdayRegisterModel).Error
	if err != nil {
		global.App.Log.Error(err.Error())
		return nil, nil, 0, 0, 0, err
	}

	var yesterdayCount int64
	err = global.App.DB.Table("user_login").
		Where("pf", pf).
		Where("gid", gid).
		Where("loginTime", ">", yesterday).
		Where("loginTime", "<=", today).
		Group("userId").Count(&yesterdayCount).Error
	if err != nil {
		global.App.Log.Error(err.Error())
		return nil, nil, 0, 0, 0, err
	}

	var yesterdayThisTimeCount int64
	err = global.App.DB.Table("user_login").
		Where("pf", pf).
		Where("gid", gid).
		Where("loginTime", ">", yesterday).
		Where("loginTime", "<=", yesterdayThisTime).
		Group("userId").Count(&yesterdayCount).Error
	if err != nil {
		global.App.Log.Error(err.Error())
		return nil, nil, 0, 0, 0, err
	}
	yesterdayRegister := distinctUserHour(yesterdayRegisterModel)
	yesterdayTimeDistribution := getTimeDistribution(yesterdayRegister, yesterdayHours)

	todayTimeDistributionRes := make(map[string]int)
	for k, v := range todayTimeDistribution {
		todayTimeDistributionRes[timeDuration[k]] = v
	}

	yesterdayTimeDistributionRes := make(map[string]int)
	for k, v := range yesterdayTimeDistribution {
		yesterdayTimeDistributionRes[timeDuration[k]] = v
	}

	return todayTimeDistributionRes, yesterdayTimeDistributionRes, yesterdayCount, todayCount, yesterdayThisTimeCount, nil
}

// 启动次数的时段信息
func GetActionDistribution(pf string, gid string) (map[string]int, map[string]int, int64, int64, int64, error) {
	now := time.Now()
	today := now.Format("2006-01-02")

	hours := utils.GetDayHour(now)
	var todayRegisterModel []time.Time

	//计算今日曲线
	err := global.App.DB.Table("user_login").
		Where("pf", pf).
		Where("gid", gid).
		Where("loginTime", ">", today).
		Select("userId", "loginTime").
		Pluck("loginTime", &todayRegisterModel).Error
	if err != nil {
		global.App.Log.Error(err.Error())
		return nil, nil, 0, 0, 0, err
	}

	//todayRegister := distinctUserHour(todayRegisterModel)

	var todayCount int64
	err = global.App.DB.Table("user_login").
		Where("pf", pf).
		Where("gid", gid).
		Where("loginTime", ">", today).
		Group("userId").Count(&todayCount).Error
	if err != nil {
		global.App.Log.Error(err.Error())
		return nil, nil, 0, 0, 0, err
	}
	todayTimeDistribution := getTimeDistribution(todayRegisterModel, hours)

	//计算昨日曲线
	var yesterdayRegisterModel []time.Time

	yesterdayHours := utils.GetDayHour(now.AddDate(0, 0, -1))
	yesterday := now.AddDate(0, 0, -1).Format("2006-01-02")
	yesterdayThisTime := now.AddDate(0, 0, -1).Format("2006-01-02 15:04:05")
	err = global.App.DB.Table("user_login").
		Where("pf", pf).
		Where("gid", gid).
		Where("loginTime", ">", yesterday).
		Where("loginTime", "<=", today).
		Pluck("loginTime", &yesterdayRegisterModel).Error
	if err != nil {
		global.App.Log.Error(err.Error())
		return nil, nil, 0, 0, 0, err
	}

	var yesterdayCount int64
	err = global.App.DB.Table("user_login").
		Where("pf", pf).
		Where("gid", gid).
		Where("loginTime", ">", yesterday).
		Where("loginTime", "<=", today).
		Group("userId").Count(&yesterdayCount).Error
	if err != nil {
		global.App.Log.Error(err.Error())
		return nil, nil, 0, 0, 0, err
	}

	var yesterdayThisTimeCount int64
	err = global.App.DB.Table("user_login").
		Where("pf", pf).
		Where("gid", gid).
		Where("loginTime", ">", yesterday).
		Where("loginTime", "<=", yesterdayThisTime).
		Group("userId").Count(&yesterdayCount).Error
	if err != nil {
		global.App.Log.Error(err.Error())
		return nil, nil, 0, 0, 0, err
	}
	//yesterdayRegister := distinctUserHour(yesterdayRegisterModel)
	yesterdayTimeDistribution := getTimeDistribution(yesterdayRegisterModel, yesterdayHours)

	todayTimeDistributionRes := make(map[string]int)
	for k, v := range todayTimeDistribution {
		todayTimeDistributionRes[timeDuration[k]] = v
	}

	yesterdayTimeDistributionRes := make(map[string]int)
	for k, v := range yesterdayTimeDistribution {
		yesterdayTimeDistributionRes[timeDuration[k]] = v
	}

	return todayTimeDistributionRes, yesterdayTimeDistributionRes, yesterdayCount, todayCount, yesterdayThisTimeCount, nil
}

// 新增设备日趋势图
func GetRegisterDayDistribution(pf string, gid string, startTime string, endTime string) (map[string]int, int, float32, error) {
	var registerDays []time.Time
	err := global.App.DB.Table("user").
		Where("gid", gid).
		Where("pf", pf).
		Where("createdAt", ">=", startTime).
		Where("createdAt", "<=", endTime).
		Pluck("createdAt", &registerDays).Error
	if err != nil {
		return nil, 0, 0, err
	}
	days := utils.GetTimeDay(startTime, endTime)

	todayTimeDistribution := getTimeDistribution(registerDays, days)

	daysFormat := utils.GetTimeDayDateFormat(startTime, endTime) //用户分别是在哪天注册的
	todayTimeDistributionRes := make(map[string]int)
	for k, day := range daysFormat {
		todayTimeDistributionRes[day] = todayTimeDistribution[k]
	}

	return todayTimeDistributionRes, len(registerDays), float32(len(registerDays) / len(days)), nil
}

// 活跃用户趋势图
func GetActiveDayDistribution(pf string, gid string, startTime string, endTime string) (map[string]int, int64, float32, error) {
	var activeDays []time.Time
	err := global.App.DB.Table("user_login").
		Where("gid", gid).
		Where("pf", pf).
		Where("loginTime", ">=", startTime).
		Where("loginTime", "<=", endTime).
		Pluck("loginTime", &activeDays).Error
	if err != nil {
		return nil, 0, 0, err
	}
	//查询总数（去重）
	var count int64
	err = global.App.DB.Table("user_login").
		Where("gid", gid).
		Where("pf", pf).
		Where("loginTime", ">=", startTime).
		Where("loginTime", "<=", endTime).
		Distinct("userId").Count(&count).Error
	if err != nil {
		return nil, 0, 0, err
	}

	days := utils.GetTimeDay(startTime, endTime)

	todayTimeDistribution := getTimeDistribution(activeDays, days)

	daysFormat := utils.GetTimeDayDateFormat(startTime, endTime) //用户分别是在哪天注册的
	todayTimeDistributionRes := make(map[string]int)
	for k, day := range daysFormat {
		todayTimeDistributionRes[day] = todayTimeDistribution[k]
	}

	return todayTimeDistributionRes, count, float32(len(activeDays) / len(days)), nil
}

// 活跃用户周趋势图
func GetActiveWeekDistribution(pf string, gid string, startTime string, endTime string) (map[string]int, int64, float32, error) {
	var activeDays []time.Time
	err := global.App.DB.Table("user_login").
		Where("gid", gid).
		Where("pf", pf).
		Where("loginTime", ">=", startTime).
		Where("loginTime", "<=", endTime).
		Pluck("loginTime", &activeDays).Error
	if err != nil {
		return nil, 0, 0, err
	}

	days := utils.GetTimeDay(startTime, endTime)

	todayTimeDistribution := getTimeDistribution(activeDays, days)

	daysFormat := utils.GetTimeDayDateFormat(startTime, endTime) //用户分别是在哪天注册的
	todayTimeDistributionRes := make(map[string]int)
	for k, day := range daysFormat {
		todayTimeDistributionRes[day] = todayTimeDistribution[k]
	}

	return todayTimeDistributionRes, 0, float32(len(activeDays) / len(days)), nil
}

// 活跃用户月趋势图
func GetActiveMouthDistribution(pf string, gid string, startTime string, endTime string) (map[string]int, int64, float32, error) {
	var activeDays []time.Time
	err := global.App.DB.Table("user_login").
		Where("gid", gid).
		Where("pf", pf).
		Where("loginTime", ">=", startTime).
		Where("loginTime", "<=", endTime).
		Pluck("loginTime", &activeDays).Error
	if err != nil {
		return nil, 0, 0, err
	}

	days := utils.GetTimeDay(startTime, endTime)

	todayTimeDistribution := getTimeDistribution(activeDays, days)
	daysFormat := utils.GetTimeDayDateFormat(startTime, endTime) //用户分别是在哪天注册的
	todayTimeDistributionRes := make(map[string]int)
	for k, day := range daysFormat {
		todayTimeDistributionRes[day] = todayTimeDistribution[k]
	}

	return todayTimeDistributionRes, 0, float32(len(activeDays) / len(days)), nil
}

func GetLoginDistribution(pf string, gid string, startTime string, endTime string) (map[int]int, float32, error) {
	var activeDays []time.Time
	err := global.App.DB.Table("user_login").
		Where("gid", gid).
		Where("pf", pf).
		Where("loginTime", ">=", startTime).
		Where("loginTime", "<=", endTime).
		Pluck("loginTime", &activeDays).Error
	if err != nil {
		return nil, 0, err
	}
	days := utils.GetTimeDay(startTime, endTime)

	todayTimeDistribution := getTimeDistribution(activeDays, days)

	return todayTimeDistribution, float32(len(activeDays) / len(days)), nil
}

// 根据时段对信息进行去重（每个小时只有一条数据是有效的）
func distinctUserHour(data []model.UserLogin) []time.Time {
	var result []time.Time

	check := make(map[string][]int)

	for _, v := range data {
		date := v.LoginTime.Format("15")
		if !utils.InArray(v.UserId, check[date]) {
			check[date] = append(check[date], v.UserId)

			result = append(result, v.LoginTime)
		}
	}

	return result
}

// 根据时间求出时段信息
func getTimeDistribution(todayRegister []time.Time, hours []int64) map[int]int {
	todayRegisterSum := make(map[int]int)
	//长度为1 不需要循环
	if len(hours) == 1 {
		todayRegisterSum[0] = len(todayRegister)
		return todayRegisterSum
	}
	//循环获取时段信息
	var todayRegisterUnix []int64
	for _, t := range todayRegister {
		todayRegisterUnix = append(todayRegisterUnix, t.Unix())
	}

	for k := range hours {
		todayRegisterSum[k] = 0
	}
	for _, t := range todayRegisterUnix {
		for k := range hours {
			if k == 0 {
				if t < hours[k+1] {
					todayRegisterSum[0]++
				}
			} else if k == len(hours)-1 {
				if t > hours[k] {
					todayRegisterSum[len(hours)-1]++
				}
			} else {
				if t > hours[k] && t <= hours[k+1] {
					todayRegisterSum[k]++
				}
			}
		}
	}
	return todayRegisterSum
}

//// 根据日期求出分天信息
//func getDayDistribution(mouthRegister []time.Time, days []int64) {
//	var mouthRegisterUnix []int64
//	for _, t := range mouthRegister {
//		mouthRegisterUnix = append(mouthRegisterUnix, t.Unix())
//	}
//
//	mouthRegisterSum := make(map[int]int)
//	for k := range days {
//		mouthRegisterSum[k] = 0
//	}
//
//	for _, t := range mouthRegisterUnix {
//		for k := range days {
//			if k == 0 {
//				if t < days[k+1] {
//					todayRegisterSum[0]++
//				}
//			} else if k ==  {
//				if t > days[k] {
//					todayRegisterSum[23]++
//				}
//			} else {
//				if t > days[k] && t <= days[k+1] {
//					todayRegisterSum[k]++
//				}
//			}
//		}
//	}
//
//
//}
