using Microsoft.EntityFrameworkCore;

public class EncounterReadService : IEncounterReadService
{
    private readonly GatewayDbContext _db;

    public EncounterReadService(GatewayDbContext db) => _db = db;

    public async Task<List<WardEncounterSummary>> ListActiveAsync(string? department)
    {
        var q = _db.Encounters
            .Include(e => e.Patient)
            .Where(e => e.Status == EncounterStatus.Active);

        if (!string.IsNullOrEmpty(department))
        {
            var dept = DepartmentExtensions.FromDbString(department);
            q = q.Where(e => e.Department == dept);
        }

        var encounters = await q
            .OrderByDescending(e => e.AdmittedAt)
            .ToListAsync();

        if (encounters.Count == 0)
            return [];

        var encounterIds = encounters.Select(e => e.Id).ToList();
        var openAlertCounts = await _db.ClinicalAlerts
            .AsNoTracking()
            .Where(a => encounterIds.Contains(a.EncounterId) && a.Status == AlertStatus.Open)
            .GroupBy(a => a.EncounterId)
            .Select(g => new { EncounterId = g.Key, Count = g.Count() })
            .ToDictionaryAsync(x => x.EncounterId, x => x.Count);

        return encounters.Select(e => new WardEncounterSummary(
            e.Id,
            e.Patient.Mrn,
            e.Patient.FirstName,
            e.Patient.LastName,
            e.Department,
            e.RoomBed,
            e.AttendingPhysician,
            e.AdmittedAt,
            openAlertCounts.GetValueOrDefault(e.Id),
            News2Score: null,
            QsofaScore: null,
            SepsisBundleStatus: null)).ToList();
    }

    public async Task<EncounterDetail?> GetByIdAsync(Guid id)
    {
        var enc = await _db.Encounters
            .Include(e => e.Patient)
            .AsNoTracking()
            .FirstOrDefaultAsync(e => e.Id == id);

        if (enc is null) return null;

        var observations = await _db.Observations
            .AsNoTracking()
            .Where(o => o.EncounterId == id)
            .OrderByDescending(o => o.RecordedAt)
            .Take(10)
            .ToListAsync();

        var alerts = await _db.ClinicalAlerts
            .AsNoTracking()
            .Where(a => a.EncounterId == id && a.Status == AlertStatus.Open)
            .OrderByDescending(a => a.TriggeredAt)
            .ToListAsync();

        return new EncounterDetail(
            enc.Id,
            enc.PatientId,
            enc.Patient.Mrn,
            enc.Patient.FirstName,
            enc.Patient.LastName,
            enc.Department,
            enc.Status,
            enc.RoomBed,
            enc.AttendingPhysician,
            enc.AdmittedAt,
            observations,
            alerts);
    }
}
