using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using PolyTrader.Modules.Accounting.Models;

namespace PolyTrader.Modules.Accounting.Services
{
    /// <summary>
    /// Unabhängige Polymarket-Activity-Quelle (Data-API /activity, ALLE Typen). Interface, damit die
    /// Buchungslogik ohne Live-API testbar/offline lauffähig ist; die Live-Implementierung (Zielland)
    /// mappt die reale API-JSON auf <see cref="RawActivity"/> und speichert den Rohschnappschuss.
    /// </summary>
    public interface IActivitySource
    {
        /// <summary>Activity ab <paramref name="since"/> (null = volle Historie/Backfill), paginiert.</summary>
        Task<IReadOnlyList<RawActivity>> GetActivityAsync(string wallet, DateTime? since, CancellationToken ct);
    }

    /// <summary>On-Chain-USDC-Transfers des Safe-Wallets (ERC-20-Logs). Live-Impl über Alchemy (Zielland).</summary>
    public interface ITransferSource
    {
        Task<IReadOnlyList<RawTransfer>> GetTransfersAsync(string wallet, DateTime? since, CancellationToken ct);
    }

    /// <summary>On-Chain-USDC-Saldo als Balance-Anker (Soll-Ist). Live-Impl über GetUsdcBalanceAsync.</summary>
    public interface IBalanceAnchorSource
    {
        Task<decimal?> GetBalanceAsync(string wallet, CancellationToken ct);
    }

    /// <summary>
    /// Offline-Stubs: das Modul läuft ohne Live-Anbindung vollständig (Ingest bucht dann korrekt nichts).
    /// Im Zielland werden die echten Quellen registriert (Muster wie NullFarmingMarketSource).
    /// </summary>
    public sealed class NullActivitySource : IActivitySource
    {
        public Task<IReadOnlyList<RawActivity>> GetActivityAsync(string wallet, DateTime? since, CancellationToken ct)
            => Task.FromResult((IReadOnlyList<RawActivity>)Array.Empty<RawActivity>());
    }

    public sealed class NullTransferSource : ITransferSource
    {
        public Task<IReadOnlyList<RawTransfer>> GetTransfersAsync(string wallet, DateTime? since, CancellationToken ct)
            => Task.FromResult((IReadOnlyList<RawTransfer>)Array.Empty<RawTransfer>());
    }

    public sealed class NullBalanceAnchorSource : IBalanceAnchorSource
    {
        public Task<decimal?> GetBalanceAsync(string wallet, CancellationToken ct) => Task.FromResult((decimal?)null);
    }

    /// <summary>
    /// Whitelist der Polymarket-System-Contract-Adressen (lowercased). Transfers zu/von diesen Adressen
    /// sind interne Trading-Bewegungen (bereits in der Activity), KEINE Ein-/Auszahlungen. Wird im
    /// Zielland aus Config/Docs befüllt/verifiziert (CTF-Adresse liegt bereits im Core; Exchange/
    /// NegRisk-Adapter/USDC ergänzen). Default leer → ohne Live-Transfers unkritisch.
    /// </summary>
    public sealed class AccountingSystemContracts
    {
        public HashSet<string> Addresses { get; } = new(StringComparer.OrdinalIgnoreCase);

        public AccountingSystemContracts(IEnumerable<string>? addresses = null)
        {
            if (addresses == null) return;
            foreach (var a in addresses)
                if (!string.IsNullOrWhiteSpace(a)) Addresses.Add(a.Trim().ToLowerInvariant());
        }
    }
}
