using System.Text.Json;

namespace SharpChat.EventStorage {
    public class VirtualEventStorage : EventStorage {
        private readonly Dictionary<long, StoredEventInfo> Events = [];

        public void AddEvent(
            long id,
            string type,
            string channelName,
            string senderId,
            string senderName,
            ColourInheritable senderColour,
            int senderRank,
            string senderNick,
            UserPermissions senderPerms,
            object? data = null,
            StoredEventFlags flags = StoredEventFlags.None
        ) {
            Events.Add(
                id,
                new(
                    id,
                    type,
                    long.TryParse(senderId, out long senderId64) && senderId64 > 0 
                        ? new User(
                            senderId,
                            senderName,
                            senderColour,
                            senderRank,
                            senderPerms,
                            senderNick
                        )
                        : null,
                    DateTimeOffset.Now,
                    null,
                    channelName,
                    JsonDocument.Parse(data == null ? "{}" : JsonSerializer.Serialize(data)),
                    flags
                )
            );
        }

        public StoredEventInfo? GetEvent(long seqId) {
            return Events.TryGetValue(seqId, out StoredEventInfo? evt) ? evt : null;
        }

        public void RemoveEvent(StoredEventInfo evt) {
            ArgumentNullException.ThrowIfNull(evt);
            Events.Remove(evt.Id);
        }

        public IEnumerable<StoredEventInfo> GetChannelEventLog(string channelName, int amount = 20, int offset = 0) {
            IEnumerable<StoredEventInfo> subset = Events.Values.Where(ev => ev.ChannelName == channelName);

            int start = subset.Count() - offset - amount;
            if(start < 0) {
                amount += start;
                start = 0;
            }

            return [.. subset.Skip(start).Take(amount)];
        }
    }
}