using qtc_net_client_2.Services;
using QtCNETAPI.Events;
using QtCNETAPI.Models;
using QtCNETAPI.Services.ApiService;
using QtCNETAPI.Services.GatewayService;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace qtc_net_client_2.Forms
{
    public partial class ChatRoom : Form
    {
        IGatewayService _gatewayService;
        IApiService _apiService;
        AudioService AudioService = new();

        public ChatRoom(IGatewayService gatewayService, IApiService apiService)
        {
            _gatewayService = gatewayService;
            _apiService = apiService;
            InitializeComponent();
        }

        private void frmChat_Load(object sender, EventArgs e)
        {
            // subscribe to server message event
            _gatewayService.OnRoomMessageReceived += _gatewayService_OnServerMessageReceived;
            _gatewayService.OnRoomUserListReceived += _gatewayService_OnRoomUserListReceived;

            if (_gatewayService.CurrentRoom != null) { Text = $"QtC.NET Client - Chat Room - {_gatewayService.CurrentRoom.Name}"; lblRoomName.Text = _gatewayService.CurrentRoom.Name; }
            else if (_gatewayService.InLobby) { Text = $"QtC.NET Client - Chat Room - Lobby"; lblRoomName.Text = "Lobby"; }

            lvUserList.Clear();

            // always add current user to list i guess
            lvUserList.Items.Add(_apiService.CurrentUser.Username, _apiService.CurrentUser.Status);
        }

        private async void frmChat_FormClosing(object sender, FormClosingEventArgs e)
        {
            // unsubscribe from server message event
            _gatewayService.OnRoomMessageReceived -= _gatewayService_OnServerMessageReceived;
            _gatewayService.OnRoomUserListReceived -= _gatewayService_OnRoomUserListReceived;

            if (_gatewayService.CurrentRoom != null || _gatewayService.InLobby)
            {
                // leave any room user is in
                await _gatewayService.LeaveRoomAsync();
            }
        }

        private async void btnSend_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(rtxtChatbox.Text))
            {
                // construct message
                QtCNETAPI.Models.Message message = new() { Content = rtxtChatbox.Text };

                // send it and clear text box
                await _gatewayService.PostMessageAsync(message);
                rtxtChatbox.Clear();
                AudioService.PlaySoundEffect("sndSendClick");
            }
        }

        private void rtxtChatbox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                btnSend_Click(sender, e);
        }

        private async void lvUserList_DoubleClick(object sender, EventArgs e)
        {
            if (lvUserList.SelectedItems.Count > 0)
            {
                string? selectedUser = (string?)lvUserList.SelectedItems[lvUserList.SelectedItems.Count - 1].Text;

                if (selectedUser != null)
                {
                    // split from [ if it exists
                    if (selectedUser.Contains('[')) selectedUser = selectedUser.Split('[', options: StringSplitOptions.TrimEntries)[0];

                    // in this context, we need to find the main form to get the current user directory
                    Main? mainForm = (Main?)Application.OpenForms[0];
                    if (mainForm != null)
                    {
                        // get user info and open profile dialog
                        var user = mainForm.UserDirectory.FirstOrDefault(e => e.Username == selectedUser);
                        var res = await _apiService.GetUserInformationAsync(user!.Id);
                        var pfpRes = await _apiService.GetUserProfilePic(user!.Id);

                        if (res.Data != null && res.Success)
                        {
                            Profile frmProfile = new Profile(res.Data, pfpRes, mainForm.Contacts, _apiService, _gatewayService);
                            frmProfile.Show();
                        }
                    }
                }
            }
        }

        private void _gatewayService_OnServerMessageReceived(object? sender, EventArgs e)
        {
            var msgEventArgs = (ServerMessageEventArgs)e;

            AddMessage(msgEventArgs.Message);
            if (!msgEventArgs.Message.Contains(_apiService.CurrentUser.Username)) AudioService.PlaySoundEffect("sndMessage");
        }

        private void _gatewayService_OnRoomUserListReceived(object? sender, EventArgs e)
        {
            var args = (RoomListEventArgs)e;

            if (!IsHandleCreated) return;

            lvUserList.BeginInvoke(lvUserList.Clear);
            foreach (var user in args.UserList)
            {
                lvUserList.BeginInvoke(delegate () { lvUserList.Items.Add(user.Username, user.Status); });
            }
        }

        private void AddMessage(string message)
        {
            if (InvokeRequired)
                Invoke(delegate { rtxtChat.AppendText(message + Environment.NewLine); });
            else rtxtChat.AppendText(message + Environment.NewLine);
        }
    }
}
