using Newtonsoft.Json;
using Xunit;
using PSO2SERVER.Models;
using PSO2SERVER.Protocol;
using PSO2SERVER.Protocol.Handlers;
using PSO2SERVER.Zone;
using System;
using System.Runtime.InteropServices;
using static PSO2SERVER.Models.CharacterStruct;

namespace ServerTest
{
    public class ReflectionTests
    {
        public ReflectionTests()
        {
            // Setup 方法：在构造函数中加载 PacketHandlers
            PacketHandlers.LoadPacketHandlers();
        }

        [Fact]
        public void TestLoginLookup()
        {
            // 使用 xUnit 的 Assert.NotNull 代替 NUnit 的 Assert.IsNotNull
            Assert.NotNull(PacketHandlers.GetHandlerFor(0x11, 0x0));
        }

        [Fact]
        public void TestAllHandlers()
        {
            // 遍历每个加载的处理程序，检查是否为 null 和正确类型
            foreach (var p in PacketHandlers.GetLoadedHandlers())
            {
                Assert.NotNull(p);  // 确保 p 不是 null
                Assert.IsType<PacketHandler>(p);  // 确保 p 是 PacketHandler 类型
            }
        }
    }

    public class UnsafeTests
    {
        private readonly JobParam _jp = new JobParam();

        [Fact]
        public void CheckJobParam()
        {
            var size = Marshal.SizeOf(typeof(JobParam));
            Assert.NotNull(_jp);
            var jpArr = new byte[size];
            var ptr = Marshal.AllocHGlobal(size);

            Marshal.StructureToPtr(_jp, ptr, true);
            Marshal.Copy(ptr, jpArr, 0, size);
            Marshal.FreeHGlobal(ptr);

            foreach (var b in jpArr)
            {
                Assert.Equal(0, b);
            }
            Assert.Equal(size, jpArr.Length);
        }
    }

    public class WriterTests
    {
        private PacketWriter _writer;

        public WriterTests()  // 构造函数初始化
        {
            _writer = new PacketWriter();
        }

        [Fact]
        public void TestStructureWrite()
        {
            var structureSize = Marshal.SizeOf(typeof(JobParam));
            var jp = new JobParam();
            jp.entries.hunter.level = 7;
            _writer.WriteStruct(jp);
            var structArray = _writer.ToArray();

            Assert.Equal(structureSize, structArray.Length);  // xUnit 中使用 Assert.Equal
            Assert.Equal(7, structArray[12]);  // xUnit 中使用 Assert.Equal
        }
    }

    public class JsonTests
    {
        [Fact]
        public void TestObjectSerialize()
        {
            var testObject = new PSOObject
            {
                Name = "testobj",
                Header = new ObjectHeader { ID = 1337, ObjectType = ObjectType.Object },
                Position = new PSOLocation
                {
                    RotX = (float)3.3,
                    RotY = (float)3.3,
                    RotZ = (float)3.3,
                    RotW = (float)3.3,
                    PosX = (float)3.3,
                    PosY = (float)3.3,
                    PosZ = (float)3.3
                },
                ThingFlag = 4,
                Things = new PSOObject.PSOObjectThing[2]
            };

            var thingData = BitConverter.ToUInt32(new byte[] { 0xff, 0xff, 0xff, 0xff }, 0);
            testObject.Things[0] = new PSOObject.PSOObjectThing { Data = thingData };
            var output = JsonConvert.SerializeObject(testObject);
            Console.WriteLine(output);  // 在 xUnit 中，控制台输出会显示在日志中
        }
    }

    public class DataTests
    {
        [Fact]
        public void TestShiftEnum()
        {
            byte[] bytes = { 0x1, 0x1, 0x1 };
            uint dataFlags = bytes[0];
            dataFlags |= (uint)(bytes[1] << 8);
            dataFlags |= (uint)(bytes[2] << 16);

            Assert.Equal(PackedData.ENT1_ID | PackedData.ROT_Y | PackedData.UNK_Y,
                (PackedData)dataFlags);  // xUnit 中使用 Assert.Equal
            Console.WriteLine((PackedData)dataFlags);  // 在 xUnit 中，控制台输出会显示在日志中
        }

        [Fact]
        public void TestItemGUID()
        {
            byte[] itemData =
            {
                0xDA, 0x40, 0x99, 0x60, 0x79, 0x2E, 0xFF, 0x03, 0x01, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x20, 0x00,
                0x00, 0x03, 0xFF, 0x0A, 0x64, 0x00, 0x12, 0x34, 0x01, 0x02, 0x02, 0x02, 0x03, 0x02, 0x04, 0x02,
                0x05, 0x02, 0x06, 0x02, 0x07, 0x02, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
            };
            PSO2Items item = PSO2Items.FromByteArray(itemData);
            ulong oldguid = 0x03FF2E79609940DA;
            ulong guid = item.GetGUID();
            ulong newguid = 0x0123456789ABCDEF;

            Assert.Equal(oldguid, guid);  // xUnit 中使用 Assert.Equal
            item.SetGUID(newguid);
            Assert.Equal(newguid, item.GetGUID());  // xUnit 中使用 Assert.Equal
        }
    }
}