package economy import ( "context" "database/sql" ) // Stats آمار بازیِ کاربر برای نمایش در پروفایل. type Stats struct { Games int64 `json:"games"` // بازی کل Wins int64 `json:"wins"` // برد کل Losses int64 `json:"losses"` // باخت کل KotMade int64 `json:"kot_made"` // کُت کردن KotReceived int64 `json:"kot_received"` // کُت شدن Cuts int64 `json:"cuts"` // بریدن (با حکم) HakemCount int64 `json:"hakem_count"` // دست حاکم } // GetStats آمار کاربر را می‌خواند (اگر ردیفی نباشد، صفر برمی‌گرداند). func (s *Service) GetStats(ctx context.Context, userID int64) (*Stats, error) { var st Stats err := s.db.QueryRowContext(ctx, `SELECT games, wins, losses, kot_made, kot_received, cuts, hakem_count FROM user_stats WHERE user_id = ?`, userID). Scan(&st.Games, &st.Wins, &st.Losses, &st.KotMade, &st.KotReceived, &st.Cuts, &st.HakemCount) if err == sql.ErrNoRows { return &st, nil // هنوز بازی‌ای ثبت نشده } if err != nil { return nil, err } return &st, nil } // bumpStats یک یا چند شمارنده را به‌صورت upsert افزایش می‌دهد. // fields نگاشتِ ستون→مقدار افزوده است؛ ستون‌ها از مجموعه‌ی ثابتِ زیر می‌آیند (نه ورودی کاربر). func (s *Service) bumpStats(ctx context.Context, userID int64, games, wins, losses, kotMade, kotRecv, cuts, hakem int64) { _, err := s.db.ExecContext(ctx, `INSERT INTO user_stats (user_id, games, wins, losses, kot_made, kot_received, cuts, hakem_count) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(user_id) DO UPDATE SET games = games + excluded.games, wins = wins + excluded.wins, losses = losses + excluded.losses, kot_made = kot_made + excluded.kot_made, kot_received = kot_received + excluded.kot_received, cuts = cuts + excluded.cuts, hakem_count = hakem_count + excluded.hakem_count`, userID, games, wins, losses, kotMade, kotRecv, cuts, hakem) if err != nil { // آمار غیرحیاتی است؛ خطا را لاگ‌نشده می‌گذریم تا جریان بازی مختل نشود. _ = err } } // RecordHand یک هَندِ پایان‌یافته را برای کاربر ثبت می‌کند. func (s *Service) RecordHand(ctx context.Context, userID int64, won, kot, asHakem bool) { var kotMade, kotRecv, hakem int64 if asHakem { hakem = 1 } if kot { if won { kotMade = 1 } else { kotRecv = 1 } } s.bumpStats(ctx, userID, 0, 0, 0, kotMade, kotRecv, 0, hakem) } // RecordCut یک بُرِش با حکم را برای کاربر ثبت می‌کند. func (s *Service) RecordCut(ctx context.Context, userID int64) { s.bumpStats(ctx, userID, 0, 0, 0, 0, 0, 1, 0) } // RecordGameResult پایانِ یک بازی را برای کاربر ثبت می‌کند (برد/باخت). func (s *Service) RecordGameResult(ctx context.Context, userID int64, won bool) { var wins, losses int64 if won { wins = 1 } else { losses = 1 } s.bumpStats(ctx, userID, 1, wins, losses, 0, 0, 0, 0) }