using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FiestaBot.Configuration;
using FiestaBot.Instances.Networking;
using FiestaBot.Login.ClientPacket;
using FiestaBot.Login.Networking;
using FiestaBot.Manager.ClientPacket;
using FiestaBot.Manager.Game;
using FiestaBot.Manager.Networking;
using FiestaBot.Zone.ClientPacket;
using FiestaBot.Zone.Game;
using FiestaBot.Zone.Networking;

namespace FiestaBot.Utilities
{
    internal class Commands
    {
        public static int MoveNum = 100;

        public static void HandleCommand(string Command)
        {
            LoginClient LoginClient = Program.LoginClient;
            ManagerClient ManagerClient = Program.ManagerClient;
            ZoneClient ZoneClient = Program.ZoneClient;

            string[] CommandSplit = Command.Split(' ');

            if (CommandSplit[0] == "selectworld")
            {
                if (LoginClient.InWorldSelect && !Program.Config.AutoSelectWorld)
                {
                    byte worldID = byte.Parse(CommandSplit[1]);
                    if (worldID > Program.AvailableWorlds) { Logger.Log(LogType.Login, "Please select a valid world ID"); }
                    else
                    {
                        LoginPacket.SendWorldSelect(LoginClient, worldID);
                    }
                }
                else { Logger.Log(LogType.Login, "You have to be in world select to use this command"); }
            }
            else if (CommandSplit[0] == "listchars")
            {
                Logger.Log(LogType.Character, "You have {0} characters available:", ManagerClient.AllCharacters.Count);
                foreach (Character x in ManagerClient.AllCharacters) { Logger.Log(LogType.Character, "ID: {0} | Name: {1} | Level: {2} | Slot: {3} | Map: {4} | Gender: {5} | Class: {6} | Hair: {7} | Color: {8} | Face: {9} | PosX: {10} | PosY: {11}", x.ID, x.Name, x.Level, x.Slot, SHNSearch.FindNameByInx(FindType.MapInfo, x.Position.MapInx), x.Style.Gender, x.Class, SHNSearch.FindNameByID(FindType.HairInfo, x.Style.HairID), SHNSearch.FindNameByID(FindType.HairColorInfo, x.Style.HairColorID), SHNSearch.FindNameByID(FindType.FaceInfo, x.Style.FaceID), x.Position.X, x.Position.Y); }
            }
            else if (CommandSplit[0] == "createchar")
            {
                if (ManagerClient.InCharSelect)
                {
                    if (ManagerClient.InUseCharSlots.Count == 4) { Logger.Log(LogType.World, "All character slots are in use, please delete a character first with delchar [ID]"); }
                    else
                    {
                        Logger.Log(LogType.Character, "== Character Creation ==");
                        Logger.Log(LogType.Character, "> Choose your class (Fighter: 0 | Cleric: 1 | Archer: 2 | Mage: 3 | Trickster: 4)");
                        byte charClass = byte.Parse(Console.ReadLine());

                        Logger.Log(LogType.Character, "> Choose a gender (Male: 1 | Female: 0)");
                        byte charGender = byte.Parse(Console.ReadLine());

                        Logger.Log(LogType.Character, "> Choose a name (maximum 16 characters)");
                        string charName = Console.ReadLine();

                        Logger.Log(LogType.Character, "> Hair/Face soonTM (using standards)");

                        //if (charClass > 5 || charClass < 0) { Console.WriteLine("Invalid class entered, please try again"); }
                        //else if (charGender > 2) { Console.WriteLine("Invalid gender entered, please try again"); }
                        if (charName.Length == 0 || charName.Length > 16 || !charName.All(char.IsLetterOrDigit)) { Logger.Log(LogType.Character, "Invalid name entered, please try again"); }
                        else
                        {
                            switch (charClass)
                            {
                                case 0:
                                    charClass = 1;
                                    break;
                                case 1:
                                    charClass = 6;
                                    break;
                                case 2:
                                    charClass = 11;
                                    break;
                                case 3:
                                    charClass = 16;
                                    break;
                                case 4:
                                    charClass = 21;
                                    break;
                            }

                            byte Slot = 0;
                            bool slotFound = false;

                            while (!slotFound)
                            {
                                if (ManagerClient.InUseCharSlots.Contains(Slot)) Slot++;
                                else slotFound = true;
                            }

                            ManagerPacket.SendCharacterCreate(ManagerClient, Slot, charName, charClass, charGender);
                        }
                    }
                }
                else { Logger.Log(LogType.World, "You have to be in character select to use that command"); }
            }
            else if (CommandSplit[0] == "deletechar")
            {
                if (ManagerClient.InCharSelect)
                {
                    byte Slot = byte.Parse(CommandSplit[1]);

                    ManagerPacket.SendCharacterDelete(ManagerClient, Slot);
                }
                else { Logger.Log(LogType.World, "You have to be in character select to use that command"); }
            }
            else if (CommandSplit[0] == "selectchar")
            {
                if (ManagerClient.InCharSelect && !Program.Config.AutoSelectCharacter)
                {
                    byte Slot = byte.Parse(CommandSplit[1]);

                    ManagerPacket.SendCharacterSelect(ManagerClient, Slot);
                }
                else { Logger.Log(LogType.World, "You have to be in character select to use that command"); }
            }
            else if (CommandSplit[0] == "chat")
            {
                if (CommandSplit[1] == "normal")
                {
                    Chat.Normal(ZoneClient, Command.Split(new string[] { "chat normal " }, StringSplitOptions.None)[1]);
                }
                else if(CommandSplit[1] == "party")
                {
                    Chat.Party(ManagerClient, Command.Split(new string[] { "chat party " }, StringSplitOptions.None)[1]);
                }
            }
            else if (CommandSplit[0] == "move")
            {
                if (CommandSplit[1] == "n")
                {
                    int NewX = ManagerClient.Character.Position.X;
                    int NewY = ManagerClient.Character.Position.Y + MoveNum;

                    ZonePacket.SendRun(ZoneClient, NewX, NewY);
                }
                else if (CommandSplit[1] == "s")
                {
                    int NewX = ManagerClient.Character.Position.X;
                    int NewY = ManagerClient.Character.Position.Y - MoveNum;

                    ZonePacket.SendRun(ZoneClient, NewX, NewY);
                }
                else if (CommandSplit[1] == "w")
                {
                    int NewX = ManagerClient.Character.Position.X + MoveNum;
                    int NewY = ManagerClient.Character.Position.Y;

                    ZonePacket.SendRun(ZoneClient, NewX, NewY);
                }
                else if (CommandSplit[1] == "e")
                {
                    int NewX = ManagerClient.Character.Position.X - MoveNum;
                    int NewY = ManagerClient.Character.Position.Y;

                    ZonePacket.SendRun(ZoneClient, NewX, NewY);
                }
            }
            else if (CommandSplit[0] == "party")
            {
                if(CommandSplit[1] == "inv")
                {
                    string ToInvite = CommandSplit[2];

                    ManagerPacket.SendPartyInvite(ManagerClient, ToInvite);
                }
            }
            else if(CommandSplit[0] == "trade")
            {
                if(CommandSplit[1] == "req")
                {
                    string Receiver = CommandSplit[2];

                    ZonePacket.SendTradeRequest(ZoneClient, Receiver);
                }
            }
        }
    }
}

