using Microsoft.EntityFrameworkCore;
using IamService.Domain.AggregatesModel.ComplianceAggregate;
using IamService.Domain.SeedWork;

namespace IamService.Infrastructure.Repositories;

public class ComplianceReportRepository : IComplianceReportRepository
{
    private readonly IamServiceContext _context;
    public IUnitOfWork UnitOfWork => _context;

    public ComplianceReportRepository(IamServiceContext context) => _context = context;

    public ComplianceReport Add(ComplianceReport report) => _context.ComplianceReports.Add(report).Entity;
    public void Update(ComplianceReport report) => _context.Entry(report).State = EntityState.Modified;

    public async Task<ComplianceReport?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default)
        => await _context.ComplianceReports.FirstOrDefaultAsync(x => x.Id == id, cancellationToken);

    public async Task<ComplianceReport?> GetByIdWithViolationsAsync(Guid id, CancellationToken cancellationToken = default)
        => await _context.ComplianceReports.Include(x => x.Violations).FirstOrDefaultAsync(x => x.Id == id, cancellationToken);

    public async Task<IEnumerable<ComplianceReport>> GetByTypeAsync(int reportTypeId, int take = 20, CancellationToken cancellationToken = default)
        => await _context.ComplianceReports
            .Where(x => EF.Property<ComplianceReportType>(x, "_reportType").Id == reportTypeId)
            .OrderByDescending(x => EF.Property<DateTime>(x, "_createdAt"))
            .Take(take)
            .ToListAsync(cancellationToken);

    public async Task<IEnumerable<ComplianceReport>> GetRecentAsync(int take = 20, CancellationToken cancellationToken = default)
        => await _context.ComplianceReports
            .OrderByDescending(x => EF.Property<DateTime>(x, "_createdAt"))
            .Take(take)
            .ToListAsync(cancellationToken);

    public async Task<IEnumerable<ComplianceViolation>> GetUnresolvedViolationsAsync(CancellationToken cancellationToken = default)
        => await _context.ComplianceViolations
            .Where(x => !EF.Property<bool>(x, "_resolved"))
            .ToListAsync(cancellationToken);
}
