using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using ZB.MOM.WW.LmxProxy.Client.Domain;

namespace ZB.MOM.WW.LmxProxy.Client
{
    /// <summary>
    /// Interface for LmxProxy client operations
    /// </summary>
    public interface ILmxProxyClient : IDisposable, IAsyncDisposable
    {
        /// <summary>
        /// Gets or sets the default timeout for operations
        /// </summary>
        TimeSpan DefaultTimeout { get; set; }

        /// <summary>
        /// Connects to the LmxProxy service
        /// </summary>
        /// <param name="cancellationToken">Cancellation token.</param>
        Task ConnectAsync(CancellationToken cancellationToken = default);

        /// <summary>
        /// Disconnects from the LmxProxy service
        /// </summary>
        Task DisconnectAsync();

        /// <summary>
        /// Checks if the client is connected to the service
        /// </summary>
        Task<bool> IsConnectedAsync();

        /// <summary>
        /// Reads a single tag value
        /// </summary>
        /// <param name="address">The tag address to read.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        Task<Vtq> ReadAsync(string address, CancellationToken cancellationToken = default);

        /// <summary>
        /// Reads multiple tag values in a single batch
        /// </summary>
        /// <param name="addresses">The tag addresses to read.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        Task<IDictionary<string, Vtq>> ReadBatchAsync(IEnumerable<string> addresses, CancellationToken cancellationToken = default);

        /// <summary>
        /// Writes a single tag value
        /// </summary>
        /// <param name="address">The tag address to write.</param>
        /// <param name="value">The value to write.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        Task WriteAsync(string address, object value, CancellationToken cancellationToken = default);

        /// <summary>
        /// Writes multiple tag values in a single batch
        /// </summary>
        /// <param name="values">The tag addresses and values to write.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        Task WriteBatchAsync(IDictionary<string, object> values, CancellationToken cancellationToken = default);

        /// <summary>
        /// Subscribes to tag updates
        /// </summary>
        /// <param name="addresses">The tag addresses to subscribe to.</param>
        /// <param name="onUpdate">Callback invoked when tag values change.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        Task<ISubscription> SubscribeAsync(IEnumerable<string> addresses, Action<string, Vtq> onUpdate, CancellationToken cancellationToken = default);

        /// <summary>
        /// Gets the current metrics snapshot
        /// </summary>
        Dictionary<string, object> GetMetrics();
    }
}
