using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using RR3CommunityServer.Data;
using RR3CommunityServer.Models;

namespace RR3CommunityServer.Controllers;

[ApiController]
[Route("synergy/multiplayer")]
public class MultiplayerController : ControllerBase
{
    private readonly RR3DbContext _context;
    private readonly ILogger<MultiplayerController> _logger;

    public MultiplayerController(RR3DbContext context, ILogger<MultiplayerController> logger)
    {
        _context = context;
        _logger = logger;
    }

    // ===== MATCHMAKING (3 endpoints) =====

    // POST /synergy/multiplayer/matchmaking/queue - Join matchmaking queue
    [HttpPost("matchmaking/queue")]
    public async Task<ActionResult<MatchmakingStatusResponse>> JoinMatchmakingQueue([FromBody] JoinMatchmakingRequest request)
    {
        try
        {
            var user = await _context.Users.FirstOrDefaultAsync(u => u.SynergyId == request.SynergyId);
            if (user == null)
            {
                return Ok(new MatchmakingStatusResponse
                {
                    ResultCode = -1,
                    Message = "User not found"
                });
            }

            // Check if already in queue
            var existingQueue = await _context.MatchmakingQueues
                .FirstOrDefaultAsync(q => q.UserId == user.Id && q.Status == "queued");

            if (existingQueue != null)
            {
                return Ok(new MatchmakingStatusResponse
                {
                    ResultCode = 0,
                    Status = "queued",
                    QueueId = existingQueue.Id,
                    QueuedAt = existingQueue.QueuedAt,
                    EstimatedWaitSeconds = 30
                });
            }

            // Add to matchmaking queue
            var queueEntry = new MatchmakingQueue
            {
                UserId = user.Id,
                CarClass = request.CarClass,
                Track = request.Track,
                GameMode = request.GameMode,
                Status = "queued",
                QueuedAt = DateTime.UtcNow
            };

            _context.MatchmakingQueues.Add(queueEntry);
            await _context.SaveChangesAsync();

            _logger.LogInformation("User {User} joined matchmaking for {Track} ({Class})", 
                user.SynergyId, request.Track, request.CarClass);

            // Simple matchmaking: find other queued player for same track/class
            var matchedPlayer = await _context.MatchmakingQueues
                .Where(q => q.Id != queueEntry.Id && 
                           q.Status == "queued" && 
                           q.Track == request.Track && 
                           q.CarClass == request.CarClass)
                .FirstOrDefaultAsync();

            if (matchedPlayer != null)
            {
                // Create race session
                var session = new RaceSession
                {
                    SessionCode = GenerateSessionCode(),
                    Track = request.Track,
                    CarClass = request.CarClass,
                    HostUserId = user.Id,
                    MaxPlayers = 8,
                    Status = "lobby",
                    IsPrivate = false,
                    CreatedAt = DateTime.UtcNow
                };

                _context.RaceSessions.Add(session);
                await _context.SaveChangesAsync();

                // Add both players as participants
                var participants = new[]
                {
                    new RaceParticipant { SessionId = session.Id, UserId = user.Id },
                    new RaceParticipant { SessionId = session.Id, UserId = matchedPlayer.UserId }
                };

                _context.RaceParticipants.AddRange(participants);

                // Update queue entries
                queueEntry.Status = "matched";
                queueEntry.MatchedAt = DateTime.UtcNow;
                queueEntry.SessionId = session.Id;

                matchedPlayer.Status = "matched";
                matchedPlayer.MatchedAt = DateTime.UtcNow;
                matchedPlayer.SessionId = session.Id;

                await _context.SaveChangesAsync();

                _logger.LogInformation("Matched 2 players, created session {SessionCode}", session.SessionCode);

                return Ok(new MatchmakingStatusResponse
                {
                    ResultCode = 0,
                    Status = "matched",
                    QueueId = queueEntry.Id,
                    SessionId = session.Id,
                    SessionCode = session.SessionCode,
                    QueuedAt = queueEntry.QueuedAt
                });
            }

            return Ok(new MatchmakingStatusResponse
            {
                ResultCode = 0,
                Status = "queued",
                QueueId = queueEntry.Id,
                QueuedAt = queueEntry.QueuedAt,
                EstimatedWaitSeconds = 30
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error joining matchmaking queue");
            return Ok(new MatchmakingStatusResponse
            {
                ResultCode = -1,
                Message = "Error joining queue"
            });
        }
    }

    // GET /synergy/multiplayer/matchmaking/status - Check matchmaking status
    [HttpGet("matchmaking/status")]
    public async Task<ActionResult<MatchmakingStatusResponse>> GetMatchmakingStatus(
        [FromQuery] string synergyId,
        [FromQuery] int queueId)
    {
        try
        {
            var user = await _context.Users.FirstOrDefaultAsync(u => u.SynergyId == synergyId);
            if (user == null)
            {
                return Ok(new MatchmakingStatusResponse
                {
                    ResultCode = -1,
                    Message = "User not found"
                });
            }

            var queueEntry = await _context.MatchmakingQueues
                .Include(q => q.Session)
                .FirstOrDefaultAsync(q => q.Id == queueId && q.UserId == user.Id);

            if (queueEntry == null)
            {
                return Ok(new MatchmakingStatusResponse
                {
                    ResultCode = -2,
                    Message = "Queue entry not found"
                });
            }

            return Ok(new MatchmakingStatusResponse
            {
                ResultCode = 0,
                Status = queueEntry.Status,
                QueueId = queueEntry.Id,
                SessionId = queueEntry.SessionId,
                SessionCode = queueEntry.Session?.SessionCode,
                QueuedAt = queueEntry.QueuedAt,
                EstimatedWaitSeconds = queueEntry.Status == "queued" ? 30 : null
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error checking matchmaking status");
            return Ok(new MatchmakingStatusResponse
            {
                ResultCode = -1,
                Message = "Error checking status"
            });
        }
    }

    // DELETE /synergy/multiplayer/matchmaking/leave - Leave matchmaking queue
    [HttpDelete("matchmaking/leave")]
    public async Task<ActionResult<SimpleResponse>> LeaveMatchmakingQueue(
        [FromQuery] string synergyId,
        [FromQuery] int queueId)
    {
        try
        {
            var user = await _context.Users.FirstOrDefaultAsync(u => u.SynergyId == synergyId);
            if (user == null)
            {
                return Ok(new SimpleResponse
                {
                    ResultCode = -1,
                    Message = "User not found"
                });
            }

            var queueEntry = await _context.MatchmakingQueues
                .FirstOrDefaultAsync(q => q.Id == queueId && q.UserId == user.Id);

            if (queueEntry == null)
            {
                return Ok(new SimpleResponse
                {
                    ResultCode = -2,
                    Message = "Queue entry not found"
                });
            }

            if (queueEntry.Status == "matched")
            {
                return Ok(new SimpleResponse
                {
                    ResultCode = -3,
                    Message = "Already matched, cannot leave"
                });
            }

            queueEntry.Status = "cancelled";
            await _context.SaveChangesAsync();

            _logger.LogInformation("User {User} left matchmaking queue", user.SynergyId);

            return Ok(new SimpleResponse
            {
                ResultCode = 0,
                Message = "Left queue"
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error leaving matchmaking queue");
            return Ok(new SimpleResponse
            {
                ResultCode = -1,
                Message = "Error leaving queue"
            });
        }
    }

    // ===== RACE SESSIONS (4 endpoints) =====

    // POST /synergy/multiplayer/session/create - Create private race session
    [HttpPost("session/create")]
    public async Task<ActionResult<RaceSessionResponse>> CreateRaceSession([FromBody] CreateRaceSessionRequest request)
    {
        try
        {
            var user = await _context.Users.FirstOrDefaultAsync(u => u.SynergyId == request.SynergyId);
            if (user == null)
            {
                return Ok(new RaceSessionResponse
                {
                    ResultCode = -1,
                    Message = "User not found"
                });
            }

            var session = new RaceSession
            {
                SessionCode = GenerateSessionCode(),
                Track = request.Track,
                CarClass = request.CarClass,
                HostUserId = user.Id,
                MaxPlayers = request.MaxPlayers,
                Status = "lobby",
                IsPrivate = request.IsPrivate,
                CreatedAt = DateTime.UtcNow
            };

            _context.RaceSessions.Add(session);
            await _context.SaveChangesAsync();

            // Add host as first participant
            var participant = new RaceParticipant
            {
                SessionId = session.Id,
                UserId = user.Id
            };

            _context.RaceParticipants.Add(participant);
            await _context.SaveChangesAsync();

            _logger.LogInformation("User {User} created race session {Code}", user.SynergyId, session.SessionCode);

            return Ok(new RaceSessionResponse
            {
                ResultCode = 0,
                Session = new RaceSessionDto
                {
                    SessionId = session.Id,
                    SessionCode = session.SessionCode,
                    Track = session.Track,
                    CarClass = session.CarClass,
                    HostUserId = user.Id,
                    HostNickname = user.Nickname ?? "Player",
                    CurrentPlayers = 1,
                    MaxPlayers = session.MaxPlayers,
                    Status = session.Status,
                    CreatedAt = session.CreatedAt
                },
                Participants = new List<ParticipantDto>
                {
                    new ParticipantDto
                    {
                        UserId = user.Id,
                        Nickname = user.Nickname ?? "Player",
                        SynergyId = user.SynergyId,
                        IsReady = false
                    }
                }
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error creating race session");
            return Ok(new RaceSessionResponse
            {
                ResultCode = -1,
                Message = "Error creating session"
            });
        }
    }

    // POST /synergy/multiplayer/session/join - Join race session
    [HttpPost("session/join")]
    public async Task<ActionResult<RaceSessionResponse>> JoinRaceSession(
        [FromQuery] string synergyId,
        [FromQuery] int? sessionId = null,
        [FromQuery] string? joinCode = null)
    {
        try
        {
            var user = await _context.Users.FirstOrDefaultAsync(u => u.SynergyId == synergyId);
            if (user == null)
            {
                return Ok(new RaceSessionResponse
                {
                    ResultCode = -1,
                    Message = "User not found"
                });
            }

            RaceSession? session = null;
            if (sessionId.HasValue)
            {
                session = await _context.RaceSessions
                    .Include(s => s.Host)
                    .Include(s => s.Participants)
                    .ThenInclude(p => p.User)
                    .FirstOrDefaultAsync(s => s.Id == sessionId.Value);
            }
            else if (!string.IsNullOrEmpty(joinCode))
            {
                session = await _context.RaceSessions
                    .Include(s => s.Host)
                    .Include(s => s.Participants)
                    .ThenInclude(p => p.User)
                    .FirstOrDefaultAsync(s => s.SessionCode == joinCode);
            }

            if (session == null)
            {
                return Ok(new RaceSessionResponse
                {
                    ResultCode = -2,
                    Message = "Session not found"
                });
            }

            if (session.Status != "lobby")
            {
                return Ok(new RaceSessionResponse
                {
                    ResultCode = -3,
                    Message = "Session already started"
                });
            }

            if (session.Participants.Count >= session.MaxPlayers)
            {
                return Ok(new RaceSessionResponse
                {
                    ResultCode = -4,
                    Message = "Session is full"
                });
            }

            // Check if already in session
            if (session.Participants.Any(p => p.UserId == user.Id))
            {
                return Ok(new RaceSessionResponse
                {
                    ResultCode = -5,
                    Message = "Already in session"
                });
            }

            // Add participant
            var participant = new RaceParticipant
            {
                SessionId = session.Id,
                UserId = user.Id
            };

            _context.RaceParticipants.Add(participant);
            await _context.SaveChangesAsync();

            _logger.LogInformation("User {User} joined session {Code}", user.SynergyId, session.SessionCode);

            // Reload participants
            session = await _context.RaceSessions
                .Include(s => s.Host)
                .Include(s => s.Participants)
                .ThenInclude(p => p.User)
                .FirstAsync(s => s.Id == session.Id);

            return Ok(new RaceSessionResponse
            {
                ResultCode = 0,
                Session = new RaceSessionDto
                {
                    SessionId = session.Id,
                    SessionCode = session.SessionCode,
                    Track = session.Track,
                    CarClass = session.CarClass,
                    HostUserId = session.HostUserId,
                    HostNickname = session.Host?.Nickname ?? "Player",
                    CurrentPlayers = session.Participants.Count,
                    MaxPlayers = session.MaxPlayers,
                    Status = session.Status,
                    CreatedAt = session.CreatedAt
                },
                Participants = session.Participants.Select(p => new ParticipantDto
                {
                    UserId = p.UserId,
                    Nickname = p.User?.Nickname ?? "Player",
                    SynergyId = p.User?.SynergyId ?? "",
                    CarId = p.CarId,
                    IsReady = p.IsReady
                }).ToList()
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error joining race session");
            return Ok(new RaceSessionResponse
            {
                ResultCode = -1,
                Message = "Error joining session"
            });
        }
    }

    // GET /synergy/multiplayer/session/{sessionId} - Get session details
    [HttpGet("session/{sessionId}")]
    public async Task<ActionResult<RaceSessionResponse>> GetRaceSession(int sessionId)
    {
        try
        {
            var session = await _context.RaceSessions
                .Include(s => s.Host)
                .Include(s => s.Participants)
                .ThenInclude(p => p.User)
                .FirstOrDefaultAsync(s => s.Id == sessionId);

            if (session == null)
            {
                return Ok(new RaceSessionResponse
                {
                    ResultCode = -1,
                    Message = "Session not found"
                });
            }

            return Ok(new RaceSessionResponse
            {
                ResultCode = 0,
                Session = new RaceSessionDto
                {
                    SessionId = session.Id,
                    SessionCode = session.SessionCode,
                    Track = session.Track,
                    CarClass = session.CarClass,
                    HostUserId = session.HostUserId,
                    HostNickname = session.Host?.Nickname ?? "Player",
                    CurrentPlayers = session.Participants.Count,
                    MaxPlayers = session.MaxPlayers,
                    Status = session.Status,
                    CreatedAt = session.CreatedAt
                },
                Participants = session.Participants.Select(p => new ParticipantDto
                {
                    UserId = p.UserId,
                    Nickname = p.User?.Nickname ?? "Player",
                    SynergyId = p.User?.SynergyId ?? "",
                    CarId = p.CarId,
                    IsReady = p.IsReady,
                    FinishPosition = p.FinishPosition,
                    RaceTime = p.RaceTime
                }).ToList()
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting race session");
            return Ok(new RaceSessionResponse
            {
                ResultCode = -1,
                Message = "Error loading session"
            });
        }
    }

    // POST /synergy/multiplayer/session/{sessionId}/ready - Mark player as ready
    [HttpPost("session/{sessionId}/ready")]
    public async Task<ActionResult<SimpleResponse>> MarkReady(
        int sessionId,
        [FromQuery] string synergyId)
    {
        try
        {
            var user = await _context.Users.FirstOrDefaultAsync(u => u.SynergyId == synergyId);
            if (user == null)
            {
                return Ok(new SimpleResponse
                {
                    ResultCode = -1,
                    Message = "User not found"
                });
            }

            var participant = await _context.RaceParticipants
                .Include(p => p.Session)
                .FirstOrDefaultAsync(p => p.SessionId == sessionId && p.UserId == user.Id);

            if (participant == null)
            {
                return Ok(new SimpleResponse
                {
                    ResultCode = -2,
                    Message = "Not in this session"
                });
            }

            participant.IsReady = true;
            await _context.SaveChangesAsync();

            // Check if all players are ready
            var allReady = await _context.RaceParticipants
                .Where(p => p.SessionId == sessionId)
                .AllAsync(p => p.IsReady);

            if (allReady && participant.Session != null)
            {
                participant.Session.Status = "countdown";
                participant.Session.StartedAt = DateTime.UtcNow;
                await _context.SaveChangesAsync();

                _logger.LogInformation("Session {Session} starting - all players ready", sessionId);
            }

            return Ok(new SimpleResponse
            {
                ResultCode = 0,
                Message = "Ready"
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error marking ready");
            return Ok(new SimpleResponse
            {
                ResultCode = -1,
                Message = "Error updating status"
            });
        }
    }

    // ===== GHOST DATA (2 endpoints) =====

    // POST /synergy/multiplayer/ghost/upload - Upload ghost race data
    [HttpPost("ghost/upload")]
    public async Task<ActionResult<SimpleResponse>> UploadGhostData([FromBody] UploadGhostRequest request)
    {
        try
        {
            var user = await _context.Users.FirstOrDefaultAsync(u => u.SynergyId == request.SynergyId);
            if (user == null)
            {
                return Ok(new SimpleResponse
                {
                    ResultCode = -1,
                    Message = "User not found"
                });
            }

            var ghost = new GhostData
            {
                UserId = user.Id,
                Track = request.Track,
                CarId = request.CarId,
                RaceTime = request.RaceTime,
                TelemetryData = request.TelemetryData,
                UploadedAt = DateTime.UtcNow
            };

            _context.GhostData.Add(ghost);
            await _context.SaveChangesAsync();

            _logger.LogInformation("User {User} uploaded ghost for {Track} ({Time:F3}s)", 
                user.SynergyId, request.Track, request.RaceTime);

            return Ok(new SimpleResponse
            {
                ResultCode = 0,
                Message = $"Ghost uploaded (ID: {ghost.Id})"
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error uploading ghost data");
            return Ok(new SimpleResponse
            {
                ResultCode = -1,
                Message = "Error uploading ghost"
            });
        }
    }

    // GET /synergy/multiplayer/ghost/download - Download ghost race data
    [HttpGet("ghost/download")]
    public async Task<ActionResult<GhostDataResponse>> DownloadGhostData(
        [FromQuery] string track,
        [FromQuery] string? synergyId = null,
        [FromQuery] int? rank = null)
    {
        try
        {
            GhostData? ghost = null;

            if (!string.IsNullOrEmpty(synergyId))
            {
                // Get specific user's best ghost for this track
                var user = await _context.Users.FirstOrDefaultAsync(u => u.SynergyId == synergyId);
                if (user != null)
                {
                    ghost = await _context.GhostData
                        .Where(g => g.UserId == user.Id && g.Track == track)
                        .OrderBy(g => g.RaceTime)
                        .FirstOrDefaultAsync();
                }
            }
            else if (rank.HasValue)
            {
                // Get nth fastest ghost for this track
                var ghosts = await _context.GhostData
                    .Where(g => g.Track == track)
                    .OrderBy(g => g.RaceTime)
                    .Skip(rank.Value - 1)
                    .Take(1)
                    .Include(g => g.User)
                    .ToListAsync();

                ghost = ghosts.FirstOrDefault();
            }
            else
            {
                // Get fastest ghost for this track
                ghost = await _context.GhostData
                    .Where(g => g.Track == track)
                    .OrderBy(g => g.RaceTime)
                    .Include(g => g.User)
                    .FirstOrDefaultAsync();
            }

            if (ghost == null)
            {
                return Ok(new GhostDataResponse
                {
                    ResultCode = -1,
                    Message = "Ghost not found"
                });
            }

            // Increment download counter
            ghost.Downloads++;
            await _context.SaveChangesAsync();

            return Ok(new GhostDataResponse
            {
                ResultCode = 0,
                Ghost = new GhostDataDto
                {
                    GhostId = ghost.Id,
                    UserId = ghost.UserId,
                    Nickname = ghost.User?.Nickname ?? "Player",
                    Track = ghost.Track,
                    CarId = ghost.CarId,
                    RaceTime = ghost.RaceTime,
                    TelemetryData = ghost.TelemetryData,
                    UploadedAt = ghost.UploadedAt
                }
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error downloading ghost data");
            return Ok(new GhostDataResponse
            {
                ResultCode = -1,
                Message = "Error downloading ghost"
            });
        }
    }

    // ===== RACE RESULTS (2 endpoints) =====

    // POST /synergy/multiplayer/race/submit - Submit race results
    [HttpPost("race/submit")]
    public async Task<ActionResult<RaceResultResponse>> SubmitRaceResult([FromBody] SubmitRaceResultRequest request)
    {
        try
        {
            var user = await _context.Users.FirstOrDefaultAsync(u => u.SynergyId == request.SynergyId);
            if (user == null)
            {
                return Ok(new RaceResultResponse
                {
                    ResultCode = -1,
                    Message = "User not found"
                });
            }

            var participant = await _context.RaceParticipants
                .Include(p => p.Session)
                .FirstOrDefaultAsync(p => p.SessionId == request.SessionId && p.UserId == user.Id);

            if (participant == null)
            {
                return Ok(new RaceResultResponse
                {
                    ResultCode = -2,
                    Message = "Not in this session"
                });
            }

            // Update participant results
            participant.FinishPosition = request.Position;
            participant.RaceTime = request.RaceTime;

            // Calculate rewards based on position
            int goldReward = Math.Max(0, 100 - (request.Position - 1) * 20);
            int cashReward = Math.Max(0, 500 - (request.Position - 1) * 100);
            int xpReward = Math.Max(0, 200 - (request.Position - 1) * 30);

            participant.RewardGold = goldReward;
            participant.RewardCash = cashReward;
            participant.RewardXP = xpReward;

            // Apply rewards to user
            user.Gold = (user.Gold ?? 0) + goldReward;
            user.Cash = (user.Cash ?? 0) + cashReward;
            user.Experience = (user.Experience ?? 0) + xpReward;

            await _context.SaveChangesAsync();

            _logger.LogInformation("User {User} finished position {Pos} in session {Session}", 
                user.SynergyId, request.Position, request.SessionId);

            var response = new RaceResultResponse
            {
                ResultCode = 0,
                Position = request.Position,
                RewardGold = goldReward,
                RewardCash = cashReward,
                RewardXP = xpReward
            };

            // If ranked match, update rating
            if (participant.Session?.Status == "racing" || participant.Session?.Status == "countdown")
            {
                var rating = await _context.CompetitiveRatings
                    .FirstOrDefaultAsync(r => r.UserId == user.Id);

                if (rating == null)
                {
                    rating = new CompetitiveRating { UserId = user.Id, Rating = 1000 };
                    _context.CompetitiveRatings.Add(rating);
                }

                // Simple rating adjustment: +20 for 1st, +10 for 2nd, 0 for 3rd, -10 for 4th+
                int ratingChange = request.Position switch
                {
                    1 => 20,
                    2 => 10,
                    3 => 0,
                    _ => -10
                };

                rating.Rating += ratingChange;
                if (request.Position == 1) rating.Wins++;
                else rating.Losses++;
                rating.LastMatchAt = DateTime.UtcNow;

                // Update division based on rating
                rating.Division = rating.Rating switch
                {
                    >= 2000 => "Diamond",
                    >= 1500 => "Platinum",
                    >= 1200 => "Gold",
                    >= 900 => "Silver",
                    _ => "Bronze"
                };

                await _context.SaveChangesAsync();

                response.RatingChange = ratingChange;
                response.NewRating = rating.Rating;
            }

            return Ok(response);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error submitting race result");
            return Ok(new RaceResultResponse
            {
                ResultCode = -1,
                Message = "Error submitting result"
            });
        }
    }

    // GET /synergy/multiplayer/race/{sessionId}/results - Get race results
    [HttpGet("race/{sessionId}/results")]
    public async Task<ActionResult<RaceResultsResponse>> GetRaceResults(int sessionId)
    {
        try
        {
            var participants = await _context.RaceParticipants
                .Where(p => p.SessionId == sessionId && p.FinishPosition.HasValue)
                .Include(p => p.User)
                .OrderBy(p => p.FinishPosition)
                .ToListAsync();

            if (!participants.Any())
            {
                return Ok(new RaceResultsResponse
                {
                    ResultCode = -1,
                    Message = "No results yet"
                });
            }

            return Ok(new RaceResultsResponse
            {
                ResultCode = 0,
                Results = participants.Select(p => new ParticipantDto
                {
                    UserId = p.UserId,
                    Nickname = p.User?.Nickname ?? "Player",
                    SynergyId = p.User?.SynergyId ?? "",
                    CarId = p.CarId,
                    FinishPosition = p.FinishPosition,
                    RaceTime = p.RaceTime
                }).ToList()
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting race results");
            return Ok(new RaceResultsResponse
            {
                ResultCode = -1,
                Message = "Error loading results"
            });
        }
    }

    // ===== RANKED/COMPETITIVE (2 endpoints) =====

    // GET /synergy/multiplayer/ranked/rating - Get player's competitive rating
    [HttpGet("ranked/rating")]
    public async Task<ActionResult<RatingResponse>> GetCompetitiveRating([FromQuery] string synergyId)
    {
        try
        {
            var user = await _context.Users.FirstOrDefaultAsync(u => u.SynergyId == synergyId);
            if (user == null)
            {
                return Ok(new RatingResponse
                {
                    ResultCode = -1,
                    Message = "User not found"
                });
            }

            var rating = await _context.CompetitiveRatings
                .FirstOrDefaultAsync(r => r.UserId == user.Id);

            if (rating == null)
            {
                // Create default rating
                rating = new CompetitiveRating
                {
                    UserId = user.Id,
                    Rating = 1000,
                    Division = "Bronze"
                };
                _context.CompetitiveRatings.Add(rating);
                await _context.SaveChangesAsync();
            }

            return Ok(new RatingResponse
            {
                ResultCode = 0,
                Rating = new CompetitiveRatingDto
                {
                    UserId = user.Id,
                    Nickname = user.Nickname ?? "Player",
                    Rating = rating.Rating,
                    Wins = rating.Wins,
                    Losses = rating.Losses,
                    Draws = rating.Draws,
                    Division = rating.Division,
                    DivisionRank = rating.DivisionRank
                }
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting competitive rating");
            return Ok(new RatingResponse
            {
                ResultCode = -1,
                Message = "Error loading rating"
            });
        }
    }

    // GET /synergy/multiplayer/ranked/leaderboard - Get competitive leaderboard
    [HttpGet("ranked/leaderboard")]
    public async Task<ActionResult<CompetitiveLeaderboardResponse>> GetCompetitiveLeaderboard(
        [FromQuery] int limit = 100)
    {
        try
        {
            var ratings = await _context.CompetitiveRatings
                .Include(r => r.User)
                .OrderByDescending(r => r.Rating)
                .Take(limit)
                .ToListAsync();

            return Ok(new CompetitiveLeaderboardResponse
            {
                ResultCode = 0,
                Leaderboard = ratings.Select(r => new CompetitiveRatingDto
                {
                    UserId = r.UserId,
                    Nickname = r.User?.Nickname ?? "Player",
                    Rating = r.Rating,
                    Wins = r.Wins,
                    Losses = r.Losses,
                    Draws = r.Draws,
                    Division = r.Division,
                    DivisionRank = r.DivisionRank
                }).ToList()
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting competitive leaderboard");
            return Ok(new CompetitiveLeaderboardResponse
            {
                ResultCode = -1,
                Message = "Error loading leaderboard"
            });
        }
    }

    // Helper method to generate session codes
    private static string GenerateSessionCode()
    {
        var random = new Random();
        return random.Next(100000, 999999).ToString();
    }
}
