package economy import ( "context" "database/sql" ) // RankEntry یک ردیف از جدولِ رتبه‌بندی. type RankEntry struct { Rank int `json:"rank"` Name string `json:"name"` Avatar string `json:"avatar"` RankPoints int64 `json:"rank_points"` Tier string `json:"tier"` } // AwardRank امتیازِ رتبه را پس از یک بازیِ رتبه‌بندی به‌روزرسانی می‌کند. // برنده +reward، بازنده −reward/2 (کفِ صفر). برای میزِ غیرِرتبه‌بندی بی‌اثر است. func (s *Service) AwardRank(ctx context.Context, userID int64, reward int, won bool) error { if reward <= 0 { return nil } delta := reward if !won { delta = -(reward / 2) } _, err := s.db.ExecContext(ctx, `UPDATE users SET rank_points = MAX(0, rank_points + ?) WHERE id = ?`, delta, userID) return err } // Leaderboard فهرستِ برترین بازیکنان بر اساس امتیازِ رتبه را برمی‌گرداند. func (s *Service) Leaderboard(ctx context.Context, limit int) ([]RankEntry, error) { if limit <= 0 || limit > 100 { limit = 50 } rows, err := s.db.QueryContext(ctx, `SELECT first_name, avatar, rank_points FROM users WHERE rank_points > 0 ORDER BY rank_points DESC LIMIT ?`, limit) if err != nil { return nil, err } defer rows.Close() out := make([]RankEntry, 0, limit) rank := 0 for rows.Next() { var name, avatar sql.NullString var pts int64 if err := rows.Scan(&name, &avatar, &pts); err != nil { return nil, err } rank++ tier, _ := RankTier(pts) nm := name.String if nm == "" { nm = "بازیکن" } out = append(out, RankEntry{ Rank: rank, Name: nm, Avatar: avatar.String, RankPoints: pts, Tier: tier, }) } return out, rows.Err() } // ResetSeason امتیازِ رتبه‌ی همه‌ی کاربران را صفر کرده و شماره‌ی فصل را زیاد می‌کند. func (s *Service) ResetSeason(ctx context.Context) error { tx, err := s.db.BeginTx(ctx, nil) if err != nil { return err } defer tx.Rollback() if _, err := tx.ExecContext(ctx, `UPDATE users SET rank_points = 0`); err != nil { return err } if _, err := tx.ExecContext(ctx, `UPDATE app_settings SET value = value + 1 WHERE key = 'season'`); err != nil { return err } return tx.Commit() } // Season شماره‌ی فصلِ جاری را برمی‌گرداند. func (s *Service) Season(ctx context.Context) int { var v int _ = s.db.QueryRowContext(ctx, `SELECT value FROM app_settings WHERE key = 'season'`).Scan(&v) return v }