// Copyright (c) 2023 Timothy Schenk. Subject to the GNU AGPL Version 3 License.

using System.Buffers.Binary;
using System.Text;
using Wonderking.Packets.Outgoing.Data;

namespace Wonderking.Packets.Outgoing;

[PacketId(OperationCode.CharacterCreationResponse)]
public class CharacterCreationResponsePacket : IPacket
{
    public required CharacterData Character { get; set; }
    public required int Slot { get; set; }
    public required bool isDuplicate { get; set; }

    public void Deserialize(byte[] data)
    {
        throw new NotSupportedException();
    }

    public byte[] Serialize()
    {
        Span<byte> data = stackalloc byte[1 + 132];
        data[0] = isDuplicate ? (byte)1 : (byte)0;

        // Character Data
        BinaryPrimitives.WriteInt32LittleEndian(data.Slice(1, 4), Slot);
        Encoding.ASCII.GetBytes(Character.Name, data.Slice(5, 20));

        // Job Data
        data[25] = Character.Job.FirstJob;
        data[26] = Character.Job.SecondJob;
        data[27] = Character.Job.ThirdJob;
        data[28] = Character.Job.FourthJob;

        data[29] = (byte)Character.Gender;
        BinaryPrimitives.WriteUInt16LittleEndian(data.Slice(30, 2), Character.Level);
        data[32] = (byte)Character.Experience;

        // Stats
        BinaryPrimitives.WriteInt16LittleEndian(data.Slice(33, 2), Character.Stats.Strength);
        BinaryPrimitives.WriteInt16LittleEndian(data.Slice(35, 2), Character.Stats.Dexterity);
        BinaryPrimitives.WriteInt16LittleEndian(data.Slice(37, 2), Character.Stats.Intelligence);
        BinaryPrimitives.WriteInt16LittleEndian(data.Slice(39, 2), Character.Stats.Vitality);
        BinaryPrimitives.WriteInt16LittleEndian(data.Slice(41, 2), Character.Stats.Luck);
        BinaryPrimitives.WriteInt16LittleEndian(data.Slice(43, 2), Character.Stats.Wisdom);

        BinaryPrimitives.WriteInt32LittleEndian(data.Slice(45, 4), Character.Health);
        BinaryPrimitives.WriteInt32LittleEndian(data.Slice(49, 4), Character.Mana);

        for (var i = 0; i < 20; i++)
        {
            // Equipped Items
            BinaryPrimitives.WriteUInt16LittleEndian(data.Slice(53 + i * 2, 2),
                Character.EquippedItems.Length > i ? Character.EquippedItems[i] : (ushort)0);

            // Equipped Cash Items
            BinaryPrimitives.WriteUInt16LittleEndian(data.Slice(93 + i * 2, 2),
                Character.EquippedCashItems.Length > i ? Character.EquippedCashItems[i] : (ushort)0);
        }

        return data.ToArray();
    }
}