package GoUtil

import (
	"server/conf"
	"time"
)

const (
	SEVENDAYS = 604800
	MONTHDAYS = 2592000
)

func ZeroTimestamp() int64 {
	now := time.Now()
	midnight := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
	return midnight.Unix()
}

func NoonTimestamp() int64 {
	now := time.Now()
	midDay := time.Date(now.Year(), now.Month(), now.Day(), 12, 0, 0, 0, now.Location())
	return midDay.Unix()
}

func MonthZeroTimestamp() int64 {
	now := time.Now()
	midnight := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
	return midnight.Unix()
}

func NextZeroTimestampDuration() int64 {
	now := time.Now()
	location := now.Location()
	midnight := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, location)
	nextMidnight := midnight.AddDate(0, 0, 1)

	// Adjust for daylight saving time transitions
	_, nowOffset := now.Zone()
	_, nextMidnightOffset := nextMidnight.Zone()
	offsetDifference := nextMidnightOffset - nowOffset

	return nextMidnight.Unix() - now.Unix() + int64(offsetDifference)
}

// 获取距离下个中午十二点时间戳的秒数
func NextNoonTimestampDuration() int64 {
	now := time.Now()
	nextNoon := time.Date(now.Year(), now.Month(), now.Day(), 12, 0, 0, 0, now.Location())

	// 如果当前时间已经过了今天的中午十二点，则计算明天的中午十二点
	if now.After(nextNoon) {
		nextNoon = nextNoon.Add(24 * time.Hour)
	}

	return int64(nextNoon.Sub(now).Seconds())
}

func NextHourRemain() float64 {
	now := time.Now()
	nextHour := now.Truncate(time.Hour).Add(time.Hour)
	return nextHour.Sub(now).Seconds()
}

func NextWeekTimestampDuration() int64 {
	now := time.Now()
	weekday := int(now.Weekday())
	if weekday == 0 {
		weekday = 7
	}
	midnight := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
	return midnight.AddDate(0, 0, 8-weekday).Unix() - now.Unix()
}

func WeekZeroTimestamp() int64 {
	now := time.Now()
	weekday := int(now.Weekday())
	if weekday == 0 {
		weekday = 7
	}
	midnight := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
	return midnight.Unix() - int64((weekday-1)*86400)
}

func Now() int64 {
	return time.Now().Unix()
}
func NowNano() int64 {
	return int64(time.Now().Nanosecond())
}
func GetWeekdayAndHour() (int, int) {
	now := time.Now()
	weekday := int(now.Weekday())
	if weekday == 0 {
		weekday = 7
	}
	hour := now.Hour()
	return weekday, hour
}

func ParseTime(timeStr string) int64 {
	loc, _ := time.LoadLocation("Local")
	t, _ := time.ParseInLocation("2006-01-02 15:04:05", timeStr, loc)
	return t.Unix()
}

func ServerOpenTime() int64 {
	return ParseTime(conf.Server.ServerOpenTime)
}

func GetServerOpenDay() int {
	ServerStartTime := conf.Server.ServerOpenTime
	t, _ := time.Parse("2006-01-02 15:04:05", ServerStartTime)
	now := time.Now()
	d := now.Sub(t)
	return int(d.Hours() / 24)
}

// 获取时间戳距离现在过了多少个自然周
func WeeksSince(timestamp int64) int {
	// 将时间戳转换为 time.Time 对象
	t := time.Unix(timestamp, 0)

	// 获取当前时间
	now := time.Now()

	// 计算两个时间之间的周数差
	weeks := int(now.Sub(t).Hours() / (24 * 7))
	return weeks
}

// 计算给定时间戳距离现在跨过了多少个自然周
func FullWeeksSince(timestamp int64) int {
	// 将时间戳转换为 time.Time 对象
	t := time.Unix(timestamp, 0)

	// 获取当前时间
	now := time.Now()

	// 计算两个时间之间跨过的自然周数
	startWeek := t.Year()*52 + t.YearDay()/7
	currentWeek := now.Year()*52 + now.YearDay()/7

	return currentWeek - startWeek
}

func ZeroTime(timestamp int64) int64 {
	t := time.Unix(timestamp, 0)
	return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location()).Unix()
}

// 计算给定时间戳所在的 0 点到现在的 0 点过了几天
func DaysSince(timestamp int64) int {
	// 获取给定时间戳的 0 点时间
	t := time.Unix(timestamp, 0)
	startOfDay := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())

	// 获取当前时间的 0 点时间
	now := time.Now()
	startOfToday := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())

	// 计算两个时间之间的天数差
	days := int(startOfToday.Sub(startOfDay).Hours() / 24)
	return days
}

func IsSameDay(timestamp1, timestamp2 int64) bool {
	t1 := time.Unix(timestamp1, 0)
	t2 := time.Unix(timestamp2, 0)

	return t1.Year() == t2.Year() && t1.YearDay() == t2.YearDay()
}

func IsFirstDayOfMonth() bool {
	now := time.Now()
	return now.Day() == 1
}
