using SIGCM2.Domain.Entities;

namespace SIGCM2.Application.Abstractions.Persistence;

public interface IRubroRepository
{
    Task<int> AddAsync(Rubro rubro, CancellationToken ct = default);
    Task<Rubro?> GetByIdAsync(int id, CancellationToken ct = default);
    Task<IReadOnlyList<Rubro>> GetAllAsync(bool incluirInactivos, CancellationToken ct = default);

    /// <summary>
    /// Returns all descendants of rootId via recursive CTE (used only by MoveRubro for cycle detection).
    /// </summary>
    Task<IReadOnlyList<Rubro>> GetDescendantsAsync(int rootId, CancellationToken ct = default);

    Task UpdateAsync(Rubro rubro, CancellationToken ct = default);

    /// <summary>
    /// Returns the count of active children for the given parentId.
    /// Used by soft-delete to guard against deleting non-leaf rubros.
    /// </summary>
    Task<int> CountActiveChildrenAsync(int id, CancellationToken ct = default);

    /// <summary>
    /// Returns MAX(Orden)+1 among siblings of the given parentId (0 if no siblings).
    /// Used for append-on-create ordering.
    /// </summary>
    Task<int> GetMaxOrdenAsync(int? parentId, CancellationToken ct = default);

    /// <summary>
    /// Returns true if an active Rubro with the same Nombre (CI) exists under the same parentId,
    /// optionally excluding the Rubro with the given id (for rename operations).
    /// </summary>
    Task<bool> ExistsByNombreUnderParentAsync(int? parentId, string nombre, int? excludeId, CancellationToken ct = default);

    /// <summary>
    /// Returns the depth of the given parentId (0 if parentId is null = root level).
    /// Uses a recursive CTE going upward through ancestors.
    /// </summary>
    Task<int> GetDepthAsync(int? parentId, CancellationToken ct = default);
}
