using qtcnet_client.Controls;
using qtcnet_client.Factories;
using QtCNETAPI.Dtos.User;
using QtCNETAPI.Events;
using QtCNETAPI.Models;
using QtCNETAPI.Services.ApiService;
using QtCNETAPI.Services.GatewayService;
using System.ComponentModel;
using System.Reflection.Metadata.Ecma335;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace qtcnet_client.Forms
{
    public partial class ChatRoomForm : Form
    {
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public string RoomId { get; set; } = string.Empty;
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string RoomName { get; set; } = "Room";
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public Dictionary<string, Bitmap> UserProfileImages { get; set; }  = [];
        public string SentMessage { get; private set; } = string.Empty;

        public event EventHandler? OnSend;
        public event EventHandler? OnClose;

        private readonly IGatewayService _gatewayService;
        private readonly IApiService _apiService;
        private readonly ImageFactory _imgFactory;

        public ChatRoomForm(IGatewayService gatewayService, IApiService apiService, ImageFactory imageFactory)
        {
            _gatewayService = gatewayService;
            _apiService = apiService;
            _imgFactory = imageFactory;
            InitializeComponent();
        }

        private void ChatRoomForm_Load(object sender, EventArgs e)
        {
            Text = $"QtC.NET Chat Room - {RoomName}";
            lblRoomName.Text = RoomName;
        }

        private void rtxtChatbox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                if (ValidateChatBox())
                {
                    SentMessage = rtxtChatbox.Text;
                    OnSend?.Invoke(this, EventArgs.Empty);
                    rtxtChatbox.Clear();
                }
            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            if (ValidateChatBox())
            {
                SentMessage = rtxtChatbox.Text;
                OnSend?.Invoke(this, EventArgs.Empty);
                rtxtChatbox.Clear();
            }
        }

        private void ChatRoomForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            OnClose?.Invoke(this, EventArgs.Empty);
        }

        public void AddUsersToRoomList(List<User> users)
        {
            if(lvUsers.InvokeRequired)
            {
                lvUsers.Invoke(() =>
                {
                    lvUsers.SuspendLayout();

                    lvUsers.Items.Clear();

                    List<ListViewItem> lvis = [];
                    foreach (User user in users)
                    {
                        lvis.Add(new ListViewItem
                        {
                            Tag = user.Id,
                            Text = user.Username,
                            ImageIndex = user.Status
                        });
                    }

                    lvUsers.Items.AddRange([.. lvis.DistinctBy(u => u.Tag)]);

                    lvUsers.ResumeLayout(true);
                });
            }
            else
            {
                lvUsers.SuspendLayout();

                lvUsers.Items.Clear();

                List<ListViewItem> lvis = [];
                foreach (User user in users)
                {
                    lvis.Add(new ListViewItem
                    {
                        Tag = user.Id,
                        Text = user.Username,
                        ImageIndex = user.Status
                    });
                }

                lvUsers.Items.AddRange([.. lvis.DistinctBy(u => u.Tag)]);

                lvUsers.ResumeLayout(true);
            }
        }

        public void AddUserToRoomList(UserInformationDto user)
        {
            ListViewItem lvi = new()
            {
                Tag = user.Id,
                Text = user.Username,
                ImageIndex = user.Status
            };

            lvUsers.Items.Add(lvi);
        }

        public async Task LoadProfileImage(MessageControl ctrl, User user)
        {
            _ = Task.Run(async () =>
            {
                var img = await AddUserProfileImageToDictionary(user);

                if (img == null || ctrl.IsDisposed)
                    return;

                if (ctrl.InvokeRequired)
                    ctrl.Invoke(() =>
                    {
                        ctrl.ProfileImage = img;
                        ctrl.ReloadProfileImage();
                    });
                else
                {
                    ctrl.ProfileImage = img;
                    ctrl.ReloadProfileImage();
                }
            });
        }

        private async Task<Bitmap?> AddUserProfileImageToDictionary(User user)
        {
            if(UserProfileImages.TryGetValue(user.Id, out var image))
                return image;
            else
            {
                var img = _imgFactory.GetAndCreateProfileImage(user.Id, -1, user.ActiveProfileCosmetic);
                UserProfileImages.Add(user.Id, img);
                return img;
            }
        }

        public void AddMessage(MessageControl messageCtrl)
        {
            messageCtrl.Width = flpMessages.ClientSize.Width - 10;
            messageCtrl.Margin = new Padding(0, 0, 0, 6);

            if(flpMessages.InvokeRequired)
            {
                Invoke(() =>
                {
                    flpMessages.Controls.Add(messageCtrl);
                    flpMessages.ScrollControlIntoView(messageCtrl);
                });
            } else
            {
                flpMessages.Controls.Add(messageCtrl);
                flpMessages.ScrollControlIntoView(messageCtrl);
            }
        }

        private bool ValidateChatBox()
        {
            return !string.IsNullOrWhiteSpace(rtxtChatbox.Text) || !string.IsNullOrEmpty(rtxtChatbox.Text);
        }
    }
}
