using Newtonsoft.Json;
using PSO2SERVER.Json;
using PSO2SERVER.Protocol;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static PSO2SERVER.Models.PSOPalette;

namespace PSO2SERVER.Models
{
    public class SubPalette
    {
        [JsonProperty("items")]
        [JsonConverter(typeof(FixedListConverter<PalettePA>))]
        // Items in the subpalette.
        public FixedList<PalettePA> Items { get; set; } = new FixedList<PalettePA>(0x0C, new PalettePA());

        // 从字节流中读取数据
        public void ReadFromStream(PacketReader reader)
        {
            // 假设 Items 长度固定为 12
            for (int i = 0; i < Items.Length; i++)
            {
                // 读取每个 PalettePA
                var palettePA = new PalettePA();
                palettePA.ReadFromStream(reader);
                Items.SetItem(i, palettePA);
            }
        }

        // 写入数据到字节流
        public void WriteToStream(PacketWriter writer)
        {
            // 遍历 FixedList，将每个 PalettePA 写入字节流
            foreach (var item in Items)
            {
                item.WriteToStream(writer);
            }
        }
    }

    public class PalettePA
    {
        [JsonProperty("id")]
        /// PA ID.
        public byte ID { get; set; } = 0;
        [JsonProperty("category")]
        /// PA category.
        public byte Category { get; set; } = 0;
        [JsonProperty("unk")]
        public byte Unk { get; set; } = 0;
        [JsonProperty("level")]
        /// PA level.
        public byte Level { get; set; } = 0;

        public PalettePA()
        {
        }

        public PalettePA(byte id, byte category, byte unk, byte level)
        {
            ID = id;
            Category = category;
            Unk = unk;
            Level = level;
        }

        public void ReadFromStream(PacketReader reader)
        {
            ID = reader.ReadByte();
            Category = reader.ReadByte();
            Unk = reader.ReadByte();
            Level = reader.ReadByte();
        }

        public void WriteToStream(PacketWriter writer)
        {
            writer.Write(ID);
            writer.Write(Category);
            writer.Write(Unk);
            writer.Write(Level);
        }
    }

    public class WeaponPalette
    {
        public ulong Uuid { get; set; } = 0;
        public uint Unk1 { get; set; } = 0;
        public PalettePA Unk2 { get; set; } = new PalettePA();
        public PalettePA Unk3 { get; set; } = new PalettePA();
        public PalettePA Unk4 { get; set; } = new PalettePA();
        public uint[] Unk { get; set; } = new uint[3];
        public uint PetId { get; set; } = 0;
        public List<PalettePA> Skills { get; set; } = new List<PalettePA>(6);

        public WeaponPalette()
        {
        }

        public void ReadFromStream(PacketReader reader)
        {
            Uuid = reader.ReadUInt64();
            Unk1 = reader.ReadUInt32();
            Unk2 = new PalettePA();
            Unk2.ReadFromStream(reader);
            Unk3 = new PalettePA();
            Unk3.ReadFromStream(reader);
            Unk4 = new PalettePA();
            Unk4.ReadFromStream(reader);
            for (int i = 0; i < Unk.Length; i++)
            {
                Unk[i] = reader.ReadUInt32();
            }
            PetId = reader.ReadUInt32();
            for (int i = 0; i < Skills.Count; i++)
            {
                Skills[i].ReadFromStream(reader);
            }
        }

        public void WriteToStream(PacketWriter writer)
        {
            writer.Write(Uuid);
            writer.Write(Unk1);
            Unk2.WriteToStream(writer);
            Unk3.WriteToStream(writer);
            Unk4.WriteToStream(writer);
            foreach (var value in Unk)
            {
                writer.Write(value);
            }
            writer.Write(PetId);
            foreach (var skill in Skills)
            {
                skill.WriteToStream(writer);
            }
        }
    }

    public class PSOPalette
    {
        public uint CurPalette { get; set; } = 0;
        public uint CurSubpalette { get; set; } = 0;
        public uint CurBook { get; set; } = 0;
        public FixedList<WeaponPalette> Palettes { get; set; } = new FixedList<WeaponPalette>(6, new WeaponPalette());
        public FixedList<SubPalette> Subpalettes { get; set; } = new FixedList<SubPalette>(6, new SubPalette());
        public List<uint> DefaultPas { get; set; } = new List<uint>();

        public PSOPalette() 
        {
            Palettes = new FixedList<WeaponPalette>(6, new WeaponPalette());
            Subpalettes = new FixedList<SubPalette>(6, new SubPalette());
            DefaultPas = new List<uint>();
        }

        public void ReadFromStream(PacketReader reader)
        {
            CurPalette = reader.ReadUInt32();
            CurSubpalette = reader.ReadUInt32();
            CurBook = reader.ReadUInt32();

            for (int i = 0; i < Palettes.Length; i++)
            {
                Palettes[i].ReadFromStream(reader);
            }

            for (int i = 0; i < Subpalettes.Length; i++)
            {
                Subpalettes[i].ReadFromStream(reader);
            }

            int defaultPasCount = reader.ReadInt32(); // 假设先读入数量
            DefaultPas.Clear();
            for (int i = 0; i < defaultPasCount; i++)
            {
                DefaultPas.Add(reader.ReadUInt32());
            }
        }

        public void WriteToStream(PacketWriter writer)
        {
            writer.Write(CurPalette);
            writer.Write(CurSubpalette);
            writer.Write(CurBook);

            for (int i = 0; i < Palettes.Length; i++)
            {
                Palettes[i].WriteToStream(writer);
            }

            for (int i = 0; i < Subpalettes.Length; i++)
            {
                Subpalettes[i].WriteToStream(writer);
            }

            foreach (var value in DefaultPas)
            {
                writer.Write(value);
            }
        }
    }
}
