using System.IO;
using System.Data.Entity;
using PSO2SERVER.Models;
using PSO2SERVER.Protocol.Packets;
using PSO2SERVER.Database;
using System.Linq;
using static PSO2SERVER.Models.CharacterStruct;
using System.Security.Cryptography.Pkcs;
using System.Runtime.InteropServices;

namespace PSO2SERVER.Protocol.Handlers
{
    [PacketHandlerAttr(0x11, 0x05)]
    public class CharacterCreate : PacketHandler
    {
        #region implemented abstract members of PacketHandler

        public uint CharacterID { get; set; }
        public uint AccountID { get; set; }
        public uint Unk1 { get; set; }
        public uint VoiceType { get; set; }
        public ushort Unk2 { get; set; }
        public short VoicePitch { get; set; }
        public string Name { get; set; }
        public LooksParam Looks { get; set; }
        public uint Unk3 { get; set; }
        public JobParam Jobs { get; set; }
        public byte[] unk4 { get; set; } = new byte[148];  // 148 字节的字节数组

        public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
        {
            if (context._account == null)
                return;

            var info = string.Format("[<--] 接收到的数据 (hex): {0} 字节", data.Length);
            Logger.WriteHex(info, data);

            var reader = new PacketReader(data, position, size);
            CharacterID = reader.ReadUInt32();
            AccountID = reader.ReadUInt32();
            Unk1 = reader.ReadUInt32();//Unk1
            VoiceType = reader.ReadUInt32(); // VoiceType
            Unk2 = reader.ReadUInt16(); // 5 unknown bytes
            VoicePitch = reader.ReadInt16(); // VoiceData
            Name = reader.ReadFixedLengthUtf16(16);
            Looks = reader.ReadStruct<LooksParam>();
            Unk3 = reader.ReadUInt32();
            Jobs = reader.ReadStruct<JobParam>();
            unk4 = reader.ReadBytes(unk4.Length);

            // 创建一个 Consumable 类型的物品
            PSO2ItemConsumable consumableItem = new PSO2ItemConsumable
            {
                amount = 10,
            };

            PSO2Items[] items = new PSO2Items[10];

            for (var i = 0; i < 10; i++)
            {
                items[i] = new PSO2Items
                {
                    uuid = (ulong)i,
                    id = new ItemId
                    {
                        ItemType = 3,
                        Id = 1,
                        Subid = 0,
                    },
                    data = new Items { Consumable = consumableItem }
                };
            }

            var newCharacter = new Character
            {
                CharacterID = 0,
                AccountID = context._account.AccountId,
                Unk1 = (int)Unk1,
                VoiceType = (int)VoiceType,
                Unk2 = (short)Unk2,
                VoicePitch = VoicePitch,
                Name = Name,
                Looks = Looks,
                Unk3 = (int)Unk3,
                Jobs = Jobs,
                Unk4 = unk4,
                EquipedItems = items,

                Account = context._account,
                Fulldata = data
            };

            // Add to database
            using (var db = new ServerEf())
            {
                // Check if any characters exist for this player
                var existingCharacters = db.Characters.Where(c => c.Account.AccountId == context._account.AccountId).ToList();
                if (existingCharacters.Count > 0)
                {
                    // Increment ID if characters already exist
                    newCharacter.CharacterID = existingCharacters.Max(c => c.CharacterID) + 1;
                }
                else
                {
                    // Start with ID 1 if no characters exist
                    newCharacter.CharacterID = 1;
                }

                Logger.Write("New character data: {0}, {1}, {2}, {3}, {4}", newCharacter.CharacterID, newCharacter.Name, newCharacter.VoiceType, newCharacter.VoicePitch, newCharacter.AccountID);

                db.Characters.Add(newCharacter);
                db.Entry(newCharacter.Account).State = EntityState.Modified;
                db.SaveChanges();
            }

            // Assign character to player
            context.Character = newCharacter;

            // Set Accounts ID
            context.SendPacket(new CharacterCreateResponsePacket(CharacterCreateResponsePacket.CharacterCreationStatus.Success, (uint)context._account.AccountId));
        }

        #endregion
    }
}