using System;
using Newtonsoft.Json;
using System.Collections.Generic;
using UnityEngine;

namespace IntelligentProjectAnalyzer.Editor
{
    /// <summary>
    /// Contains all the data structures and models used throughout the dependency build process.
    /// </summary>
    public static class DependencyBuilderData
    {
        /// <summary>
        /// A helper class to map concrete AssetMetadata types to a stable integer index.
        /// </summary>
        public static class MetadataTypeHelper
        {
            // This list defines the stable mapping. Order is important.
            private static readonly List<Type> Types = new()
            {
                typeof(ScriptMetadata),
                typeof(PrefabMetadata),
                typeof(SceneMetadata),
                typeof(ScriptableObjectMetadata),
                typeof(MiscAssetMetadata),
            };

            public static int GetIndexFromType(Type type) => Types.IndexOf(type);
            
            public static Type GetTypeFromIndex(int index) => (index >= 0 && index < Types.Count) ? Types[index] : null;
        }
        
        public class RoslynSetupData
        {
            public string[] SourceFiles { get; set; }
            public string[] References { get; set; }
            public string[] PreprocessorSymbols { get; set; }
            public Dictionary<string, string> TypeToGuidMap { get; set; }
            public List<string> SystemTypePrefixes { get; set; }
        }
        
        /// <summary>
        /// A serializable wrapper to store the concrete type and JSON data of our
        /// abstract AssetMetadata objects. This allows for correct deserialization.
        /// </summary>
        [Serializable]
        public class MetadataWrapper
        {
            public int AssetTypeIndex { get; set; }
            public string JsonData { get; set; }
        }
        
        /// <summary>
        /// The base class for all asset metadata. It is now the primary serializable object
        /// and contains the list of direct dependencies for the asset.
        /// </summary>
        [Serializable]
        public abstract class AssetMetadata
        {
            public string Guid { get; set; }
            public List<string> DependencyGuids { get; set; } = new();
        }

        /// <summary>
        /// Metadata for a C# script. Its DependencyGuids will be populated by Roslyn analysis.
        /// </summary>
        [Serializable]
        public class ScriptMetadata : AssetMetadata
        {
            [JsonIgnore]
            public string FullPath { get; set; }
        }

        /// <summary>
        /// Metadata for a Prefab. Its DependencyGuids will contain the GUIDs of all scripts attached as components.
        /// </summary>
        [Serializable]
        public class PrefabMetadata : AssetMetadata { }

        /// <summary>
        /// Metadata for a ScriptableObject. Its DependencyGuids will contain the GUID of its backing script.
        /// </summary>
        [Serializable]
        public class ScriptableObjectMetadata : AssetMetadata { }
        
        /// <summary>
        /// Metadata for scene.Its DependencyGuids will contain the GUIDs of all scripts attached as components.
        /// </summary>
        [Serializable]
        public class SceneMetadata : AssetMetadata { }
        
        [Serializable]
        public class MiscAssetMetadata : AssetMetadata { }
    }
}