using adas_core.Domain.Enums;
using adas_core.Domain.Models;
using adas_core.Domain.Models.DTO;
using adas_core.Domain.Models.Filter;
using adas_core.Domain.Models.MongoModels;
using MongoDB.Bson;
using MongoDB.Driver;

namespace adas_core.Application.Repositories.Interfaces;

public interface IPointOfCareRepository : IMongoRepository<PointOfCare>
{
    Task Delete(ObjectId id);

    Task Update(PointOfCare pointOfCare);

    Task UpdateUnitId(ObjectId id, Unit unit);

    Task UpdateConfiguration(ObjectId id, PointOfCareConfiguration configuration);

    Task<PointOfCare?> FindById(ObjectId id);

    Task<IEnumerable<PointOfCare>?> FindAllByUnitId(ObjectId unit);

    Task<IEnumerable<PointOfCare>?> FindByRoom(string room);

    Task<List<PointOfCare>> FindByFilter(FilterDefinition<PointOfCare> filter,
        ProjectionDefinition<PointOfCare>? projection = null);

    Task<IEnumerable<PointOfCare>?> FindByBed(string bed);
    Task<List<PointOfCare>?> GetAll();
    Task<List<PointOfCare>?> GetAllConfigs();

    Task<List<PointOfCare>?> GetAllLocationInfo();

    Task<PointOfCare?> GetPoCConfiguration(ObjectId pocId);


    Task<PointOfCare?> FindByBedAndUnitId(string? bed, ObjectId unitId);

    Task<PointOfCare?> FindByPatientLocation(PatientLocation patientLocation);

    Task<IEnumerable<PointOfCare>> FindByUnitAndStatus(ObjectId unitId, StatusEnum.PointOfCare status,
        bool excludeVirtual = false);

    Task UpdateRelayConfig(ObjectId pocId, List<Relay> relayConfig);
    Task UpdateRelayConfig(ObjectId pocId, List<ObjectId> relayConfig);

    IFindFluent<PointOfCare, PointOfCare> GetPaginatedPoCs(PaginationFilter filter);
    Task<long> CountByUnitId(ObjectId unitId);
    Task<long> CountVirtualsByUnitId(ObjectId unitId);
    Task<bool> DeleteManyByUnitId(ObjectId unitId);
    Task<PointOfCare?> FindByIdAllConfig(ObjectId id);
    Task<HashSet<ObjectId>> FindAllIdCamerasInUse();
    Task<HashSet<ObjectId>> FindAllIdRelaysInUse();
    Task<HashSet<ObjectId>> FindAllIdBeaconsInUse();
    Task<IEnumerable<PointOfCare>?> FindAllByUnitIdWithDevices(ObjectId unitId);
}