using UnityEngine;
using UnityEditor;
using System.Linq;
using LLM.Editor.Core;
using LLM.Editor.Data;
using LLM.Editor.Helper;
using LLM.Editor.Commands;
using Newtonsoft.Json.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;

namespace LLM.Editor.Client
{
    /// <summary>
    /// A mock client that simulates an LLM response for testing purposes.
    /// It now reads from an external JSON file to handle complex, multi-step test cases.
    /// </summary>
    public class DummyApiClient : ILlmApiClient
    {
        [System.Serializable]
        private class CommandResponse { public List<CommandData> commands; }
        
        private static DummyTestCase _activeTestCase;
        private static int _activeResponseStep;

        public Task SendPrompt(string prompt, List<Object> stagedContext)
        {
            var responseSheet = LoadResponseSheet();
            if (responseSheet == null)
            {
                DisplayError("Could not load DummyResponses.json. Make sure it exists in a Resources folder.");
                return Task.CompletedTask;
            }

            // Find a test case whose trigger phrase is in the user's prompt.
            _activeTestCase = responseSheet.testCases.FirstOrDefault(
                c => prompt.ToLower().Contains(c.triggerPhrase.ToLower())
            );

            if (_activeTestCase != null)
            {
                Debug.Log($"[DummyApiClient] Triggered test case for: '{_activeTestCase.triggerPhrase}'");
                _activeResponseStep = 0; // Start at the first response
                ExecuteStep();
            }
            else
            {
                // Fallback to a default response if no test case matches.
                ExecuteCommandsFromJson(GetDefaultResponse());
            }

            return Task.CompletedTask;
        }

        public Task SendFollowUp(string detailedContext)
        {
            if (_activeTestCase != null)
            {
                _activeResponseStep++; // Move to the next response
                Debug.Log($"[DummyApiClient] Executing follow-up step #{_activeResponseStep + 1} for test case: '{_activeTestCase.triggerPhrase}'");
                ExecuteStep();
            }
            else
            {
                Debug.LogWarning("[DummyApiClient] Received a follow-up call, but no active test case was found.");
                ExecuteCommandsFromJson(GetDefaultResponse());
            }

            return Task.CompletedTask;
        }
        
        private static void ExecuteStep()
        {
            if (_activeTestCase?.responses == null || _activeResponseStep >= _activeTestCase.responses.Count)
            {
                Debug.Log("[DummyApiClient] Test case finished or has no more steps.");
                _activeTestCase = null; // End the test case
                return;
            }
            
            var jsonResponse = _activeTestCase.responses[_activeResponseStep];
            ExecuteCommandsFromJson(jsonResponse);
        }

        private static void ExecuteCommandsFromJson(string json)
        {
            var commandResponse = json.FromJson<CommandResponse>();
            if (commandResponse?.commands != null)
            {
                CommandExecutor.SetQueue(commandResponse.commands);
                CommandExecutor.ExecuteNextCommand();
            }
            else
            {
                DisplayError($"Failed to parse command structure from dummy JSON response: {json}");
            }
        }

        private static DummyResponseSheet LoadResponseSheet()
        {
            TextAsset textAsset;
            var allMatches = AssetDatabase.FindAssets("t:textasset DummyResponses");
            foreach (var match in allMatches)
            {
                var path = AssetDatabase.GUIDToAssetPath(match);
                textAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(path);
                if (textAsset)
                {
                    return textAsset.text.FromJson<DummyResponseSheet>();
                }
            }
            textAsset = Resources.Load<TextAsset>($"DummyResponses");
            return !textAsset ? null : textAsset.text.FromJson<DummyResponseSheet>();
        }

        private static void DisplayError(string message)
        {
            var errorParams = new DisplayMessageParams { outcome = CommandOutcome.Error, message = $"[Dummy Client Error] {message}" };
            var commandData = new CommandData { commandName = nameof(DisplayMessageCommand), jsonData = new JObject(errorParams) };
            CommandExecutor.SetQueue(new List<CommandData> { commandData });
            CommandExecutor.ExecuteNextCommand();
        }

        private static string GetDefaultResponse()
        {
            return @"{
                ""commands"": [
                    {
                        ""commandName"": ""DisplayMessageCommand"",
                        ""jsonData"": {
                            ""outcome"": ""Success"",
                            ""message"": ""[Dummy] No specific test case was triggered by your prompt.""
                        }
                    }
                ]
            }";
        }
    }
}
