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

namespace OmsorgCore.Application.Services;

public class FacilityService : IFacilityService
{
    private readonly IFacilityRepository _facilityRepository;

    public FacilityService(IFacilityRepository facilityRepository)
    {
        _facilityRepository = facilityRepository;
    }

    public Task<IReadOnlyList<Facility>> GetAllAsync(CancellationToken cancellationToken = default)
        => _facilityRepository.GetAllAsync(cancellationToken);

    public Task<(IReadOnlyList<Facility> Items, int TotalCount)> GetPagedAsync(
        string? search,
        string? crmStatus,
        bool followUpDueOnly,
        int page,
        int pageSize,
        CancellationToken cancellationToken = default)
        => _facilityRepository.GetPagedAsync(search, crmStatus, followUpDueOnly, page, pageSize, cancellationToken);

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

    public async Task<Facility> CreateAsync(Facility facility, CancellationToken cancellationToken = default)
    {
        await _facilityRepository.AddAsync(facility, cancellationToken);
        await _facilityRepository.SaveChangesAsync(cancellationToken);
        return facility;
    }

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

        facility.Name = updates.Name;
        facility.FacilityType = updates.FacilityType;
        facility.Website = updates.Website;
        facility.Street = updates.Street;
        facility.PostalCode = updates.PostalCode;
        facility.City = updates.City;
        facility.Country = updates.Country;
        facility.BillingStreet = updates.BillingStreet;
        facility.BillingPostalCode = updates.BillingPostalCode;
        facility.BillingCity = updates.BillingCity;
        facility.BillingCountry = updates.BillingCountry;
        facility.CrmStatus = updates.CrmStatus;
        facility.FollowUpDueDate = updates.FollowUpDueDate;
        facility.BillingRate = updates.BillingRate;
        facility.NightSurchargePercent = updates.NightSurchargePercent;
        facility.SaturdaySurchargePercent = updates.SaturdaySurchargePercent;
        facility.SundaySurchargePercent = updates.SundaySurchargePercent;
        facility.HolidaySurchargePercent = updates.HolidaySurchargePercent;
        facility.TravelCostRate = updates.TravelCostRate;
        facility.TravelCostMode = updates.TravelCostMode;
        facility.TravelCostPerKm = updates.TravelCostPerKm;
        facility.MealAllowanceRate = updates.MealAllowanceRate;
        facility.MinimumHours = updates.MinimumHours;
        facility.BillingInterval = updates.BillingInterval;
        facility.PaymentTermDays = updates.PaymentTermDays;
        facility.IndividualAgreements = updates.IndividualAgreements;
        facility.UpdatedAt = DateTime.UtcNow;

        await _facilityRepository.UpdateAsync(facility, cancellationToken);
        await _facilityRepository.SaveChangesAsync(cancellationToken);
        return facility;
    }

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

        return deleted;
    }

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

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

        return restored;
    }
}
