using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.ComponentModel;

namespace AssetBank.Editor.Data
{
    [Serializable]
    public class SceneData
    {
        // --- LEGEND ---
        // p: PrefabsInScene
        // h: Hierarchy

        [JsonProperty("p", NullValueHandling = NullValueHandling.Ignore)]
        public List<string> PrefabsInScene { get; set; } = new();

        [JsonProperty("h", NullValueHandling = NullValueHandling.Ignore)]
        public List<GameObjectData> Hierarchy { get; set; } = new();
        
        public bool ShouldSerializePrefabsInScene() => PrefabsInScene is { Count: > 0 };
        public bool ShouldSerializeHierarchy() => Hierarchy is { Count: > 0 };
    }

    [Serializable]
    public class GameObjectData
    {
        // --- LEGEND ---
        // e: Enabled
        // n: Name
        // t: Tag
        // l: Layer
        // a: AnchorId
        // pi: PrefabIndex
        // c: Components
        // ac: AddedComponents
        // rc: RemovedComponentAnchorIds
        // ch: Children

        [JsonProperty("e", DefaultValueHandling = DefaultValueHandling.Ignore)]
        [DefaultValue(true)]
        public bool Enabled { get; set; } = true;
        
        [JsonProperty("n")]
        public string Name { get; set;}
        
        [JsonProperty("t", DefaultValueHandling = DefaultValueHandling.Ignore)]
        [DefaultValue("Untagged")]
        public string Tag { get; set; } = "Untagged";
        
        [JsonProperty("l", DefaultValueHandling = DefaultValueHandling.Ignore)]
        [DefaultValue(0)]
        public int Layer { get; set; }
        
        [JsonProperty("a")]
        public string AnchorId { get; set;}
        
        [JsonProperty("pi", NullValueHandling = NullValueHandling.Ignore)]
        public int? PrefabIndex { get; set; }

        [JsonProperty("c", NullValueHandling = NullValueHandling.Ignore)]
        public List<ComponentData> Components { get; set; } = new();

        [JsonProperty("ac", NullValueHandling = NullValueHandling.Ignore)]
        public List<ComponentData> AddedComponents { get; set; } = new();

        [JsonProperty("rc", NullValueHandling = NullValueHandling.Ignore)]
        public List<string> RemovedComponentAnchorIds { get; set; } = new();

        [JsonProperty("ch", NullValueHandling = NullValueHandling.Ignore)]
        public List<GameObjectData> Children { get; set; } = new();
        
        public bool ShouldSerializeComponents() => Components is { Count: > 0 };
        public bool ShouldSerializeAddedComponents() => AddedComponents is { Count: > 0 };
        public bool ShouldSerializeRemovedComponentAnchorIds() => RemovedComponentAnchorIds is { Count: > 0 };
        public bool ShouldSerializeChildren() => Children is { Count: > 0 };
    }

    [Serializable]
    public class ComponentData
    {
        // --- LEGEND ---
        // t: Name (Type)
        // a: AnchorId
        // f: Fields (via JsonExtensionData)

        [JsonProperty("t")]
        public string Name { get; set; }
        
        [JsonProperty("a")]
        public string AnchorId { get; set; }
        
        [JsonProperty("f")]
        [JsonExtensionData]
        public IDictionary<string, JToken> Fields { get; set; } = new Dictionary<string, JToken>();
        
        public bool ShouldSerializeFields() => Fields is { Count: > 0 };
    }
}
