using NBitcoin;
using Newtonsoft.Json;
using Nostr.Client.Messages;
using NostrServices.Client;

namespace NostrServices.Services.EventHandlers;

public class RedisEventCache : IEventHandler
{
    private readonly RedisStore _redisStore;

    public RedisEventCache(RedisStore redisStore)
    {
        _redisStore = redisStore;
    }

    public async ValueTask HandleEvent(NostrEvent ev)
    {
        if (ev.Kind is NostrKind.Metadata)
        {
            var p = CompactProfile.FromNostrEvent(ev);
            if (p != default)
            {
                await _redisStore.StoreProfile(p);
            }
        }
        else if (ev.Kind is NostrKind.Contacts)
        {
            var relays = JsonConvert.DeserializeObject<Dictionary<string, ContactsRelays>>(ev.Content!);
            if (relays == default) return;

            var compact = relays.Select(a => new RelaySetting
            {
                Url = new Uri(a.Key.ToLower()),
                Read = a.Value.Read,
                Write = a.Value.Write
            });

            await _redisStore.StoreUserRelays(ev.Pubkey!, new()
            {
                Created = ev.CreatedAt!.Value.ToUnixTimestamp(),
                Relays = compact.ToList()
            });
        }
        else if (ev.Kind is NostrKind.RelayListMetadata)
        {
            var rTags = ev.Tags!.Where(a => a.TagIdentifier == "r").ToList();
            if (rTags.Count > 50) return;

            var compact = rTags.Select(a => new RelaySetting
            {
                Url = new Uri(a.AdditionalData[0].ToLower()),
                Read = a.AdditionalData.Length == 1 || a.AdditionalData[1] == "read",
                Write = a.AdditionalData.Length == 1 || a.AdditionalData[1] == "write"
            });

            await _redisStore.StoreUserRelays(ev.Pubkey!, new()
            {
                Created = ev.CreatedAt!.Value.ToUnixTimestamp(),
                Relays = compact.ToList()
            });
        }
        else
        {
            await _redisStore.StoreEvent(CompactEvent.FromNostrEvent(ev));
        }
    }

    class ContactsRelays
    {
        [JsonProperty("read")]
        public bool Read { get; init; }

        [JsonProperty("write")]
        public bool Write { get; init; }
    }
}
