using Akka.Actor;
using Akka.Cluster.Tools.PublishSubscribe;
using ZB.MOM.WW.OtOpcUa.Commons.Messages.Drivers;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;

namespace ZB.MOM.WW.OtOpcUa.Runtime.Drivers;

/// <summary>
///     Forwards <see cref="DriverHealth"/> transitions to the cluster-wide
///     <c>driver-health</c> DistributedPubSub topic. Consumed by the AdminUI
///     <c>DriverStatusSignalRBridge</c>.
/// </summary>
public sealed class AkkaDriverHealthPublisher : IDriverHealthPublisher
{
    /// <summary>The DistributedPubSub topic name for driver-health snapshots — single source
    /// of truth on the message contract itself.</summary>
    public const string TopicName = DriverHealthChanged.TopicName;

    private readonly ActorSystem _system;

    /// <summary>Initializes a new instance of <see cref="AkkaDriverHealthPublisher"/>.</summary>
    /// <param name="system">The Akka actor system used to resolve the DPS mediator.</param>
    public AkkaDriverHealthPublisher(ActorSystem system) => _system = system;

    /// <inheritdoc />
    public void Publish(string clusterId, string driverInstanceId, DriverHealth health, int errorCount5Min)
    {
        var msg = new DriverHealthChanged(
            clusterId,
            driverInstanceId,
            health.State.ToString(),
            health.LastSuccessfulRead,
            health.LastError,
            errorCount5Min,
            DateTime.UtcNow);
        DistributedPubSub.Get(_system).Mediator.Tell(new Publish(TopicName, msg));
    }
}
