using SharpChat.EventStorage;
using System;
using System.Collections.Generic;
using System.Text;

namespace SharpChat.Packet
{
    public class ContextMessagePacket(StoredEventInfo evt, bool notify = false) : ServerPacket {
        public StoredEventInfo Event { get; private set; } = evt ?? throw new ArgumentNullException(nameof(evt));

        private const string V1_CHATBOT = "-1\tChatBot\tinherit\t\t";

        public override IEnumerable<string> Pack() {
            bool isAction = Event.Flags.HasFlag(StoredEventFlags.Action);
            bool isBroadcast = Event.Flags.HasFlag(StoredEventFlags.Broadcast);
            bool isPrivate = Event.Flags.HasFlag(StoredEventFlags.Private);

            StringBuilder sb = new();

            sb.Append('7');
            sb.Append('\t');
            sb.Append('1');
            sb.Append('\t');
            sb.Append(Event.Created.ToUnixTimeSeconds());
            sb.Append('\t');

            switch(Event.Type) {
                case "msg:add":
                case "SharpChat.Events.ChatMessage":
                    if(isBroadcast) {
                        sb.Append(V1_CHATBOT);
                        sb.Append("0\fsay\f");
                    } else {
                        sb.Append(Event.Sender.Pack());
                        sb.Append('\t');
                    }

                    if(isAction)
                        sb.Append("<i>");

                    sb.Append(
                        Event.Data.RootElement.GetProperty("text").GetString()
                            .Replace("<", "&lt;")
                            .Replace(">", "&gt;")
                            .Replace("\n", " <br/> ")
                            .Replace("\t", "    ")
                    );

                    if(isAction)
                        sb.Append("</i>");
                    break;

                case "user:connect":
                case "SharpChat.Events.UserConnectEvent":
                    sb.Append(V1_CHATBOT);
                    sb.Append("0\fjoin\f");
                    sb.Append(Event.Sender.LegacyName);
                    break;

                case "chan:join":
                case "SharpChat.Events.UserChannelJoinEvent":
                    sb.Append(V1_CHATBOT);
                    sb.Append("0\fjchan\f");
                    sb.Append(Event.Sender.LegacyName);
                    break;

                case "chan:leave":
                case "SharpChat.Events.UserChannelLeaveEvent":
                    sb.Append(V1_CHATBOT);
                    sb.Append("0\flchan\f");
                    sb.Append(Event.Sender.LegacyName);
                    break;

                case "user:disconnect":
                case "SharpChat.Events.UserDisconnectEvent":
                    sb.Append(V1_CHATBOT);
                    sb.Append("0\f");

                    switch((UserDisconnectReason)Event.Data.RootElement.GetProperty("reason").GetByte()) {
                        case UserDisconnectReason.Flood:
                            sb.Append("flood");
                            break;
                        case UserDisconnectReason.Kicked:
                            sb.Append("kick");
                            break;
                        case UserDisconnectReason.TimeOut:
                            sb.Append("timeout");
                            break;
                        case UserDisconnectReason.Leave:
                        default:
                            sb.Append("leave");
                            break;
                    }

                    sb.Append('\f');
                    sb.Append(Event.Sender.LegacyName);
                    break;
            }

            sb.Append('\t');
            sb.Append(Event.Id < 1 ? SequenceId : Event.Id);
            sb.Append('\t');
            sb.Append(notify ? '1' : '0');
            sb.AppendFormat(
                "\t1{0}0{1}{2}",
                isAction ? '1' : '0',
                isAction ? '0' : '1',
                isPrivate ? '1' : '0'
            );

            yield return sb.ToString();
        }
    }
}