using FiestaBot.Configuration;
using FiestaBot.Enums;
using FiestaBot.Instances.Networking;
using FiestaBot.Manager.ClientPacket;
using FiestaBot.Manager.Game;
using FiestaBot.Manager.Networking;
using FiestaBot.Utilities;
using FiestaBot.Zone.Game;

namespace FiestaBot.Manager.Handlers
{
    internal class Manager03Handler
    {
        [ManagerPacketHandler(3, 20)]
        public static void CharacterList(ManagerClient Socket, Packet Packet)
        {
            Socket.InCharSelect = true;
            
            Packet.ReadUShort(out ushort ZoneKey);
            Socket.ZoneKey = ZoneKey;
            Packet.ReadByte(out byte totalCharacters);
            if (totalCharacters > 0)
            {
                Logger.Log(LogType.Character, "You have {0} characters available:", totalCharacters);
                for (int i = 0; i < totalCharacters; i++)
                {
                    //basic info
                    Packet.ReadInt(out int charID);
                    Packet.ReadString(out string charName, 16);
                    Packet.ReadUShort(out ushort charLevel);
                    Packet.ReadByte(out byte charSlot);
                    Socket.InUseCharSlots.Add(charSlot);
                    Packet.ReadString(out string charMapIndex, 12);
                    Packet.ReadByte(out byte Unk00);
                    Packet.ReadInt(out int Unwanted00);
                    //character looks
                    Packet.ReadByte(out byte charLookJobGender);
                    Packet.ReadByte(out byte charLookHair);
                    Packet.ReadByte(out byte charLookHairColor);
                    Packet.ReadByte(out byte charLookFace);
                    //character equipment
                    Packet.ReadUShort(out ushort charEqHelmet);
                    Packet.ReadUShort(out ushort charEqWeapon);
                    Packet.ReadUShort(out ushort charEqArmor);
                    Packet.ReadUShort(out ushort charEqShield);
                    Packet.ReadUShort(out ushort charEqPants);
                    Packet.ReadUShort(out ushort charEqBoots);
                    Packet.ReadUShort(out ushort charEqCosmeticBoots);
                    Packet.ReadUShort(out ushort charEqCosmeticPants);
                    Packet.ReadUShort(out ushort charEqCosmeticArmor);
                    for (int x = 0; x < 6; x++) { Packet.ReadByte(out byte Unk01); }
                    Packet.ReadUShort(out ushort charEqCosmeticGlasses);
                    Packet.ReadUShort(out ushort charEqCosmeticHelmet);
                    for (int x = 0; x < 2; x++) { Packet.ReadByte(out byte Unk02); }
                    Packet.ReadUShort(out ushort charEqCosmeticWeapon);
                    Packet.ReadUShort(out ushort charEqCosmeticBack);
                    for (int x = 0; x < 2; x++) { Packet.ReadByte(out byte Unk03); }
                    Packet.ReadUShort(out ushort charEqComseticTail);
                    Packet.ReadUShort(out ushort charEqCosmeticPet);
                    //refinement? whatever that is supposed to be
                    for (int x = 0; x < 3; x++) { Packet.ReadByte(out byte Unk04); }
                    //continue normal data
                    for (int x = 0; x < 4; x++) { Packet.ReadByte(out byte Unk05); }
                    Packet.ReadString(out string charMapName, 12); //???
                    Packet.ReadInt(out int charPosX);
                    Packet.ReadInt(out int charPosY);
                    Packet.ReadInt(out int Unk06);
                    Packet.ReadByte(out byte Unk07);
                    Packet.ReadInt(out int Unk08);
                    Packet.ReadByte(out byte Unk09);

                    byte genderID = (byte)((charLookJobGender >> 7) & 0x01);
                    byte classID = (byte)((charLookJobGender >> 2) & 0x1F);

                    Position Position = new Position
                    {
                        MapInx = charMapIndex,
                        X = charPosX,
                        Y = charPosY,
                        Z = 90
                    };

                    Style Style = new Style
                    {
                        Gender = (Gender)genderID,
                        HairID = charLookHair,
                        HairColorID = charLookHairColor,
                        FaceID = charLookFace
                    };

                    Equipment Equipment = new Equipment
                    {
                        Helmet = charEqHelmet,
                        Armor = charEqArmor,
                        Pants = charEqPants,
                        Boots = charEqBoots,
                        Weapon = charEqWeapon,
                        Shield = charEqShield,
                        CosmeticHelmet = charEqCosmeticHelmet,
                        CosmeticArmor = charEqCosmeticArmor,
                        CosmeticPants = charEqCosmeticPants,
                        CosmeticBoots = charEqCosmeticBoots,
                        CosmeticGlasses = charEqCosmeticGlasses,
                        CosmeticBack = charEqCosmeticBack,
                        CosmeticTail = charEqComseticTail,
                        CosmeticPet = charEqCosmeticPet,
                        CosmeticWeaponSkin = charEqCosmeticWeapon
                    };

                    Character Character = new Character
                    {
                        Slot = charSlot,
                        ID = charID,
                        Name = charName,
                        Class = (Class)classID,
                        Level = charLevel,
                        AdminLevel = 0,
                        Style = Style,
                        Position = Position,
                        Equipment = Equipment
                    };

                    Socket.AllCharacters.Add(Character);

                    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}", charID, charName, charLevel, charSlot, SHNSearch.FindNameByInx(FindType.MapInfo, charMapIndex), (Gender)genderID, (Class)classID, SHNSearch.FindNameByID(FindType.HairInfo, charLookHair), SHNSearch.FindNameByID(FindType.HairColorInfo, charLookHairColor), SHNSearch.FindNameByID(FindType.FaceInfo, charLookFace), charPosX, charPosY);
                }
                if (Program.Config.AutoSelectCharacter) { ManagerPacket.SendCharacterSelect(Socket, Program.Config.AutoSelectCharacterSlot); }
                else { Logger.Log(LogType.Character, "> Pick a character with selectchar [ID] OR type createchar to start the creation of a new character"); }
            }
            else { Logger.Log(LogType.Character, "> You currently have no characters available, type createchar to start the creation of a charater"); }
            
            Packet.Dispose();

            if(Program.Config.AutoSelectCharacter)
            {
                ManagerPacket.SendCharacterSelect(Socket, Program.Config.AutoSelectCharacterSlot);
            }
            else { Socket.InCharSelect = true; }
        }

        [ManagerPacketHandler(3, 21)]
        public static void InvalidworldTransfer(ManagerClient Socket, Packet Packet)
        {
            Logger.Log(LogType.World, "World transfer failed: invalid transferkey specified");
            Packet.Dispose();
            Socket.Disconnect();
        }
    }
}
