using ScadaLink.Commons.Types;

namespace ScadaLink.Commons.Interfaces.Services;

/// <summary>
/// Interface for invoking external system HTTP APIs.
/// Implemented by ExternalSystemGateway, consumed by ScriptRuntimeContext.
/// </summary>
public interface IExternalSystemClient
{
    /// <summary>
    /// Synchronous call to an external system. All failures returned to caller.
    /// </summary>
    Task<ExternalCallResult> CallAsync(
        string systemName,
        string methodName,
        IReadOnlyDictionary<string, object?>? parameters = null,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Attempt immediate delivery; on transient failure, hand to S&amp;F engine.
    /// Permanent failures returned to caller.
    /// </summary>
    Task<ExternalCallResult> CachedCallAsync(
        string systemName,
        string methodName,
        IReadOnlyDictionary<string, object?>? parameters = null,
        string? originInstanceName = null,
        CancellationToken cancellationToken = default);
}

/// <summary>
/// Result of an external system call.
/// </summary>
public record ExternalCallResult(
    bool Success,
    string? ResponseJson,
    string? ErrorMessage,
    bool WasBuffered = false)
{
    private dynamic? _response;
    private bool _responseParsed;

    /// <summary>
    /// Parsed response as a dynamic object. Returns null if ResponseJson is null or empty.
    /// Access properties directly: result.Response.result, result.Response.items[0].name, etc.
    /// </summary>
    public dynamic? Response
    {
        get
        {
            if (!_responseParsed)
            {
                _response = string.IsNullOrEmpty(ResponseJson)
                    ? null
                    : new DynamicJsonElement(System.Text.Json.JsonDocument.Parse(ResponseJson).RootElement);
                _responseParsed = true;
            }
            return _response;
        }
    }
}
