package bot import ( "context" "fmt" "strings" "time" "github.com/bwmarrin/discordgo" ) func (b *Bot) handleMyStats(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) { userID := i.Member.User.ID username := displayName(i.Member, i.Member.User) unit, _ := b.db.GetUserPreference(ctx, userID, i.GuildID) since := b.challengeStart(ctx, i.GuildID) challenge, _ := b.db.GetUserStats(ctx, i.GuildID, userID, since) yearly, _ := b.db.GetUserYearlyStats(ctx, i.GuildID, userID, time.Now().Year()) allTime, _ := b.db.GetUserStats(ctx, i.GuildID, userID, time.Time{}) pb, _ := b.db.GetUserPB(ctx, i.GuildID, userID) streak, _ := b.db.GetUserStreak(ctx, userID) kudos, _ := b.db.GetKudosReceived(ctx, i.GuildID, userID) if allTime.LogCount == 0 { respondEphemeral(s, i, "You haven't logged any distances yet. Post your rides in the fitness challenge channel!") return } name, _, _ := b.db.GetSetting(ctx, i.GuildID, "challenge_name") if name == "" { name = "Challenge" } var sb strings.Builder sb.WriteString(fmt.Sprintf("## 🚴 %s's Stats\n\n", username)) sb.WriteString(fmt.Sprintf("**%s:** %s (%d ride%s)\n", name, formatDist(challenge.TotalKM, unit), challenge.LogCount, plural(challenge.LogCount))) sb.WriteString(fmt.Sprintf("**%d:** %s (%d ride%s)\n", time.Now().Year(), formatDist(yearly.TotalKM, unit), yearly.LogCount, plural(yearly.LogCount))) sb.WriteString(fmt.Sprintf("**All time:** %s (%d ride%s)\n\n", formatDist(allTime.TotalKM, unit), allTime.LogCount, plural(allTime.LogCount))) sb.WriteString(fmt.Sprintf("**Personal best:** %s\n", formatDist(pb, unit))) sb.WriteString(fmt.Sprintf("**Average ride:** %s\n", formatDist(allTime.TotalKM/float64(allTime.LogCount), unit))) if streak > 0 { sb.WriteString(fmt.Sprintf("**Current streak:** %d day%s 🔥\n", streak, plural(streak))) } if kudos > 0 { sb.WriteString(fmt.Sprintf("**Kudos received:** %d 👏\n", kudos)) } respondEphemeral(s, i, sb.String()) } func (b *Bot) handleHistory(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) { userID := i.Member.User.ID unit, _ := b.db.GetUserPreference(ctx, userID, i.GuildID) count := int(optInt(i.ApplicationCommandData().Options, "count", 5)) if count > 20 { count = 20 } logs, err := b.db.GetUserHistory(ctx, i.GuildID, userID, count) if err != nil || len(logs) == 0 { respondEphemeral(s, i, "No rides logged yet.") return } var sb strings.Builder sb.WriteString(fmt.Sprintf("## 🚴 Your Last %d Ride%s\n\n", len(logs), plural(len(logs)))) for _, l := range logs { sb.WriteString(fmt.Sprintf("**%s** — %s\n", l.LoggedAt.Format("02 Jan 2006"), formatDist(l.KM, unit))) } respondEphemeral(s, i, sb.String()) } func (b *Bot) handlePB(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) { userID := i.Member.User.ID unit, _ := b.db.GetUserPreference(ctx, userID, i.GuildID) pb, err := b.db.GetUserPB(ctx, i.GuildID, userID) if err != nil || pb == 0 { respondEphemeral(s, i, "No rides logged yet.") return } respondEphemeral(s, i, fmt.Sprintf("🏆 Your personal best single ride is **%s**!", formatDist(pb, unit))) } func (b *Bot) handleStreak(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) { target := optUser(i.ApplicationCommandData().Options, "user", s) var userID, username string if target != nil { userID = target.ID username = target.Username } else { userID = i.Member.User.ID username = displayName(i.Member, i.Member.User) } streak, err := b.db.GetUserStreak(ctx, userID) if err != nil { respondEphemeral(s, i, "Error fetching streak.") return } if streak == 0 { respondEphemeral(s, i, fmt.Sprintf("**%s** has no active streak. Get riding! 🚴", username)) return } respondEphemeral(s, i, fmt.Sprintf("🔥 **%s** is on a **%d day** streak!", username, streak)) } func (b *Bot) handleSetUnit(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) { unit := i.ApplicationCommandData().Options[0].StringValue() if err := b.db.SetUserPreference(ctx, i.Member.User.ID, i.GuildID, unit); err != nil { respondEphemeral(s, i, "Error saving preference.") return } respondEphemeral(s, i, fmt.Sprintf("✅ Your stats will now show in **%s**.", unit)) }