using Fitness_core_BE.Interfaces; using Fitness_core_BE.Models; using Microsoft.EntityFrameworkCore; namespace Fitness_core_BE.Repos { public class PlaceRepo : IPlaceRepo { private readonly TenantDbContext _context; public PlaceRepo(TenantDbContext context) { _context = context; } public async Task> GetAllPlaces(Guid clientId, bool includeInactive = false) { var query = _context.Places.Where(p => p.FKClientId == clientId); if (!includeInactive) query = query.Where(p => p.IsActive); return await query.OrderBy(p => p.Name).ToListAsync(); } public Task GetPlaceById(Guid placeId) => _context.Places.FirstOrDefaultAsync(p => p.PlaceId == placeId); public async Task CreatePlace(Place place) { place.PlaceId = Guid.NewGuid(); place.CreatedAt = DateTime.UtcNow; place.IsActive = true; _context.Places.Add(place); return place; } public async Task UpdatePlace(Place place) { var existing = await _context.Places.FindAsync(place.PlaceId) ?? throw new KeyNotFoundException("Place not found"); existing.Name = place.Name; existing.Description = place.Description; existing.IsActive = place.IsActive; return existing; } public async Task SetPlaceActive(Guid placeId, Guid clientId, bool isActive) { var place = await _context.Places .FirstOrDefaultAsync(p => p.PlaceId == placeId && p.FKClientId == clientId); if (place == null) return null; place.IsActive = isActive; return place; } public Task GetDeviceByIdForClientAsync(Guid deviceId, Guid clientId) => _context.AccessDevices .FirstOrDefaultAsync(d => d.DeviceId == deviceId && d.FKClientId == clientId); public async Task> GetPlaceNamesByIdsAsync(List placeIds) { return await _context.Places .Where(p => placeIds.Contains(p.PlaceId)) .ToDictionaryAsync(p => p.PlaceId, p => p.Name); } public async Task> GetDevicesByPlaceIdsAsync(List placeIds) { var devices = await _context.AccessDevices .Where(d => d.FKPlaceId != null && placeIds.Contains(d.FKPlaceId.Value)) .ToListAsync(); return devices.ToDictionary(d => d.FKPlaceId!.Value, d => d); } public Task IsDeviceAssignedToAnotherPlaceAsync(Guid deviceId, Guid placeId) => _context.AccessDevices .AnyAsync(d => d.DeviceId == deviceId && d.FKPlaceId != null && d.FKPlaceId != placeId); public async Task AssignDeviceAsync(Guid placeId, Guid deviceId) { // A device can only sit in one place at a time -- clear anywhere else it's // currently assigned before pointing it at this place. var previouslyAssigned = await _context.AccessDevices .Where(d => d.FKPlaceId == placeId && d.DeviceId != deviceId) .ToListAsync(); foreach (var device in previouslyAssigned) device.FKPlaceId = null; var target = await _context.AccessDevices.FindAsync(deviceId) ?? throw new KeyNotFoundException("Device not found"); target.FKPlaceId = placeId; } public async Task UnassignDeviceAsync(Guid placeId) { var devices = await _context.AccessDevices .Where(d => d.FKPlaceId == placeId) .ToListAsync(); foreach (var device in devices) device.FKPlaceId = null; } public async Task SetPlanPlacesAsync(Guid customerPlanId, List placeIds) { var existing = await _context.CustomerPlanPlaces .Where(pp => pp.FKCustomerPlanId == customerPlanId) .ToListAsync(); _context.CustomerPlanPlaces.RemoveRange(existing); foreach (var placeId in placeIds.Distinct()) { _context.CustomerPlanPlaces.Add(new CustomerPlanPlace { CustomerPlanPlaceId = Guid.NewGuid(), FKCustomerPlanId = customerPlanId, FKPlaceId = placeId }); } } public Task> GetPlaceIdsForPlanAsync(Guid customerPlanId) => _context.CustomerPlanPlaces .Where(pp => pp.FKCustomerPlanId == customerPlanId) .Select(pp => pp.FKPlaceId) .ToListAsync(); public async Task>> GetPlaceIdsByPlanIdsAsync(List customerPlanIds) { var rows = await _context.CustomerPlanPlaces .Where(pp => customerPlanIds.Contains(pp.FKCustomerPlanId)) .ToListAsync(); return rows .GroupBy(pp => pp.FKCustomerPlanId) .ToDictionary(g => g.Key, g => g.Select(pp => pp.FKPlaceId).ToList()); } } }