using Microsoft.EntityFrameworkCore;
using OmsorgCore.Application.Abstractions;
using OmsorgCore.Infrastructure.Persistence;

namespace OmsorgCore.Infrastructure.Repositories;

/// <summary>
/// Verwendungsprüfung für die Liste "Qualification" — anders als die übrigen String-Feld-Listen
/// (<see cref="StringFieldValueListUsageChecker"/>) wird ihr Wert von DREI Entitäten referenziert
/// (Employee.Qualification, Order.RequiredQualification, FacilityQualificationRate.Qualification).
/// ValueListService.FindUsagesAsync wählt
/// pro Key nur den ERSTEN registrierten Checker aus, daher eine eigene Klasse statt zwei separater
/// StringFieldValueListUsageChecker-Registrierungen mit demselben Key (die zweite würde sonst nie
/// befragt und das Löschen eines noch verwendeten Werts fälschlich erlauben).
/// </summary>
public class QualificationValueListUsageChecker : IValueListUsageChecker
{
    private readonly OmsorgCoreDbContext _db;

    public string Key => "Qualification";

    public QualificationValueListUsageChecker(OmsorgCoreDbContext db)
    {
        _db = db;
    }

    public async Task<IReadOnlyList<ValueListUsageEntry>> FindUsagesAsync(Guid itemId, string itemValue, CancellationToken cancellationToken = default)
    {
        var employeeUsages = await _db.Employees.AsNoTracking()
            .Where(e => e.Qualification == itemValue)
            .Select(e => new ValueListUsageEntry("Employee", e.Id, $"{e.FirstName} {e.LastName}"))
            .ToListAsync(cancellationToken);

        var orderUsages = await _db.Orders.AsNoTracking()
            .Where(o => o.RequiredQualification == itemValue)
            .Select(o => new ValueListUsageEntry("Order", o.Id, $"Auftrag {o.Id}"))
            .ToListAsync(cancellationToken);

        var facilityQualificationRateUsages = await _db.FacilityQualificationRates.AsNoTracking()
            .Where(r => r.Qualification == itemValue)
            .Select(r => new ValueListUsageEntry("FacilityQualificationRate", r.Id, $"Qualifikationspreis {r.Id}"))
            .ToListAsync(cancellationToken);

        return employeeUsages.Concat(orderUsages).Concat(facilityQualificationRateUsages).ToList();
    }
}
