using ZB.MOM.WW.GalaxyRepository;

namespace ZB.MOM.WW.MxGateway.Server.Dashboard;

/// <summary>
///     In-process facade over <see cref="GalaxyBrowseProjector"/> for the dashboard's
///     BrowsePage. Provides one-level-at-a-time browse without going through the
///     gRPC stack. Backed by the same shared <see cref="IGalaxyHierarchyCache"/> the
///     gRPC service uses, so dashboard and external clients render identical results.
/// </summary>
public interface IDashboardBrowseService
{
    /// <summary>Returns root browse nodes (objects with no parent).</summary>
    /// <param name="filter">Filter arguments forwarded to the projector.</param>
    /// <returns>The root-level browse nodes and the cache sequence they were projected from.</returns>
    BrowseLevelResult GetRoots(BrowseFilterArgs filter);

    /// <summary>Returns the direct children of the given parent gobject id.</summary>
    /// <param name="parentGobjectId">The Galaxy gobject id of the parent to expand.</param>
    /// <param name="filter">Filter arguments forwarded to the projector.</param>
    /// <returns>The child browse nodes for the requested parent and the cache sequence they were projected from.</returns>
    BrowseLevelResult GetChildren(int parentGobjectId, BrowseFilterArgs filter);

    /// <summary>Current Galaxy cache sequence. Bumps after each successful refresh.</summary>
    ulong CurrentCacheSequence { get; }
}

/// <summary>Filter arguments forwarded into the projector.</summary>
/// <param name="TagNameGlob">Optional tag-name glob filter (case-insensitive).</param>
/// <param name="AlarmBearingOnly">When true, only return objects with at least one alarm-bearing attribute.</param>
/// <param name="HistorizedOnly">When true, only return objects with at least one historized attribute.</param>
public sealed record BrowseFilterArgs(
    string? TagNameGlob = null,
    bool AlarmBearingOnly = false,
    bool HistorizedOnly = false);

/// <summary>One level of browse data plus the cache sequence it was projected from.</summary>
/// <param name="Nodes">The direct-child nodes for the requested parent (or roots when no parent given).</param>
/// <param name="TotalCount">Total matching sibling count, post-filter.</param>
/// <param name="CacheSequence">The cache entry sequence this result was projected from.</param>
/// <param name="Error">Friendly error string if the projection failed; null on success.</param>
public sealed record BrowseLevelResult(
    IReadOnlyList<DashboardBrowseNode> Nodes,
    int TotalCount,
    ulong CacheSequence,
    string? Error = null);
