package service

import (
	"bufio"
	"designs/config"
	"designs/utils"
	"fmt"
	"math"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"
)

type logData struct {
	LogTime time.Time `json:"LogTime"`
	Type    int       `json:"Type"`
}

// 查询单日使用时长曲线
func UserOnlineSummaryByDay(gid string, pf string, startTime string, endTime string) (map[string]int, int, int, error) {
	//var onlineData []model.UserOnline
	////从数据库中查询出所有的数据
	//query := global.App.DB.Table("user_online").Where("gid", gid).Where("pf", pf)
	//
	//if startTime != "" && endTime != "" {
	//	query = query.Where("logTime", ">=", startTime).Where("logTime", "<=", endTime)
	//}
	//err := query.Scan(&onlineData).Error
	//if err != nil {
	//	return nil, 0, 0, err
	//}
	////对数据进行分组
	//userOnlineData := make(map[string]map[int][]logData)
	//dateSlice := utils.GetTimeDayDateFormat(startTime, endTime)
	//for _, v := range dateSlice {
	//	userOnlineData[v] = make(map[int][]logData)
	//}
	//
	//for _, v := range onlineData {
	//	date := v.LogTime.Format("2006-01-02")
	//	userOnlineData[date][v.UserId] = append(userOnlineData[date][v.UserId], logData{v.LogTime, v.Type})
	//}

	userOnlineData := make(map[string]map[int][]logData)

	dateSlice := utils.GetTimeDayDateFormat(startTime, endTime)

	for _, v := range dateSlice {

		userOnlineData[v] = make(map[int][]logData)

		userOnlineData[v] = GetLocalActiveLogDetail(gid, pf, v)

	}

	//计算每天的数据，然后得出平均值
	var totalAvg int
	var total int
	var totalTime int64

	daysAvg := make(map[string]int)
	for date, daysData := range userOnlineData {
		var userTotalTime int64
		//分组后对于每个用户的数据进行处理，得到他们的具体在线时长
		for _, v := range daysData {
			userTotalTime = userTotalTime + calculateUserOnlineTime(v)
		}
		//计算出平均值,并且格式化
		if len(daysData) > 0 {
			avg := float64(userTotalTime) / float64(len(daysData))
			daysAvg[date] = int(math.Round(avg))
		} else {
			daysAvg[date] = 0
		}

		//统计累加
		total = total + len(daysData)
		totalTime = totalTime + userTotalTime
	}
	//统计平均值
	if total <= 0 {
		totalAvg = 0
	} else {
		avg := float64(totalTime) / float64(total)
		totalAvg = int(math.Round(avg))
	}
	return daysAvg, total, totalAvg, nil

}

func UserOnlineSummary(gid string, pf string, date string, startTime string, endTime string) (map[int]int64, error) {
	//var onlineData []model.UserOnline
	////从数据库中查询出所有的数据
	//query := global.App.DB.Table("user_online").Where("gid", gid).Where("pf", pf)
	//if date != "" {
	//	query = query.Where("date", "=", date)
	//}
	//
	//if startTime != "" && endTime != "" {
	//	query = query.Where("logTime", ">=", startTime).Where("logTime", "<=", endTime)
	//}
	//err := query.Scan(&onlineData).Error
	//if err != nil {
	//	return nil, err
	//}

	////对数据进行分组
	//userOnlineData := make(map[int][]logData)
	//for _, v := range onlineData {
	//	value, exists := userOnlineData[v.UserId]
	//	if exists {
	//		userOnlineData[v.UserId] = append(value, logData{v.LogTime, v.Type})
	//
	//	} else {
	//		userOnlineData[v.UserId] = []logData{{v.LogTime, v.Type}}
	//	}
	//}
	//onlineData = nil

	userOnlineData := make(map[int][]logData)
	userOnlineData = GetLocalActiveLogDetailRange(gid, pf, startTime, endTime)

	userLogMsg := make(map[int]int64)
	//分组后对于每个用户的数据进行处理，得到他们的具体在线时长
	for k, v := range userOnlineData {
		userLogMsg[k] = calculateUserOnlineTime(v)
	}
	userOnlineData = nil

	return userLogMsg, nil
}

func calculateUserOnlineTime(logData []logData) int64 {

	var lastLog int64
	var isStart bool
	var onlineTimeTotal int64
	for k, v := range logData {
		logTime := v.LogTime.Unix()
		//如果跟上一次的记录隔的时间超过6分钟，就认为是之前断线了，属于无效数据
		if k > 0 && logData[k-1].LogTime.Unix()+60*6 < logTime {
			isStart = false
			continue
		}

		if v.Type == 1 && isStart == false {
			isStart = true
			lastLog = v.LogTime.Unix()
			continue
		}

		if v.Type == 1 && isStart == true {
			//logTime := v.LogTime.Unix()
			onlineTimeTotal = onlineTimeTotal + (logTime - lastLog)
			lastLog = logTime
			//如果下一次的心跳，间隔时间大于6分钟了，就可以认为，这次就算是结束了
			if k+1 == len(logData) || logData[k+1].LogTime.Unix() > logTime+60*6 {
				isStart = false
			}
			continue
		}

		if v.Type == 2 && isStart == true {
			//logTime := v.LogTime.Unix()
			onlineTimeTotal = onlineTimeTotal + (logTime - lastLog)

			isStart = false
			continue
		}

	}

	return onlineTimeTotal
}

func GetLocalActiveLogDetail(gid string, pf string, date string) map[int][]logData {
	var dir string
	if config.Get("app.local") == "local" {
		//url = "mongodb://localhost:27017"
		dir = "storage"
	} else {
		dir = "/www/wwwroot/chunhao_receive/storage"
	}

	dirPath := filepath.Join(dir, date)
	fileName := fmt.Sprintf("%s_%s.txt", gid, pf)
	filePath := filepath.Join(dirPath, fileName)

	file, _ := os.Open(filePath)

	defer file.Close() // 确保函数结束时关闭文件

	// 创建 Scanner 对象
	scanner := bufio.NewScanner(file)

	res := make(map[int][]logData)
	// 逐行读取文件内容
	lineNumber := 1
	for scanner.Scan() {
		line := scanner.Text() // 获取当前行内容
		lineNumber++

		//11887,2,2025-03-24 09:05:19
		lineSlice := strings.Split(line, ",")

		userId, _ := strconv.Atoi(lineSlice[0])
		types, _ := strconv.Atoi(lineSlice[1])
		// 解析时间
		t, _ := time.Parse("2006-01-02  15:04:05", lineSlice[2])

		res[userId] = append(res[userId], logData{t, types})
	}

	return res
}

func GetLocalActiveLogDetailRange(gid string, pf string, start string, end string) map[int][]logData {
	var dir string
	if config.Get("app.local") == "local" {
		//url = "mongodb://localhost:27017"
		dir = "storage"
	} else {
		dir = "/www/wwwroot/chunhao_receive/storage"
	}

	dateSlice := utils.GetTimeDayDateFormat(start, end)

	res := make(map[int][]logData)
	for _, v := range dateSlice {

		dirPath := filepath.Join(dir, v)
		fileName := fmt.Sprintf("%s_%s.txt", gid, pf)
		filePath := filepath.Join(dirPath, fileName)

		file, _ := os.Open(filePath)

		// 创建 Scanner 对象
		scanner := bufio.NewScanner(file)
		// 逐行读取文件内容
		lineNumber := 1
		for scanner.Scan() {
			line := scanner.Text() // 获取当前行内容
			lineNumber++

			//11887,2,2025-03-24 09:05:19
			lineSlice := strings.Split(line, ",")

			userId, _ := strconv.Atoi(lineSlice[0])
			types, _ := strconv.Atoi(lineSlice[1])
			// 解析时间
			t, _ := time.Parse("2006-01-02  15:04:05", lineSlice[2])

			res[userId] = append(res[userId], logData{t, types})
		}

		file.Close() // 确保函数结束时关闭文件
	}

	return res
}
