#nullable enable
using Baya.Application.Models.Catalog;
using Baya.Application.Models.Common;
using Baya.Domain.Entities.Catalog;

namespace Baya.Application.Contracts.Persistence;

/// <summary>
/// A nurse's priced offerings — the atomic bookable unit. Writes go through the owning-nurse tenancy check;
/// reads project to <see cref="VariantDto"/> with resolved category/option labels. The duplicate-listing
/// guard is a pre-check here plus the filtered unique index backstop in the EF configuration.
/// </summary>
public interface INurseServiceVariantRepository
{
    Task AddAsync(NurseServiceVariant variant, CancellationToken cancellationToken);

    /// <summary>Tracked, tenancy-scoped getter for owner scalar edits/toggle. Null if not owned/absent —
    /// existence of another nurse's variant is never leaked.</summary>
    Task<NurseServiceVariant?> GetOwnedAsync(long id, long nurseId, CancellationToken cancellationToken);

    /// <summary>Duplicate-listing pre-check: a non-deleted variant with this exact option-set already exists
    /// for the nurse+category. <paramref name="excludeVariantId"/> skips the variant being edited.</summary>
    Task<bool> DuplicateHashExistsAsync(long nurseId, long serviceCategoryId, string optionSetHash, long? excludeVariantId, CancellationToken cancellationToken);

    /// <summary>The nurse's own offerings (active + inactive), paginated, active-first, resolved labels.</summary>
    Task<PagedResult<VariantDto>> ListMineAsync(long nurseId, int page, int pageSize, CancellationToken cancellationToken);

    /// <summary>Full projection for the owning nurse — any status. Null if not owned/absent.</summary>
    Task<VariantDto?> GetOwnedProjectedAsync(long id, long nurseId, CancellationToken cancellationToken);

    /// <summary>Full projection for admin — any status. Null if absent.</summary>
    Task<VariantDto?> GetProjectedAsync(long id, CancellationToken cancellationToken);

    /// <summary>Public-safe projection: an <b>active</b> variant only. Null when missing/inactive.</summary>
    Task<VariantDto?> GetPublicProjectedAsync(long id, CancellationToken cancellationToken);
}
