using Godot;
using System;
using System.Linq;
using System.Text.Json;
using System.Collections.Generic;

// using System.IO;
using AvatarDoll;
using ProjectSettings = AvatarDoll.ProjectSettings;

public partial class _Test : Node2D
{

	
	// Called when the node enters the scene tree for the first time.
	public override void _Ready()
	{
		// AvatarDataTest();
		// AvatarProjectTest();
	}

	// Called every frame. 'delta' is the elapsed time since the previous frame.
	public override void _Process(double delta)
	{
		
	}

	public void LubanTest()
	{
		// string path = "res://DataTables/Table/demo_tbitem.bytes";
		// //byte[] buffer = File.ReadAllBytes(path);
		//
		// using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
		// long fileLength = (long)file.GetLength();
		// byte[] buffer = new byte[fileLength];
		// buffer = file.GetBuffer(fileLength);
		// var tables = new cfg.Tables(file => new JsonElement(buffer));
		//
		// cfg.demo.item reward = tables.Tbitem.Get(1001);
		// GD.Print("== load succ ==:" + reward.Name);
		
		
		string path = "res://DataTables/Table/avatar_data.json";
		//byte[] buffer = File.ReadAllBytes(path);
		
		using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
		string jsonText = file.GetAsText();
		using JsonDocument doc = JsonDocument.Parse(jsonText);
		// var tables = new cfg.Tables(file => doc.RootElement);

		
		// cfg.AvatarDoll.AvatarDollData_Test reward = tables.TbAvatarDollDataTest;
		GD.Print("== load succ ==:");
		
	}
	

	public void AvatarDataTest()
	{
		// 准备测试数据
		AvatarDollData data = new AvatarDollData();
		{
			data.FormatVersion = 1;
			data.Metadata.Author = "Author";
			data.Metadata.Introduction = "Introduction\nIntroduction\nIntroduction";
			data.Metadata.Version = "3.0.1";
			data.Metadata.Link = "https://www.google.com/";

			for (int i = 0; i < 10; ++i)
			{
				char a = (char)('a' + i);
				data.AssetMap[i] = "asset_" + a + a + a + ".png";
			}

			AvatarBody body = new AvatarBody();
			body.Guid = BitConverter.ToUInt32(Guid.NewGuid().ToByteArray(), 0);
			body.Name = "少女体型";
			body.Introduction = "默认少女体型";
			body.IconAssetId = 1;

			AvatarElement bodypart1 = new AvatarElement();
			bodypart1.AssetId = 1;
			bodypart1.PositionX = 111;
			bodypart1.PositionY = 111;
			bodypart1.Layer = 11;
			body.Elements["3000"] = new List<AvatarDoll.AvatarElement>();
			body.Elements["3000"].Add(bodypart1);
			data.Bodies.Add(body);

			AvatarHair hair = new AvatarHair();
			hair.Guid = BitConverter.ToUInt32(Guid.NewGuid().ToByteArray(), 0);
			hair.Name = "少女发型";
			hair.Introduction = "默认少女发型";
			hair.IconAssetId = 1;

			AvatarElement hairpart = new AvatarElement();
			hairpart.AssetId = 2;
			hairpart.PositionX = 222;
			hairpart.PositionY = 222;
			hairpart.Layer = 22;
			hair.Elements["3000"] = new List<AvatarDoll.AvatarElement>();
			hair.Elements["3000"].Add(hairpart);
			data.Hairs.Add(hair);

			AvatarFace face = new AvatarFace();
			face.Guid = BitConverter.ToUInt32(Guid.NewGuid().ToByteArray(), 0);
			face.Name = "少女脸型";
			face.Introduction = "默认少女脸型";
			face.IconAssetId = 1;
			
			AvatarElement facepart = new AvatarElement();
			facepart.AssetId = 3;
			facepart.PositionX = 333;
			facepart.PositionY = 333;
			facepart.Layer = 33;
			face.Elements["3000"] = new List<AvatarDoll.AvatarElement>();
			face.Elements["3000"].Add(facepart);
			data.Faces.Add(face);

			for (int i = 0; i < 3; ++i)
			{
				AvatarCloth cloth = new AvatarCloth();
				cloth.Guid = BitConverter.ToUInt32(Guid.NewGuid().ToByteArray(), 0);
				// cloth.SupportPose.Add("3000");
				// cloth.SupportPose.Add(EAvatarPose.Walk1_1);
				cloth.ClothClasses.SetType1(EClothClasses_Type1._衣服);
				cloth.ClothClasses.SetType2((short)EClothClasses_Type2_Cloth._套服);

				// cloth.SupportClothStatus.AdaptBody = (byte)EClothStatus_AdaptBody.Maid;
				// cloth.SupportClothStatus.Completeness = (byte)(EClothStatus_Completeness.Percent100 |
				//                                                EClothStatus_Completeness.Percent50 |
				//                                                EClothStatus_Completeness.Percent0);
				// cloth.SupportClothStatus.Style = (byte)EClothStatus_Style.Style0;

				cloth.BodySlotCost[cloth.ClothClasses.Hash] = 5;

				cloth.Name = "裙子" + i;
				cloth.Introduction = "裙子介绍";
				cloth.IconAssetId = i;
				
				PaletteParam setting1 = new PaletteParam();
				setting1.ElementIndex = -1;
				setting1.BasicColor = Colors.White;
				setting1.Tolerance = 30;
				setting1.ModulateColor = Colors.Red;
				setting1.BlendMode = 0;
				
				PaletteParam setting2 = new PaletteParam();
				setting2.ElementIndex = -1;
				setting2.BasicColor = new Color(1.0f, 1.0f, 0.0f, 1.0f);
				setting2.Tolerance = 30;
				setting2.ModulateColor = new Color(0.11f, 0.9f, 0.12f, 1.0f);
				setting2.BlendMode = 22;
				
				List<Palette> colorPalettes  = new List<Palette>();
				Palette  colorPalette = new Palette();
				colorPalette.Guid = BitConverter.ToUInt32(Guid.NewGuid().ToByteArray(), 0);
				colorPalette.Name = "原色";
				colorPalette.Introduction = "介绍";
				colorPalette.IconPaletteParams.Add(setting1);
				colorPalette.ElementPaletteParams.Add(setting1);
				colorPalette.ElementPaletteParams.Add(setting2);
				colorPalettes.Add(colorPalette);
				cloth.Palettes = colorPalettes;

				AvatarElement part = new AvatarElement();
				part.AssetId = i;
				part.Layer = i * 11;
				part.LayerOffset = -i;
				part.PositionX = i * 111;
				part.PositionY = -i * 111;
				part.Rotation = 103.5f;
				part.ScaleX = -1.0f;
				part.ScaleY = 2.5f;
				part.Skew = 1.0f;
				cloth.Elements["3000"] = new List<AvatarDoll.AvatarElement>();
				cloth.Elements["3000"].Add(part);
				
				// ClothStatus state = new ClothStatus(EClothStatus_AdaptBody.Maid, EClothStatus_Style.Style0,
				// 	EClothStatus_Completeness.Percent100);
				// cloth.PoseSet[state.Hash] = elementSet;
				data.Clothes.Add(cloth);
			}
		}

		// 序列化测试
		string jsonString = JsonSerializer.Serialize<AvatarDollData>(data);
		GD.Print("AvatarDollData json: \n" + jsonString);
		
		// 反序列化
		AvatarDollData deData = JsonSerializer.Deserialize<AvatarDollData>(jsonString);
		
		// 反序列化校验
		bool equal = true;
		{
			equal &= deData.FormatVersion == data.FormatVersion;
			equal &= deData.Metadata.Equals(data.Metadata);

			equal &= deData.AssetMap.Count == data.AssetMap.Count;
			equal &= deData.AssetMap.OrderBy(kv => kv.Key).SequenceEqual(data.AssetMap.OrderBy(kv => kv.Key));

			equal &= deData.Bodies.Count == data.Bodies.Count;
			for (int i = 0; i < data.Bodies.Count; ++i)
				equal &= deData.Bodies[i].Equals(data.Bodies[i]);
			
			equal &= deData.Faces.Count == data.Faces.Count;
			for (int i = 0; i < data.Faces.Count; ++i)
				equal &= deData.Faces[i].Equals(data.Faces[i]);

			equal &= deData.Hairs.Count == data.Hairs.Count;
			for (int i = 0; i < data.Hairs.Count; ++i)
				equal &= deData.Hairs[i].Equals(data.Hairs[i]);
			
			equal &= deData.Clothes.Count == data.Clothes.Count;
			for (int i = 0; i < data.Clothes.Count; ++i)
				equal &= deData.Clothes[i].Equals(data.Clothes[i]);
			
		}
		GD.Print("AvatarDollData Equal: " + equal);
	}

	public void AvatarProjectTest()
	{
		ProjectSettings settings = new ProjectSettings();
		
		PartState state1 = new PartState();
		state1.Name = "BodyType";
		state1.Scope = PartScope.All;
		state1.Default = 3;
		state1.Values = new List<string>() {"Chibi", "Kid", "Girl", "Maid", "Lady", "Miss" };
		state1.Required = new List<bool>() {false, false, false, true, false, false };
		settings.States.Add(state1);
		
		PartState state2 = new PartState();
		state2.Name = "Poses";
		state2.Scope = PartScope.All;
		state2.Default = 0;
		state2.Values = new List<string>() {"Stand_0", "Stand_1", "Stand_2" };
		state2.Required = new List<bool>() {true, true, true };
		settings.States.Add(state2);
		
		PartState state3 = new PartState();
		state3.Name = "ClothType";
		state3.Scope = PartScope.Cloth;
		state3.Default = 0;
		state3.Values = new List<string>() {"Normal", "LeftPart", "RightPart" };
		state3.Required = new List<bool>() {true, false, false };
		settings.States.Add(state3);
		
		PartState state4 = new PartState();
		state4.Name = "Completeness";
		state4.Scope = PartScope.Body | PartScope.Head | PartScope.Cloth;
		state4.Default = 0;
		state4.Values = new List<string>() {"DamageLevel0", "DamageLevel1", "DamageLevel2", "DamageLevel3" };
		state4.Required = new List<bool>() {true,false,false,false };
		settings.States.Add(state4);
		
		PartState state5 = new PartState();
		state5.Name = "Expression";
		state5.Scope = PartScope.Face;
		state5.Default = 0;
		state5.Values = new List<string>() {"Normal", "Happy", "Wink"};
		state5.Required = new List<bool>() {true,false,false };
		settings.States.Add(state5);
		
		// List<List<bool>> test_data = new()
		// {
		// 	new() { false, false, false, true, false, false },
		// 	new() { true, true, true },
		// 	new() { true, false, false },
		// 	new() { true, false, false, false },
		// 	new() { true, false, false }
		// };
		// int hash1 = AvatarDollProjectSettings.GetStatusesHashCode(settings);
		// int hash2 = AvatarDollProjectSettings.GetStatusesHashCode(test_data);
		//
		// GD.Print("States Hash Code Test"  );
		//
		// // GD.Print(hash1);
		// GD.Print(hash2);
		
		// 序列化测试
		string jsonString = JsonSerializer.Serialize<ProjectSettings>(settings);
		GD.Print("AvatarDollProjectSettings json: \n" + jsonString);
		GD.Print(ProjectSettings.GetStatusesCode(settings));
		// 反序列化
		ProjectSettings deData = JsonSerializer.Deserialize<ProjectSettings>(jsonString);
		
		GD.Print(settings.Equals(deData));
		
	}
}
