using Microsoft.AspNetCore.SignalR.Client;
using QtCNETAPI.Dtos.User;
using QtCNETAPI.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace QtCNETAPI.Services.GatewayService
{
    public interface IGatewayService
    {
        // VARIABLES

        /// <summary>
        /// The Current Room The Current User Is In
        /// </summary>
        public Room? CurrentRoom { get; }

        /// <summary>
        /// The Current Connection To The Gateway
        /// </summary>
        public HubConnection? HubConnection { get; }
        /// <summary>
        /// The URI in which the client will try to use for SignalR requests.
        /// </summary>
        public string? GWUri { get; }

        // FUNCTIONS

        /// <summary>
        /// The Function Used To Connect To The Gateway Server Asynchronously
        /// </summary>
        /// <returns></returns>
        public Task StartAsync();

        /// <summary>
        /// Stops The Connection To The Gateway Server
        /// </summary>
        /// <returns></returns>
        public Task StopAsync();

        /// <summary>
        /// Disposes Of The Gateway Connection And Clears Other Variables
        /// </summary>
        /// <returns></returns>
        public Task DisposeAsync();

        /// <summary>
        /// Joins The Current User To A Room On The Server
        /// </summary>
        /// <param name="room">Room To Join</param>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException">Thrown if the function is called before the connection is established.</exception>
        public Task JoinRoomAsync(Room? room = null);

        /// <summary>
        /// Leaves The Current Room The Current User Is In
        /// </summary>
        /// <returns></returns>
        public Task LeaveRoomAsync();

        /// <summary>
        /// Posts A Message To Whatever Room The User Is In
        /// </summary>
        /// <param name="message">Message To Post</param>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException">Thrown if the function is called before the connection is established.</exception>
        public Task PostMessageAsync(Message message);

        /// <summary>
        /// Sends A Direct Message To The Specified User
        /// </summary>
        /// <param name="user">The User You Wish To DM</param>
        /// <param name="currentUser">Yourself</param>
        /// <param name="message"></param>
        /// <returns></returns>
        public Task SendDirectMessageAsync(UserInformationDto user, Message message);

        /// <summary>
        /// Updates The Status For The Current User
        /// </summary>
        /// <param name="status">The Status You Want To Set On The Current User</param>
        /// <returns></returns>
        public Task UpdateStatus(int status);

        // EVENTS

        /// <summary>
        /// When A Room Message Is Received, This Event Fires
        /// </summary>
        public event EventHandler OnRoomMessageReceived;

        /// <summary>
        /// Fires When The User List For A Room Is Received
        /// </summary>
        public event EventHandler OnRoomUserListReceived;

        /// <summary>
        /// Fires When The Room The User Is In Gets Deleted By An Admin
        /// </summary>
        public event EventHandler OnRoomDeleted;

        /// <summary>
        /// Fires When A Guest User Joins Your Room
        /// </summary>
        public event EventHandler OnGuestUserJoin;

        /// <summary>
        /// When A Client Function/Event Is Received, This Event Fires
        /// </summary>
        public event EventHandler OnClientFunctionReceived;

        /// <summary>
        /// When The Client Received A DM, This Event Fires
        /// </summary>
        public event EventHandler OnDirectMessageReceived;

        /// <summary>
        /// Fires When The Client Receives The Request To Refresh Its User List
        /// </summary>
        public event EventHandler OnRefreshUserListsReceived;

        /// <summary>
        /// Fires When The Client Receives The Request To Refresh Its Room List
        /// </summary>
        public event EventHandler OnRefreshRoomListReceived;

        /// <summary>
        /// Fires When The Client Receives The Request To Refresh Its Contacts List
        /// </summary>
        public event EventHandler OnRefreshContactsListReceived;

        /// <summary>
        /// When The Server Config Is Received, This Event Fires
        /// </summary>
        public event EventHandler OnServerConfigReceived;

        /// <summary>
        /// When The Connection To The Gateway Is Lost, This Event Fires
        /// </summary>
        public event EventHandler OnServerDisconnect;

        /// <summary>
        /// When The Connection Attempts To Reconnect, This Event Fires
        /// </summary>
        public event EventHandler OnServerReconnecting;

        /// <summary>
        /// When the Connection Reconnects, This Event Fires
        /// </summary>
        public event EventHandler OnServerReconnected;

        /// <summary>
        /// Fires When The Current User Is Signed Out By The Server
        /// </summary>
        public event EventHandler OnUserForceLogout;
    }
}
