﻿using AsmodeeDigital.PlayReal.Plugin.Domain.GameState;
using AsmodeeDigital.PlayReal.Plugin.Domain.Message;
using AsmodeeDigital.PlayReal.Plugin.Domain.Players;
using com.daysofwonder.async;

namespace AsmodeeDigital.PlayReal.Plugin.Logic.Gameplay
{
    /// <summary>
    /// Distant gameplay logic contract
    /// </summary>
    /// <typeparam name="T">Game state type</typeparam>
    /// <typeparam name="U">Message type in multicast</typeparam>
    public interface IDistantGameplayLogic<T,U> : IGameplayLogic<T>
        where T : GameStateBase
        where U : IMessage
    {
        /// <summary>
        /// Distant gameplay component
        /// </summary>
        DistantGameplayComponent<T,U> DistantGameplayComponent { get; set; }

        /// <summary>
        /// Called when a local player quit a distant game
        /// </summary>
        void SetGameOver();

        /// <summary>
        /// Called when a multicast message is receive
        /// </summary>
        /// <param name="message">Message</param>
        void MessageReceived(U message);

        /// <summary>
        /// Fresh status report of a game coming from the DoW server
        /// </summary>
        /// <param name="statusReport"></param>
        void RefreshGameStatus(StatusReport statusReport);

        /// <summary>
        /// A player presence has been updated
        /// </summary>
        void PlayerPresenceUpdated();

        /// <summary>
        /// The game has been aborted
        /// </summary>
        /// <param name="gameAbortedRequest">Score an player ranking of the game</param>
        void GameAborted(GameAbortedRequest gameAbortedRequest);

        /// <summary>
        /// A local player quit the game
        /// </summary>
        /// <param name="playerSeat">Player seat</param>
        /// <param name="playerStatus">Status of the player</param>
        void LocalPlayerQuitGame(IPlayerSeat playerSeat, PlayerTimeoutRequest.PlayerStatus playerStatus);

        /// <summary>
        /// A distant player quit the game
        /// </summary>
        /// <param name="playerSeat">Player seat</param>
        /// <param name="status">Status of the player</param>
        void OtherPlayerQuitGame(IPlayerSeat playerSeat, PlayerTimeoutRequest.PlayerStatus status);
        
        /// <summary>
        /// A distant player join the game
        /// </summary>
        /// <param name="distantPlayerSeat">Distant player seat</param>
        void PlayerJoinGame(DistantPlayerSeat distantPlayerSeat);
    }
}
