using Newtonsoft.Json;
using PSO2SERVER.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
using UltimateOrb;

namespace PSO2SERVER.Models
{
    // 表示 JSON 的根对象
    public class ItemAttributesRootObject
    {
        [JsonProperty("PC")]
        public ItemAttributesPC PC { get; set; }
        [JsonProperty("VITA")]
        public ItemAttributesVita VITA { get; set; }
    }

    // Base class for ItemAttributes
    [Serializable]
    public abstract class ItemAttributesBase
    {
        [JsonProperty("unk1")]
        public uint Unk1 { get; set; }
        [JsonProperty("unk2")]
        public UInt128 Unk2 { get; set; }
    }

    // PC ItemAttributes (NA and JP client)
    [Serializable]
    public class ItemAttributesPC : ItemAttributesBase
    {
        [JsonProperty("weapons")]
        public List<WeaponAttrs> Weapons { get; set; } = new List<WeaponAttrs>();
        [JsonProperty("human_costumes")]
        public List<HumanCostume> HumanCostumes { get; set; } = new List<HumanCostume>();
        [JsonProperty("cast_parts")]
        public List<CastPart> CastParts { get; set; } = new List<CastPart>();
        [JsonProperty("consumables")]
        public List<Consumable> Consumables { get; set; } = new List<Consumable>();
        [JsonProperty("data5")]
        public List<Data5> Data5 { get; set; } = new List<Data5>();
        [JsonProperty("data6")]
        public List<Unit> Data6 { get; set; } = new List<Unit>();
        [JsonProperty("data7")]
        public List<Data7> Data7 { get; set; } = new List<Data7>();
        [JsonProperty("data8")]
        public List<Data8> Data8 { get; set; } = new List<Data8>();
        [JsonProperty("data9")]
        public List<Data9> Data9 { get; set; } = new List<Data9>();
        [JsonProperty("data10")]
        public List<Data10> Data10 { get; set; } = new List<Data10>();
        [JsonProperty("data11")]
        public List<Data11> Data11 { get; set; } = new List<Data11>();
        [JsonProperty("data12")]
        public List<Data12> Data12 { get; set; } = new List<Data12>();
        [JsonProperty("data13")]
        public List<Data13> Data13 { get; set; } = new List<Data13>();
        [JsonProperty("data14")]
        public List<Data14> Data14 { get; set; } = new List<Data14>();
        [JsonProperty("data15")]
        public List<Data15> Data15 { get; set; } = new List<Data15>();
        [JsonProperty("data16")]
        public List<Data16> Data16 { get; set; } = new List<Data16>();
        [JsonProperty("data17")]
        public List<Data17> Data17 { get; set; } = new List<Data17>();
        [JsonProperty("data18")]
        [JsonConverter(typeof(FixedListConverter<ShortData>))]
        public FixedList<ShortData> Data18 { get; set; } = new FixedList<ShortData>(406);
        [JsonProperty("data19")]
        public List<Data19> Data19 { get; set; } = new List<Data19>();
        [JsonProperty("data20")]
        public List<Data20> Data20 { get; set; } = new List<Data20>();


        public static void LogWeapons(List<WeaponAttrs> weapons)
        {
            if (weapons == null || weapons.Count == 0) return;

            Logger.Write($"Weapons Count: {weapons.Count}");
            foreach (var weapon in weapons)
            {
                Logger.Write($"Weapon ID: {weapon.Id}, Range Damage: {weapon.RangeDmg}, Gender: {weapon.Gender}");
                Logger.Write($"weapon.Unk8 Length: {weapon.Unk8.Length}");
                foreach (var un8 in weapon.Unk8)
                {
                    Logger.Write($"Weapon un8: {un8}");
                }
            }
        }

        // 输出 Data17 列表信息
        public static void LogData17(List<Data17> data17List)
        {
            if (data17List == null || data17List.Count == 0) return;

            Logger.Write($"Data17 Count: {data17List.Count}");
            foreach (var data17 in data17List)
            {
                Logger.Write($"data17.unk Length: {data17.unk.Length}");
                foreach (var value in data17.unk)
                {
                    Logger.Write($"data17 value: {value}");
                }
            }
        }
    }

    // Vita ItemAttributes (Vita client)
    [Serializable]
    public class ItemAttributesVita : ItemAttributesBase
    {
        [JsonProperty("weapons")]
        public List<WeaponAttrs> Weapons { get; set; } = new List<WeaponAttrs>();
        [JsonProperty("human_costumes")]
        public List<HumanCostume> HumanCostumes { get; set; } = new List<HumanCostume>();
        [JsonProperty("cast_parts")]
        public List<CastPart> CastParts { get; set; } = new List<CastPart>();
        [JsonProperty("consumables")]
        public List<Consumable> Consumables { get; set; } = new List<Consumable>();
        [JsonProperty("data5")]
        public List<Data5> Data5 { get; set; } = new List<Data5>();
        [JsonProperty("data6")]
        public List<Unit> Data6 { get; set; } = new List<Unit>();
        [JsonProperty("data7")]
        public List<Data7> Data7 { get; set; } = new List<Data7>();
        [JsonProperty("data8")]
        public List<Data8> Data8 { get; set; } = new List<Data8>();
        [JsonProperty("data9")]
        public List<Data9> Data9 { get; set; } = new List<Data9>();
        [JsonProperty("data10")]
        public List<Data10> Data10 { get; set; } = new List<Data10>();
        [JsonProperty("data11")]
        public List<Data11> Data11 { get; set; } = new List<Data11>();
        [JsonProperty("data12")]
        public List<Data12> Data12 { get; set; } = new List<Data12>();
        [JsonProperty("data13")]
        public List<Data13> Data13 { get; set; } = new List<Data13>();
        [JsonProperty("data14")]
        public List<Data14> Data14 { get; set; } = new List<Data14>();
        [JsonProperty("data15")]
        public List<Data15> Data15 { get; set; } = new List<Data15>();
        [JsonProperty("data16")]
        public List<Data16> Data16 { get; set; } = new List<Data16>();
        [JsonProperty("data17")]
        public List<Data17> Data17 { get; set; } = new List<Data17>();
        [JsonProperty("data18")]
        [JsonConverter(typeof(FixedListConverter<ShortData>))]
        public FixedList<ShortData> Data18 { get; set; } = new FixedList<ShortData>(406);
        [JsonProperty("data19")]
        public List<Data19Vita> Data19 { get; set; } = new List<Data19Vita>();
        [JsonProperty("data20")]
        public List<Data20> Data20 { get; set; } = new List<Data20>();
    }

    // Abstract base class that holds the common functionality of the Item, irrespective of the platform
    [Serializable]
    public class ItemAttr
    {
        public ItemAttributesBase Attributes { get; set; }

        // Constructor to initialize an item with platform-specific attributes
        public ItemAttr(ItemAttributesBase attributes)
        {
            Attributes = attributes;
        }

        // Method to display item attributes
        public void DisplayAttributes()
        {
            switch (Attributes)
            {
                case ItemAttributesPC pcAttributes:
                    Console.WriteLine("PC Version Item Attributes:");
                    Console.WriteLine($"Weapons Count: {pcAttributes.Weapons.Count}");
                    // Add further attribute display logic for PC
                    break;

                case ItemAttributesVita vitaAttributes:
                    Console.WriteLine("Vita Version Item Attributes:");
                    Console.WriteLine($"Weapons Count: {vitaAttributes.Weapons.Count}");
                    // Add further attribute display logic for Vita
                    break;

                default:
                    Console.WriteLine("Unknown ItemAttributes");
                    break;
            }
        }
    }

    // Example of a simple class, could be for one of the referenced types
    [Serializable]
    public class WeaponAttrs
    {
        // Item category
        [JsonProperty("id")]
        public ushort Id { get; set; }

        // Item ID
        [JsonProperty("subid")]
        public ushort Subid { get; set; }

        [JsonProperty("unk1")]
        public byte Unk1 { get; set; }

        [JsonProperty("priority")]
        public byte Priority { get; set; }

        [JsonProperty("unk2")]
        public byte Unk2 { get; set; }

        [JsonProperty("priority2")]
        public byte Priority2 { get; set; }

        // Item rarity in stars
        [JsonProperty("rarity")]
        public byte Rarity { get; set; }

        [JsonProperty("flags")]
        public ushort Flags { get; set; }

        [JsonProperty("unk3")]
        public byte Unk3 { get; set; }

        [JsonProperty("icon_list")]
        public ushort IconList { get; set; }

        [JsonProperty("icon_index")]
        public ushort IconIndex { get; set; }

        // Range damage
        [JsonProperty("range_dmg")]
        public ushort RangeDmg { get; set; }

        [JsonProperty("unk4")]
        public byte Unk4 { get; set; }

        // Melee damage
        [JsonProperty("melee_dmg")]
        public ushort MeleeDmg { get; set; }

        [JsonProperty("unk5")]
        public byte Unk5 { get; set; }

        [JsonProperty("unk6")]
        public uint Unk6 { get; set; }

        // Force damage and equipable genders
        [JsonProperty("force_dmg")]
        public uint ForceDmg { get; set; }

        [JsonProperty("gender")]
        public string Gender { get; set; }

        [JsonProperty("unk8")]
        [JsonConverter(typeof(FixedListConverter<byte>))]
        public FixedList<byte> Unk8 { get; set; } = new FixedList<byte>(0x04, 0);

        // Equipable races
        [JsonProperty("race")]
        public string Race { get; set; }

        [JsonProperty("flags2")]
        public byte Flags2 { get; set; }

        // Equipable classes
        [JsonProperty("class")]
        public string Class { get; set; }

        // Required stat value
        [JsonProperty("req_stat")]
        public ushort ReqStat { get; set; }

        // Required stat type
        [JsonProperty("req_stat_type")]
        public string ReqStatType { get; set; }

        [JsonProperty("unk9")]
        public byte Unk9 { get; set; }

        [JsonProperty("model")]
        public ushort Model { get; set; }

        [JsonProperty("unk10")]
        public uint Unk10 { get; set; }

        [JsonProperty("unk11")]
        public ushort Unk11 { get; set; }

        [JsonProperty("affix_flag")]
        public ushort AffixFlag { get; set; }

        [JsonProperty("unk12")]
        public ushort Unk12 { get; set; }
    }

    [Serializable]
    public class HumanCostume
    {
        /// <summary>
        /// Item category.
        /// </summary>
        [JsonProperty("id")]
        public ushort Id { get; set; }

        /// <summary>
        /// Item ID.
        /// </summary>
        [JsonProperty("subid")]
        public ushort Subid { get; set; }
        [JsonProperty("unk1")]
        public ushort Unk1 { get; set; }
        [JsonProperty("unk2")]
        public ushort Unk2 { get; set; }
        /// <summary>
        /// Item rarity in stars.
        /// </summary>
        [JsonProperty("rarity")]
        public byte Rarity { get; set; }
        [JsonProperty("flags")]
        public ushort Flags { get; set; }
        [JsonProperty("unk3")]
        public byte Unk3 { get; set; }
        [JsonProperty("icon_list")]
        public ushort IconList { get; set; }
        [JsonProperty("icon_index")]
        public ushort IconIndex { get; set; }
        /// <summary>
        /// Equipable genders.
        /// </summary>
        [JsonProperty("gender_flags")]
        [JsonConverter(typeof(GenderFlagsConverter))]
        public GenderFlags GenderFlags { get; set; }
        [JsonProperty("color_flags")]
        public byte ColorFlags { get; set; }
        /// <summary>
        /// Equipable races.
        /// </summary>
        [JsonProperty("race_flags")]
        [JsonConverter(typeof(RaceFlagsConverter))]
        public RaceFlags RaceFlags { get; set; }
        [JsonProperty("unk4")]
        public byte Unk4 { get; set; }
        [JsonProperty("model")]
        public ushort Model { get; set; }
        [JsonProperty("unk5")]
        [JsonConverter(typeof(FixedUShort.FixedUShortConverter))]
        public FixedUShort Unk5 { get; set; } = new FixedUShort(3);
    }

    [Serializable]
    public class CastPart
    {
        /// <summary>
        /// Item category.
        /// </summary>
        [JsonProperty("id")]
        public ushort Id { get; set; }

        /// <summary>
        /// Item ID.
        /// </summary>
        [JsonProperty("subid")]
        public ushort Subid { get; set; }
        [JsonProperty("unk1")]
        public ushort Unk1 { get; set; }
        [JsonProperty("unk2")]
        public ushort Unk2 { get; set; }
        /// <summary>
        /// Item rarity in stars.
        /// </summary>
        /// [JsonProperty("")]
        [JsonProperty("rarity")]
        public byte Rarity { get; set; }
        [JsonProperty("flags")]
        public ushort Flags { get; set; }
        [JsonProperty("unk3")]
        public byte Unk3 { get; set; }
        [JsonProperty("icon_list")]
        public ushort IconList { get; set; }
        [JsonProperty("icon_index")]
        public ushort IconIndex { get; set; }
        [JsonProperty("gender_flags")]
        public byte GenderFlags { get; set; }
        [JsonProperty("unk4")]
        public byte Unk4 { get; set; }
        [JsonProperty("race_flags")]
        public byte RaceFlags { get; set; }
        [JsonProperty("unk5")]
        public byte Unk5 { get; set; }
        [JsonProperty("unk6")]
        public ushort Unk6 { get; set; }
        [JsonProperty("model")]
        public ushort Model { get; set; }

        // 默认构造函数
        public CastPart()
        {
            // 如果需要初始化某些属性，可以在这里进行
        }
    }

    [Serializable]
    public class Consumable
    {
        [JsonProperty("id")]
        public ushort Id { get; set; }

        [JsonProperty("subid")]
        public ushort Subid { get; set; }

        [JsonProperty("unk1")]
        public ushort Unk1 { get; set; }

        [JsonProperty("unk2")]
        public ushort Unk2 { get; set; }

        [JsonProperty("rarity")]
        public byte Rarity { get; set; }

        [JsonProperty("flags")]
        public ushort Flags { get; set; }

        [JsonProperty("unk3")]
        public byte Unk3 { get; set; }

        [JsonProperty("icon_list")]
        public ushort IconList { get; set; }

        [JsonProperty("icon_index")]
        public ushort IconIndex { get; set; }

        [JsonProperty("max_qty")]
        public byte MaxQty { get; set; }

        [JsonProperty("unk4")]
        public byte[] Unk4 { get; set; } = new byte[3];

        [JsonProperty("unk5")]
        public uint Unk5 { get; set; }
    }

    [Serializable]
    public class Data5
    {
        [JsonProperty("id")]
        public ushort Id { get; set; }

        [JsonProperty("subid")]
        public ushort Subid { get; set; }

        [JsonProperty("unk1")]
        public ushort Unk1 { get; set; }

        [JsonProperty("unk2")]
        public ushort Unk2 { get; set; }

        [JsonProperty("unk6")]
        public byte Unk6 { get; set; }

        [JsonProperty("unk3")]
        public byte Unk3 { get; set; }

        [JsonProperty("unk4")]
        public byte Unk4 { get; set; }

        [JsonProperty("unk5")]
        public byte Unk5 { get; set; }

        [JsonProperty("icon_list")]
        public ushort IconList { get; set; }

        [JsonProperty("icon_index")]
        public ushort IconIndex { get; set; }

        [JsonProperty("unk")]
        public byte[] Unk { get; set; } = new byte[0x30]; // Fixed length of 0x30 bytes
    }

    [Serializable]
    public class Unit
    {
        /// <summary>
        /// Item category.
        /// </summary>
        [JsonProperty("id")]
        public ushort Id { get; set; }

        /// <summary>
        /// Item ID.
        /// </summary>
        [JsonProperty("subid")]
        public ushort Subid { get; set; }

        [JsonProperty("unk1")]
        public ushort Unk1 { get; set; }

        [JsonProperty("unk2")]
        public ushort Unk2 { get; set; }

        /// <summary>
        /// Item rarity in stars.
        /// </summary>
        [JsonProperty("rarity")]
        public byte Rarity { get; set; }

        [JsonProperty("flags")]
        public ushort Flags { get; set; }

        [JsonProperty("unk3")]
        public byte Unk3 { get; set; }

        [JsonProperty("icon_list")]
        public ushort IconList { get; set; }

        [JsonProperty("icon_index")]
        public ushort IconIndex { get; set; }

        /// <summary>
        /// Unit stats.
        /// </summary>
        [JsonProperty("stats")]
        public UnitRes Stats { get; set; }

        /// <summary>
        /// Required stat type.
        /// </summary>
        [JsonProperty("req_stat_type")]
        public StatType ReqStatType { get; set; }

        [JsonProperty("unk4")]
        public byte Unk4 { get; set; }

        [JsonProperty("unk5")]
        public byte Unk5 { get; set; }

        [JsonProperty("unk6")]
        public ushort Unk6 { get; set; }

        [JsonProperty("unk7")]
        public ushort Unk7 { get; set; }

        [JsonProperty("unk8")]
        public ushort Unk8 { get; set; }

        [JsonProperty("unk9")]
        public ushort Unk9 { get; set; }

        /// <summary>
        /// Required stat value.
        /// </summary>
        [JsonProperty("req_stat")]
        public ushort ReqStat { get; set; }

        /// <summary>
        /// Unit attack values.
        /// </summary>
        [JsonProperty("atk")]
        public UnitAtk Atk { get; set; }

        [JsonProperty("unk10")]
        public byte Unk10 { get; set; }

        [JsonProperty("unk11")]
        public byte Unk11 { get; set; }

        [JsonProperty("unk12")]
        public byte Unk12 { get; set; }

        [JsonProperty("unk13")]
        public ushort Unk13 { get; set; }

        [JsonProperty("unk14")]
        public uint Unk14 { get; set; }

        [JsonProperty("unk15")]
        public uint Unk15 { get; set; }
    }

    public class Data7
    {
        [JsonConverter(typeof(FixedListConverter<byte>))]
        public FixedList<byte> unk { get; set; } = new FixedList<byte>(0x38, 0);
    }
    public class Data8
    {
        [JsonConverter(typeof(FixedListConverter<byte>))]
        public FixedList<byte> unk { get; set; } = new FixedList<byte>(0x10, 0);
    }
    public class Data9
    {
        [JsonConverter(typeof(FixedListConverter<byte>))]
        public FixedList<byte> unk { get; set; } = new FixedList<byte>(0x3C, 0);
    }
    public class Data10
    {
        [JsonConverter(typeof(FixedListConverter<byte>))]
        public FixedList<byte> unk { get; set; } = new FixedList<byte>(0x24, 0);
    }
    public class Data11
    {
        [JsonConverter(typeof(FixedListConverter<byte>))]
        public FixedList<byte> unk { get; set; } = new FixedList<byte>(0x10, 0);
    }
    public class Data12
    {
        [JsonConverter(typeof(FixedListConverter<byte>))]
        public FixedList<byte> unk { get; set; } = new FixedList<byte>(0x24, 0);
    }
    public class Data13
    {
        [JsonConverter(typeof(FixedListConverter<byte>))]
        public FixedList<byte> unk { get; set; } = new FixedList<byte>(0x50, 0);
    }
    public class Data14
    {
        [JsonConverter(typeof(FixedListConverter<byte>))]
        public FixedList<byte> unk { get; set; } = new FixedList<byte>(0x7C, 0);
    }
    public class Data15
    {
        [JsonConverter(typeof(FixedListConverter<byte>))]
        public FixedList<byte> unk { get; set; } = new FixedList<byte>(0x10, 0);
    }
    public class Data16
    {
        [JsonConverter(typeof(FixedListConverter<byte>))]
        public FixedList<byte> unk { get; set; } = new FixedList<byte>(0x12, 0);
    }
    public class Data17
    {
        [JsonConverter(typeof(FixedListConverter<byte>))]
        public FixedList<byte> unk { get; set; } = new FixedList<byte>(0x5A, 0);
    }
    public class Data18
    {
        [JsonConverter(typeof(FixedListConverter<byte>))]
        public FixedList<byte> unk { get; set; } = new FixedList<byte>(0x08, 0);
    }
    public class ShortData
    {
        public List<Data18> unk { get; set; } = new List<Data18>();
    }
    public class Data19
    {
        [JsonConverter(typeof(FixedListConverter<byte>))]
        public FixedList<byte> unk { get; set; } = new FixedList<byte>(0x54, 0);
    }
    public class Data19Vita
    {
        [JsonConverter(typeof(FixedListConverter<byte>))]
        public FixedList<byte> unk { get; set; } = new FixedList<byte>(0x2C, 0);
    }
    public class Data20
    {
        [JsonConverter(typeof(FixedListConverter<byte>))]
        public FixedList<byte> unk { get; set; } = new FixedList<byte>(0x1C, 0);
    }

    public struct GenderDmg
    {
        /// Force damage.
        public ushort force_dmg;
        /// Equipable genders.
        public GenderFlags gender;
    }

    public enum StatType
    {
        // MEL power.
        MELPwr = 0,

        // RNG power.
        RNGPwr = 1,

        // TEC power.
        TECPwr = 2,

        // DEX.
        DEX = 3,

        // MEL defence.
        MELDef = 4,

        // RNG defence.
        RNGDef = 5,

        // TEC defence.
        TECDef = 6
    }

    public static class StatTypeExtensions
    {
        public static StatType Default => StatType.MELPwr;
    }

    public class UnitRes
    {
        /// <summary>
        /// TEC resistance.
        /// </summary>
        [JsonProperty("tec_res")]
        public byte TecRes { get; set; }

        /// <summary>
        /// TEC defence.
        /// </summary>
        [JsonProperty("tec_def")]
        public ushort TecDef { get; set; }

        /// <summary>
        /// RNG defence.
        /// </summary>
        [JsonProperty("rng_def")]
        public ushort RngDef { get; set; }

        /// <summary>
        /// MEL defence.
        /// </summary>
        [JsonProperty("mel_def")]
        public ushort MelDef { get; set; }

        /// <summary>
        /// Additional HP.
        /// </summary>
        [JsonProperty("hp")]
        public ushort Hp { get; set; }

        /// <summary>
        /// Additional PP.
        /// </summary>
        [JsonProperty("pp")]
        public byte Pp { get; set; }

        /// <summary>
        /// Dark resistance.
        /// </summary>
        [JsonProperty("dark_res")]
        public byte DarkRes { get; set; }

        /// <summary>
        /// Light resistance.
        /// </summary>
        [JsonProperty("light_res")]
        public byte LightRes { get; set; }

        /// <summary>
        /// Wind resistance.
        /// </summary>
        [JsonProperty("wind_res")]
        public byte WindRes { get; set; }

        /// <summary>
        /// Lightning resistance.
        /// </summary>
        [JsonProperty("lightning_res")]
        public byte LightningRes { get; set; }

        /// <summary>
        /// Ice resistance.
        /// </summary>
        [JsonProperty("ice_res")]
        public byte IceRes { get; set; }

        /// <summary>
        /// Fire resistance.
        /// </summary>
        [JsonProperty("fire_res")]
        public byte FireRes { get; set; }

        /// <summary>
        /// RNG resistance.
        /// </summary>
        [JsonProperty("rng_res")]
        public byte RngRes { get; set; }

        /// <summary>
        /// MEL resistance.
        /// </summary>
        [JsonProperty("mel_res")]
        public byte MelRes { get; set; }
    }

    public class UnitAtk
    {
        /// <summary>
        /// Additional MEL attack.
        /// </summary>
        [JsonProperty("mel_atk")]
        public ushort MelAtk { get; set; }

        /// <summary>
        /// Additional RNG attack.
        /// </summary>
        [JsonProperty("rng_atk")]
        public ushort RngAtk { get; set; }

        /// <summary>
        /// Additional TEC attack.
        /// </summary>
        [JsonProperty("tec_atk")]
        public ushort TecAtk { get; set; }

        /// <summary>
        /// Additional DEX.
        /// </summary>
        [JsonProperty("dex")]
        public ushort Dex { get; set; }

        [JsonProperty("unk_atk")]
        public byte UnkAtk { get; set; }
    }

    public class GenderFlagsConverter : JsonConverter<GenderFlags>
    {
        public override GenderFlags ReadJson(JsonReader reader, Type objectType, GenderFlags existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
            var value = reader.Value as string;
            if (value != null)
            {
                GenderFlags genderFlags = GenderFlags.NONE;

                // 按 '|' 分割字符串
                var flags = value.Split('|');
                foreach (var flag in flags)
                {
                    var trimmedFlag = flag.Trim();
                    if (Enum.TryParse<GenderFlags>(trimmedFlag, out var parsedFlag))
                    {
                        genderFlags |= parsedFlag;
                    }
                }
                return genderFlags;
            }

            return GenderFlags.NONE;
        }

        public override void WriteJson(JsonWriter writer, GenderFlags value, JsonSerializer serializer)
        {
            writer.WriteValue(value.ToString());
        }
    }

    [Flags]
    /// Equipable genders.
    public enum GenderFlags : byte
    {
        NONE = 0,
        /// Males can equip.
        MALE = 1 << 0,
        /// Females can equip.
        FEMALE = 1 << 1,
    }

    public class RaceFlagsConverter : JsonConverter<RaceFlags>
    {
        public override RaceFlags ReadJson(JsonReader reader, Type objectType, RaceFlags existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
            var value = reader.Value as string;
            if (value != null)
            {
                RaceFlags raceFlags = RaceFlags.NONE;

                // 按 '|' 分割字符串
                var flags = value.Split('|');
                foreach (var flag in flags)
                {
                    var trimmedFlag = flag.Trim();
                    if (Enum.TryParse<RaceFlags>(trimmedFlag, out var parsedFlag))
                    {
                        raceFlags |= parsedFlag;
                    }
                }
                return raceFlags;
            }

            return RaceFlags.NONE;
        }

        public override void WriteJson(JsonWriter writer, RaceFlags value, JsonSerializer serializer)
        {
            writer.WriteValue(value.ToString());
        }
    }

    [Flags]
    /// Equipable races.
    public enum RaceFlags : byte
    {
        NONE = 0,
        /// Humans can equip.
        HUMAN = 1 << 0,
        /// Newmans can equip.
        NEWMAN = 1 << 1,
        /// CASTs can equip.
        CAST = 1 << 2,
        /// Deumans can equip.
        DEUMAN = 1 << 3,
    }
}
