using PSO2SERVER.Database;
using PSO2SERVER.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Contexts;
using System.Text;
using static PSO2SERVER.Models.CharacterStruct;

namespace PSO2SERVER.Protocol.Packets
{
    public class CharacterListPacket : Packet
    {
        // Available characters
        public List<Character> Characters { get; set; } = new List<Character>();

        // Equipped items (List of 10 Items for each character)
        public List<PSO2Items[]> EquippedItems { get; set; } = new List<PSO2Items[]>();

        // Character play times (30 times)
        public uint[] PlayTimes { get; set; } = new uint[30];

        // Character deletion flags (flag, deletion timestamp) (30 pairs of (u32, u32))
        public (uint flag, uint timestamp)[] DeletionFlags { get; set; } = new (uint, uint)[30];

        // Character ship transfer flags (30 pairs of (u32, u32))
        public (uint flag, uint timestamp)[] TransferFlags { get; set; } = new (uint, uint)[30];

        // Account accessory flag (unknown)
        public ushort AccountAccessory { get; set; }

        // Login survey flag
        public uint LoginSurvey { get; set; }

        // Ad flag
        public uint Ad { get; set; }

        // Ninji note: This packet may be followed by extra data,
        // after a fixed-length array of character data structures.
        // Needs more investigation at some point.
        // --- 
        // CK note: Extra data is likely current equipment, playtime, etc.
        // All of that data is currently unaccounted for at the moment.
        //忍者注意:这个包后面可能有额外的数据，
        //在固定长度的字符数据结构数组之后。
        //需要更多的调查。
        // ---
        // CK注:额外的数据可能是当前设备，游戏时间等。
        //所有这些数据目前都是未知的。

        private int AccountId;

        public CharacterListPacket(int AccountId)
        {
            this.AccountId = AccountId;
        }

        #region implemented abstract members of Packet

        public override byte[] Build()
        {
            using (var db = new ServerEf())
            {
                var chars = db.Characters
                    .Where(w => w.Account.AccountId == AccountId)
                    .OrderBy(o => o.CharacterID) // TODO: 按照最后游玩的角色排序
                    .Select(s => s);

                foreach (var ch in chars)
                {
                    Characters.Add(ch);

                    //// 创建一个 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 }
                    //    };
                    //}

                    EquippedItems.Add(ch.EquipedItems);
                }
            }

            var pkt = new PacketWriter();

            pkt.Write((uint)Characters.Count()); // 写入玩家数量
            pkt.Write((uint)0);
            foreach (var ch in Characters)
            {
                pkt.Write((uint)0);
                pkt.Write(ch.BuildCharacterByteArray());//4
            }

            pkt.Write((uint)EquippedItems.Count()); // 写入物品数量
            foreach (var itemsArray in EquippedItems)
            {
                foreach (var item in itemsArray)
                {
                    byte[] itemBytes = item.ToByteArray();  // Assume PSO2Items has a ToByteArray method
                    pkt.Write(itemBytes);  // Write the item bytes
                }
            }
            // Write PlayTimes
            foreach (var playTime in PlayTimes)
            {
                pkt.Write(playTime);
            }
            // Write DeletionFlags
            foreach (var flag in DeletionFlags)
            {
                pkt.Write(flag.flag);
                pkt.Write(flag.timestamp);
            }
            // Write TransferFlags
            foreach (var flag in TransferFlags)
            {
                pkt.Write(flag.flag);
                pkt.Write(flag.timestamp);
            }

            // Write AccountAccessory
            pkt.Write(AccountAccessory);

            // Write LoginSurvey
            pkt.Write(LoginSurvey);

            // Write Ad
            pkt.Write(Ad);

            pkt.WriteBytes(0, 2);


            return pkt.ToArray();
        }

        public override PacketHeader GetHeader()
        {
            return new PacketHeader(0x11, 0x03, PacketFlags.None);
        }

        #endregion
    }
}