using CoreLibrary.Events;
using CoreLibrary.Joueurs;
using CoreLibrary.Core;

namespace ConsoleApp
{
    /// <summary>
    /// Fournit un ensemble de méthodes écoutant les événements liés au déroulement de la partie.
    /// </summary>
    public static class Evenements
    {
        /// <summary>
        /// Ecoute l'événement en rapport avec la demande du nom d'un joueur.
        /// <param name="sender">La classe qui appelle l'événement; ici Partie.</param>
        /// <param name="e">L'instance de l'événement DemanderJoueurEventArgs créée par Partie.</param>
        /// <returns>Le nom du joueur.</returns>
        /// </summary>
        public static string? DemanderJoueur(Object? sender, DemanderJoueurEventArgs e)
        {
            Console.WriteLine($"Joueur {e.Numero}");
            Console.Write(">>> ");

            string? nom = Console.ReadLine();

            Console.WriteLine();

            return nom;
        }


        /// <summary>
        /// Ecoute l'événement en rapport avec le début de la partie.
        /// <param name="sender">La classe qui appelle l'événement; ici Partie.</param>
        /// <param name="e">L'instance de l'événement DebutPartieEventArgs créée par Partie.</param>
        /// </summary>
        public static void CommencerLaPartie(Object? sender, DebutPartieEventArgs e)
        {
            Utils.DessinerSeparateur();

            Console.WriteLine("La partie commence, bonne chance à tous !\n");
        }

        /// <summary>
        /// Ecoute l'événement en rapport avec un nouveau tour.
        /// <param name="sender">La classe qui appelle l'événement; ici Partie.</param>
        /// <param name="e">L'instance de l'événement NouveauTourEventArgs créée par Partie.</param>
        /// </summary>
        public static void NouveauTour(Object? sender, NouveauTourEventArgs e)
        {
            Utils.DessinerSeparateur();

            Console.WriteLine($"Tour {e.Tour} - {e.Joueur.Nom}\n");

            Utils.DessinerPlateau(e.Grille, e.Indicateurs);

            Console.WriteLine();

        }

        /// <summary>
        /// Ecoute l'événement en rapport avec la demande d'un jeton.
        /// <param name="sender">La classe qui appelle l'événement; ici Partie.</param>
        /// <param name="e">L'instance de l'événement DemanderJetonEventArgs créée par Partie.</param>
        /// <returns>Le jeton choisi par le joueur.</returns>
        /// </summary>
        public static Jeton? DemanderJeton(Object? sender, DemanderJetonEventArgs e)
        {
            Console.TreatControlCAsInput = true;
            Console.CursorVisible = false;

            bool aChoisi = false;
            int indice = 0;
            Couleur[] couleurs = (Couleur[])Enum.GetValues(typeof(Couleur));

            while (!aChoisi)
            {
                Utils.DessinerPion(couleurs[indice]);
                Console.Write("\b\b\b");

                switch (Console.ReadKey(true).Key)
                {
                    case ConsoleKey.Enter:
                        aChoisi = true;
                        break;

                    case ConsoleKey.LeftArrow:
                        --indice;
                        break;

                    case ConsoleKey.RightArrow:
                        ++indice;
                        break;

                    case ConsoleKey.Escape:
                        if (e.Indice != 0)
                        {
                            aChoisi = true;
                            indice = -2;
                        }
                        break;

                    default:
                        break;
                }

                if (indice == -1)
                    indice = couleurs.Length - 1;
                else if (indice == couleurs.Length)
                    indice = 0;
            }

            Console.TreatControlCAsInput = false;
            Console.CursorVisible = true;

            return indice != -2 ? new Jeton(couleurs[indice]) : null;
        }

        /// <summary>
        /// Ecoute l'événement en rapport avec l'ajout d'un jeton dans le code.
        /// <param name="sender">La classe qui appelle l'événement; ici Partie.</param>
        /// <param name="e">L'instance de l'événement AjouterJetonEventArgs créée par Partie.</param>
        /// </summary>
        public static void AjouterJeton(Object? sender, AjouterJetonEventArgs e)
        {
            Utils.DessinerPion(e.Jeton.Couleur);
        }

        /// <summary>
        /// Ecoute l'événement en rapport avec la suppression du dernier jeton ajouté dans le code.
        /// <param name="sender">La classe qui appelle l'événement; ici Partie.</param>
        /// <param name="e">L'instance de l'événement SupprimerDernierJetonEventArgs créée par Partie.</param>
        /// </summary>
        public static void SupprimerDernierJeton(Object? sender, SupprimerDernierJetonEventArgs e)
        {
            Console.Write("\b\b\b      \b\b\b\b\b\b");
        }

        /// <summary>
        /// Ecoute l'événement en rapport avec l'ajout d'un code dans le plateau.
        /// <param name="sender">La classe qui appelle l'événement; ici Partie.</param>
        /// <param name="e">L'instance de l'événement AjouterCodeEventArgs créée par Partie.</param>
        /// </summary>
        public static void AjouterCode(Object? sender, AjouterCodeEventArgs e)
        {
            Console.WriteLine();

            Utils.DessinerSeparateur();
        }

        /// <summary>
        /// Ecoute l'événement en rapport avec la fin de la partie.
        /// <param name="sender">La classe qui appelle l'événement; ici Partie.</param>
        /// <param name="e">L'instance de l'événement PartieTermineeEventArgs créée par Partie.</param>
        /// </summary>
        public static void PartieTerminee(Object? sender, PartieTermineeEventArgs e)
        {
            Joueur[] gagnants = e.Gagnants.ToArray();

            if (gagnants.Length > 1)
            {
                Console.WriteLine("C'est une égalité !");
            }
            else if (gagnants.Length == 1)
            {
                Console.WriteLine($"C'est une victoire de {gagnants[0].Nom}.");
            }
            else
            {
                Console.WriteLine("C'est une défaite des deux joueurs...");
            }
        }
    }
}
