using MongoDB.Driver; using QRRapidoApp.Models; namespace QRRapidoApp.Data { public class MongoDbContext { private readonly IMongoDatabase? _database; private readonly bool _isConnected; public MongoDbContext(IConfiguration configuration, IMongoClient? mongoClient = null) { var connectionString = configuration.GetConnectionString("MongoDB"); connectionString = connectionString + (connectionString.Contains("?") ? "&" : "?") + "maxPoolSize=200&minPoolSize=50&maxIdleTimeMS=30000"; if (mongoClient != null && !string.IsNullOrEmpty(connectionString)) { try { var databaseName = MongoUrl.Create(connectionString).DatabaseName; _database = mongoClient.GetDatabase(databaseName); _isConnected = true; } catch { _isConnected = false; } } else { _isConnected = false; } } public IMongoCollection Users => _database.GetCollection("users"); public IMongoCollection QRCodeHistory => _database.GetCollection("qrCodeHistory"); public IMongoCollection Plans => _database.GetCollection("plans"); public IMongoCollection Orders => _database.GetCollection("orders"); public IMongoCollection? AdFreeSessions => _isConnected ? _database?.GetCollection("ad_free_sessions") : null; public IMongoCollection? Ratings => _isConnected ? _database?.GetCollection("ratings") : null; public IMongoDatabase? Database => _isConnected ? _database : null; public bool IsConnected => _isConnected; public async Task InitializeAsync() { if (_isConnected) { // Create indexes for better performance await CreateIndexesAsync(); } } private async Task CreateIndexesAsync() { // User indexes var userIndexKeys = Builders.IndexKeys; await Users.Indexes.CreateManyAsync(new[] { new CreateIndexModel(userIndexKeys.Ascending(u => u.Email)), new CreateIndexModel(userIndexKeys.Ascending(u => u.ProviderId)), new CreateIndexModel(userIndexKeys.Ascending(u => u.Provider)), new CreateIndexModel(userIndexKeys.Ascending(u => u.LastLoginAt)), new CreateIndexModel(userIndexKeys.Ascending(u => u.IsPremium)) }); // QR Code History indexes var qrIndexKeys = Builders.IndexKeys; await QRCodeHistory.Indexes.CreateManyAsync(new[] { new CreateIndexModel(qrIndexKeys.Ascending(q => q.UserId)), new CreateIndexModel(qrIndexKeys.Ascending(q => q.CreatedAt)), new CreateIndexModel(qrIndexKeys.Ascending(q => q.Type)), new CreateIndexModel(qrIndexKeys.Ascending(q => q.IsActive)), new CreateIndexModel( Builders.IndexKeys.Combine( qrIndexKeys.Ascending(q => q.UserId), qrIndexKeys.Descending(q => q.CreatedAt) ) ) }); // Ad Free Session indexes var adFreeIndexKeys = Builders.IndexKeys; await AdFreeSessions.Indexes.CreateManyAsync(new[] { new CreateIndexModel(adFreeIndexKeys.Ascending(a => a.UserId)), new CreateIndexModel(adFreeIndexKeys.Ascending(a => a.ExpiresAt)), new CreateIndexModel(adFreeIndexKeys.Ascending(a => a.IsActive)), new CreateIndexModel( Builders.IndexKeys.Combine( adFreeIndexKeys.Ascending(a => a.UserId), adFreeIndexKeys.Ascending(a => a.IsActive), adFreeIndexKeys.Descending(a => a.ExpiresAt) ) ) }); // Rating indexes var ratingIndexKeys = Builders.IndexKeys; await Ratings.Indexes.CreateManyAsync(new[] { new CreateIndexModel(ratingIndexKeys.Descending(r => r.CreatedAt)), new CreateIndexModel(ratingIndexKeys.Ascending(r => r.UserId)), new CreateIndexModel(ratingIndexKeys.Ascending(r => r.RatingValue)), new CreateIndexModel(ratingIndexKeys.Ascending(r => r.Culture)) }); } } }