using Nostr.Client.Messages;
using Nostr.Client.Requests;
using NostrRelay;
using NostrServices.Services.EventHandlers;

namespace NostrServices.Services;

public class CacheRelay : INostrRelay, IDisposable
{
    private readonly ILogger<CacheRelay> _logger;
    private readonly IEnumerable<IEventHandler> _handlers;

    public CacheRelay(ILogger<CacheRelay> logger, IEnumerable<IEventHandler> handlers)
    {
        _logger = logger;
        _handlers = handlers;
    }

    public ValueTask<bool> AcceptConnection(NostrClientContext context)
    {
        _logger.LogInformation("New connection {ip} {ua}", context.Ip, context.UserAgent);
        return ValueTask.FromResult(true);
    }

    public async IAsyncEnumerable<NostrEvent> HandleRequest(NostrClientContext context, NostrRequest req)
    {
        //no results yet
        yield break;
    }

    public async ValueTask<HandleEventResponse> HandleEvent(NostrClientContext context, NostrEvent ev)
    {
        if (RelayListener.AcceptedKinds.Contains(ev.Kind))
        {
            foreach (var eventHandler in _handlers)
            {
                try
                {
                    await eventHandler.HandleEvent(ev);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Handler failed {msg}", ex.Message);
                }
            }

            return new(true, null);
        }

        return new(false, "blocked: kind not accepted");
    }

    public void Dispose()
    {
        // TODO release managed resources here
    }
}
