using adas_core.Application.Repositories.Interfaces;
using adas_core.Domain.Models.AppSettings;
using adas_core.Domain.Models.Pumps;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using MongoDB.Driver;

namespace adas_core.Infrastructure.Repositories
{
    public class PumpStateRepository : MongoRepository<PumpState>, IPumpStateRepository
    {
        private readonly ApiSettings _apiSettings;

        public PumpStateRepository(IOptions<ApiSettings> apiSettings, IMongoDatabase database)
            : base(database)
        {
            _apiSettings = apiSettings.Value;
        }


        public override string GetCollectionName()
        {
            return _apiSettings.PumpStates ?? "pump_states";
        }

        public override async Task CreateIndexes()
        {
            var indexModels = new List<CreateIndexModel<PumpState>>
            {
                // Clave única del snapshot
                new CreateIndexModel<PumpState>(
                    Builders<PumpState>.IndexKeys.Ascending(x => x.DeviceId),
                    new CreateIndexOptions { Unique = true, Name = "ux_deviceId" }),

                // Consultas por DeviceId + actualización temporal
                new CreateIndexModel<PumpState>(
                    Builders<PumpState>.IndexKeys
                        .Ascending(x => x.DeviceId)
                        .Descending(x => x.LastUpdated),
                    new CreateIndexOptions { Name = "ix_deviceId_lastUpdated" }),

                // indexado por PatientId
                new CreateIndexModel<PumpState>(
                    Builders<PumpState>.IndexKeys.Ascending(x => x.PatientId),
                    new CreateIndexOptions { Name = "ix_patientId" })
            };

            await Collection.Indexes.CreateManyAsync(indexModels);
        }

        public async Task<PumpState?> FindByDeviceIdAsync(string deviceId)
        {
            return await Collection.Find(x => x.DeviceId == deviceId).FirstOrDefaultAsync();
        }

        public async Task UpsertAsync(PumpState state)
        {
            var existing = await Collection
                .Find(x => x.DeviceId == state.DeviceId)
                .FirstOrDefaultAsync();

            if (existing != null)
                state.Id = existing.Id;
            else
                if (state.Id == ObjectId.Empty)
                    state.Id = ObjectId.GenerateNewId();

            await Collection.ReplaceOneAsync(
                x => x.DeviceId == state.DeviceId,
                state,
                new ReplaceOptions { IsUpsert = true });
        }

        public async Task<IEnumerable<PumpState>> GetAllAsync()
        {
            return await Collection.Find(Builders<PumpState>.Filter.Empty).ToListAsync();
        }
    }
}