using System.IO;
using System.Linq;
using System.Text;
// using Newtonsoft.Json;
using IntelligentProjectAnalyzer.Editor.DependencyViewer;
using IntelligentProjectAnalyzer.Helper;

namespace IntelligentProjectAnalyzer.Editor.Graphing
{
    public static class GraphJsonExporter
    {
        /// <summary>
        /// Exports the dependency and reference graph for a given asset as a compact JSON string.
        /// </summary>
        /// <param name="rootAssetGuid">The GUID of the asset to start the graph traversal from.</param>
        /// <param name="jsonOutput">The resulting JSON string if the export is successful.</param>
        /// <returns>True if the root asset exists and the graph was exported, otherwise false.</returns>
        public static bool TryExportAssetGraph(string rootAssetGuid, out string jsonOutput)
        {
            if (TryBuildGraph(rootAssetGuid, out var serializableGraph))
            {
                jsonOutput = JsonFileSystem.GetJson(serializableGraph);
                return true;
            }

            jsonOutput = null;
            return false;
        }

        /// <summary>
        /// Appends a human-readable representation of the asset's dependency graph to a StringBuilder.
        /// </summary>
        /// <param name="rootAssetGuid">The GUID of the asset to analyze.</param>
        /// <param name="builder">The StringBuilder to append the report to.</param>
        /// <returns>True if the root asset exists and the report was generated, otherwise false.</returns>
        public static bool TryAppendHumanReadableGraph(string rootAssetGuid, StringBuilder builder)
        {
            if (!TryBuildGraph(rootAssetGuid, out var graph))
            {
                return false;
            }

            if (graph.Nodes == null || graph.Links == null || !graph.Nodes.Any()) return true;
            
            var nodeMap = graph.Nodes
                .Select((node, index) => new { node, index })
                .ToDictionary(item => item.index, item => item.node);

            builder.AppendLine($"- Dependency Report for: {Path.GetFileName(nodeMap[0].Path)}");
            
            foreach (var link in graph.Links)
            {
                if (nodeMap.TryGetValue(link.Source, out var sourceNode) &&
                    nodeMap.TryGetValue(link.Target, out var targetNode))
                {
                    builder.AppendLine($"  - [{sourceNode.Type}] '{Path.GetFileName(sourceNode.Path)}' (Guid: {sourceNode.Guid}) -> USES -> [{targetNode.Type}] '{Path.GetFileName(targetNode.Path)}' (Guid: {targetNode.Guid})");
                }
            }
                
            builder.AppendLine("--- End of Report ---");
            return true;
        }

        /// <summary>
        /// Private helper to build the graph, shared by both export methods.
        /// </summary>
        private static bool TryBuildGraph(string rootAssetGuid, out SerializableGraph graph)
        {
            var dependencyGraph = new DependencyGraph();
            if (!dependencyGraph.AssetExists(rootAssetGuid))
            {
                graph = null;
                return false;
            }

            var graphBuilder = new GraphBuilder(dependencyGraph);
            graph = graphBuilder.BuildFromRoot(rootAssetGuid);
            return graph != null;
        }
    }
}
