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<User> Users => _database.GetCollection<User>("users");
        public IMongoCollection<QRCodeHistory> QRCodeHistory => _database.GetCollection<QRCodeHistory>("qrCodeHistory");
        public IMongoCollection<Plan> Plans => _database.GetCollection<Plan>("plans");
        public IMongoCollection<Order> Orders => _database.GetCollection<Order>("orders");
        public IMongoCollection<AdFreeSession>? AdFreeSessions => _isConnected ? _database?.GetCollection<AdFreeSession>("ad_free_sessions") : null;
        public IMongoCollection<Rating>? Ratings => _isConnected ? _database?.GetCollection<Rating>("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<User>.IndexKeys;
            await Users.Indexes.CreateManyAsync(new[]
            {
                new CreateIndexModel<User>(userIndexKeys.Ascending(u => u.Email)),
                new CreateIndexModel<User>(userIndexKeys.Ascending(u => u.ProviderId)),
                new CreateIndexModel<User>(userIndexKeys.Ascending(u => u.Provider)),
                new CreateIndexModel<User>(userIndexKeys.Ascending(u => u.LastLoginAt)),
                new CreateIndexModel<User>(userIndexKeys.Ascending(u => u.IsPremium))
            });

            // QR Code History indexes
            var qrIndexKeys = Builders<QRCodeHistory>.IndexKeys;
            await QRCodeHistory.Indexes.CreateManyAsync(new[]
            {
                new CreateIndexModel<QRCodeHistory>(qrIndexKeys.Ascending(q => q.UserId)),
                new CreateIndexModel<QRCodeHistory>(qrIndexKeys.Ascending(q => q.CreatedAt)),
                new CreateIndexModel<QRCodeHistory>(qrIndexKeys.Ascending(q => q.Type)),
                new CreateIndexModel<QRCodeHistory>(qrIndexKeys.Ascending(q => q.IsActive)),
                new CreateIndexModel<QRCodeHistory>(
                    Builders<QRCodeHistory>.IndexKeys.Combine(
                        qrIndexKeys.Ascending(q => q.UserId),
                        qrIndexKeys.Descending(q => q.CreatedAt)
                    )
                )
            });

            // Ad Free Session indexes
            var adFreeIndexKeys = Builders<AdFreeSession>.IndexKeys;
            await AdFreeSessions.Indexes.CreateManyAsync(new[]
            {
                new CreateIndexModel<AdFreeSession>(adFreeIndexKeys.Ascending(a => a.UserId)),
                new CreateIndexModel<AdFreeSession>(adFreeIndexKeys.Ascending(a => a.ExpiresAt)),
                new CreateIndexModel<AdFreeSession>(adFreeIndexKeys.Ascending(a => a.IsActive)),
                new CreateIndexModel<AdFreeSession>(
                    Builders<AdFreeSession>.IndexKeys.Combine(
                        adFreeIndexKeys.Ascending(a => a.UserId),
                        adFreeIndexKeys.Ascending(a => a.IsActive),
                        adFreeIndexKeys.Descending(a => a.ExpiresAt)
                    )
                )
            });

            // Rating indexes
            var ratingIndexKeys = Builders<Rating>.IndexKeys;
            await Ratings.Indexes.CreateManyAsync(new[]
            {
                new CreateIndexModel<Rating>(ratingIndexKeys.Descending(r => r.CreatedAt)),
                new CreateIndexModel<Rating>(ratingIndexKeys.Ascending(r => r.UserId)),
                new CreateIndexModel<Rating>(ratingIndexKeys.Ascending(r => r.RatingValue)),
                new CreateIndexModel<Rating>(ratingIndexKeys.Ascending(r => r.Culture))
            });
        }
    }
}