package services import ( "database/sql" "log" "synlotto-website/handlers" "synlotto-website/helpers" "synlotto-website/models" "synlotto-website/rules" draws "synlotto-website/services/draws" ) func RunTicketMatching(db *sql.DB, triggeredBy string) (models.MatchRunStats, error) { stats := models.MatchRunStats{} rows, err := db.Query(` SELECT id, game_type, draw_date, ball1, ball2, ball3, ball4, ball5, ball6, bonus1, bonus2 FROM my_tickets WHERE matched_main IS NULL `) if err != nil { return stats, err } defer rows.Close() // Buffer results to avoid writing while iterating var pending []models.Ticket for rows.Next() { var t models.Ticket var b1, b2, b3, b4, b5, b6, bo1, bo2 sql.NullInt64 if err := rows.Scan( &t.Id, &t.GameType, &t.DrawDate, &b1, &b2, &b3, &b4, &b5, &b6, &bo1, &bo2, ); err != nil { continue } t.Ball1 = int(b1.Int64) t.Ball2 = int(b2.Int64) t.Ball3 = int(b3.Int64) t.Ball4 = int(b4.Int64) t.Ball5 = int(b5.Int64) t.Ball6 = int(b6.Int64) t.Bonus1 = helpers.IntPtrIfValid(bo1) t.Bonus2 = helpers.IntPtrIfValid(bo2) pending = append(pending, t) } for _, t := range pending { matchTicket := models.MatchTicket{ ID: t.Id, GameType: t.GameType, DrawDate: t.DrawDate, Balls: helpers.BuildBallsSlice(t), BonusBalls: helpers.BuildBonusSlice(t), } draw := draws.GetDrawResultForTicket(db, t.GameType, t.DrawDate) result := handlers.MatchTicketToDraw(matchTicket, draw, rules.ThunderballPrizeRules) if result.MatchedDrawID == 0 { continue } _, err := db.Exec(` UPDATE my_tickets SET matched_main = ?, matched_bonus = ?, prize_tier = ?, is_winner = ? WHERE id = ? `, result.MatchedMain, result.MatchedBonus, result.PrizeTier, result.IsWinner, t.Id) if err != nil { log.Println("⚠️ Failed to update ticket match:", err) continue } stats.TicketsMatched++ if result.IsWinner { stats.WinnersFound++ } } _, _ = db.Exec(` INSERT INTO log_ticket_matching (triggered_by, tickets_matched, winners_found) VALUES (?, ?, ?) `, triggeredBy, stats.TicketsMatched, stats.WinnersFound) return stats, nil }