package bot import ( "context" "fmt" "strings" "time" "github.com/bwmarrin/discordgo" "cycling-discord-bot/db" ) func (b *Bot) handleLeaderboard(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) { since := b.challengeStart(ctx, i.GuildID) entries, err := b.db.GetLeaderboard(ctx, i.GuildID, since, 10) if err != nil { respondEphemeral(s, i, "Error fetching leaderboard.") return } if len(entries) == 0 { respondEphemeral(s, i, "No distances logged yet. Get riding! 🚴") return } name, _, _ := b.db.GetSetting(ctx, i.GuildID, "challenge_name") if name == "" { name = "Fitness Challenge" } respond(s, i, leaderboardText(fmt.Sprintf("🚴 %s — Leaderboard", name), entries)) } func (b *Bot) handleYearlyLeaderboard(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) { year := time.Now().Year() entries, err := b.db.GetYearlyLeaderboard(ctx, i.GuildID, year, 10) if err != nil { respondEphemeral(s, i, "Error fetching yearly leaderboard.") return } if len(entries) == 0 { respondEphemeral(s, i, fmt.Sprintf("No distances logged in %d yet.", year)) return } respond(s, i, leaderboardText(fmt.Sprintf("📅 %d Yearly Leaderboard", year), entries)) } func (b *Bot) handleTotalKM(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) { since := b.challengeStart(ctx, i.GuildID) total, err := b.db.GetTotalKM(ctx, i.GuildID, since) if err != nil { respondEphemeral(s, i, "Error fetching total.") return } yearStart := time.Date(time.Now().Year(), 1, 1, 0, 0, 0, 0, time.UTC) yearTotal, _ := b.db.GetTotalKM(ctx, i.GuildID, yearStart) name, _, _ := b.db.GetSetting(ctx, i.GuildID, "challenge_name") if name == "" { name = "Challenge" } var sb strings.Builder sb.WriteString("## 🌍 Distance Totals\n\n") sb.WriteString(fmt.Sprintf("**%s:** %.1f km\n", name, total)) sb.WriteString(fmt.Sprintf("**%d total:** %.1f km\n\n", time.Now().Year(), yearTotal)) if goalStr, ok, _ := b.db.GetSetting(ctx, i.GuildID, "challenge_goal_km"); ok { var goal float64 fmt.Sscanf(goalStr, "%f", &goal) if goal > 0 { sb.WriteString(fmt.Sprintf("**Goal:** %.1f km %s\n\n", goal, progressBar(total, goal, 12))) } } sb.WriteString(distanceComparison(total)) respond(s, i, sb.String()) } func leaderboardText(title string, entries []*db.UserStats) string { medals := []string{"🥇", "🥈", "🥉"} var sb strings.Builder sb.WriteString(fmt.Sprintf("## %s\n\n", title)) for idx, e := range entries { medal := " " if idx < len(medals) { medal = medals[idx] } sb.WriteString(fmt.Sprintf("%s **%d.** %s — **%.1f km** (%d ride%s)\n", medal, idx+1, e.Username, e.TotalKM, e.LogCount, plural(e.LogCount))) } return sb.String() }