using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace PolyTrader.Core.Streaming
{
    /// <summary>
    /// Ein einzelner eth_subscribe("logs")-Filter. Positionsbasiert wie bei Alchemy:
    /// Topic0 = Event-Signaturen (OR-Array), Topic1..3 = indizierte Parameter
    /// (z.B. Adress-Filter). null an einer Position = Wildcard.
    /// </summary>
    public class LogSubscriptionFilter
    {
        public string Address { get; set; } = string.Empty;
        public List<string> Topic0 { get; set; } = new();
        public List<string>? Topic1 { get; set; }
        public List<string>? Topic2 { get; set; }
        public List<string>? Topic3 { get; set; }
    }

    /// <summary>
    /// Beschreibt, was ein WSS-Client abonniert. Der Aufrufer (Modul) baut die Filter
    /// aus seinen eigenen Daten (z.B. Wallets der getrackten Master-Trader) und batcht sie.
    /// </summary>
    public class BlockchainWssSubscription
    {
        public List<LogSubscriptionFilter> Filters { get; } = new();
    }

    /// <summary>
    /// Ein dekodiertes Log-Event aus dem Stream (domänen-agnostisch).
    /// Die fachliche Auswertung (welche Adresse, welche Reaktion) macht der Aufrufer.
    /// </summary>
    public class BlockchainLogEvent
    {
        public IReadOnlyList<string?> Topics { get; init; } = Array.Empty<string?>();
        public string TransactionHash { get; init; } = string.Empty;
        public string Address { get; init; } = string.Empty;
        public string Data { get; init; } = string.Empty;
    }

    /// <summary>
    /// Wiederverwendbare WSS-Verbindungsfähigkeit (Core-Infrastruktur). Kapselt Connect,
    /// eth_subscribe, Empfangs-Loop und Decode. Reconnect-Policy, Gating und der Filterinhalt
    /// liegen beim Aufrufer, damit jedes Modul eine eigene, gefilterte Instanz mit eigenem
    /// Key betreiben kann (kein geteilter, gefluteter Singleton-Stream).
    /// </summary>
    public interface IBlockchainWssClient
    {
        /// <summary>True während einer aktiven, verbundenen Session.</summary>
        bool IsHealthy { get; }

        /// <summary>
        /// Baut EINE Session auf: verbindet, sendet die Subscriptions, liest bis Close/Cancel/Fehler
        /// und ruft <paramref name="onLog"/> je dekodiertem Log. Wirft bei Verbindungsfehlern —
        /// die Reconnect-Entscheidung trifft der Aufrufer.
        /// </summary>
        Task ConnectAndListenAsync(string rpcUrl, BlockchainWssSubscription subscription,
            Action<BlockchainLogEvent> onLog, CancellationToken ct);
    }

    /// <summary>Erzeugt pro Aufrufer/Modul eine eigene WSS-Client-Instanz.</summary>
    public interface IBlockchainWssClientFactory
    {
        IBlockchainWssClient Create();
    }
}
