using OmsorgCore.Application.Abstractions;
using OmsorgCore.Domain.Entities;

namespace OmsorgCore.Application.Services;

public class EmployeeFacilityDistanceService : IEmployeeFacilityDistanceService
{
    private readonly IEmployeeFacilityDistanceRepository _employeeFacilityDistanceRepository;

    public EmployeeFacilityDistanceService(IEmployeeFacilityDistanceRepository employeeFacilityDistanceRepository)
    {
        _employeeFacilityDistanceRepository = employeeFacilityDistanceRepository;
    }

    public Task<IReadOnlyList<EmployeeFacilityDistance>> GetByFacilityIdAsync(Guid facilityId, CancellationToken cancellationToken = default)
        => _employeeFacilityDistanceRepository.GetByFacilityIdAsync(facilityId, cancellationToken);

    public Task<EmployeeFacilityDistance?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default)
        => _employeeFacilityDistanceRepository.GetByIdAsync(id, cancellationToken);

    public Task<EmployeeFacilityDistance?> GetByFacilityAndEmployeeAsync(Guid facilityId, Guid employeeId, CancellationToken cancellationToken = default)
        => _employeeFacilityDistanceRepository.GetByFacilityAndEmployeeAsync(facilityId, employeeId, cancellationToken);

    public async Task<EmployeeFacilityDistance> CreateAsync(EmployeeFacilityDistance distance, CancellationToken cancellationToken = default)
    {
        await _employeeFacilityDistanceRepository.AddAsync(distance, cancellationToken);
        await _employeeFacilityDistanceRepository.SaveChangesAsync(cancellationToken);
        return distance;
    }

    public async Task<EmployeeFacilityDistance?> UpdateAsync(Guid id, EmployeeFacilityDistance updates, CancellationToken cancellationToken = default)
    {
        var distance = await _employeeFacilityDistanceRepository.GetByIdAsync(id, cancellationToken);
        if (distance is null)
        {
            return null;
        }

        distance.DistanceKm = updates.DistanceKm;
        distance.UpdatedAt = DateTime.UtcNow;

        await _employeeFacilityDistanceRepository.UpdateAsync(distance, cancellationToken);
        await _employeeFacilityDistanceRepository.SaveChangesAsync(cancellationToken);
        return distance;
    }

    public async Task<bool> DeleteAsync(Guid id, CancellationToken cancellationToken = default)
    {
        var deleted = await _employeeFacilityDistanceRepository.SoftDeleteAsync(id, cancellationToken);
        if (deleted)
        {
            await _employeeFacilityDistanceRepository.SaveChangesAsync(cancellationToken);
        }

        return deleted;
    }

    public Task<IReadOnlyList<EmployeeFacilityDistance>> GetDeletedAsync(string? search, CancellationToken cancellationToken = default)
        => _employeeFacilityDistanceRepository.GetDeletedAsync(search, cancellationToken);

    public async Task<bool> RestoreAsync(Guid id, CancellationToken cancellationToken = default)
    {
        var restored = await _employeeFacilityDistanceRepository.RestoreAsync(id, cancellationToken);
        if (restored)
        {
            await _employeeFacilityDistanceRepository.SaveChangesAsync(cancellationToken);
        }

        return restored;
    }
}
