using NUnit.Framework;
using UnityEngine;
using UnityEditor;
using System.IO;
using LLM.Editor.Commands;
using LLM.Editor.Data;
using LLM.Editor.Helper;
using UnityEngine.TestTools;

namespace LLM.Editor.Tests.Unit
{
    [TestFixture]
    public class EditScriptCommandTests
    {
        private const string TestScriptName = "TempEditTestScript.cs";
        private string _testScriptPath;
        private string _testScriptGuid;
        private CommandContext _context;

        [SetUp]
        public void SetUp()
        {
            _context = new CommandContext();
            _testScriptPath = Path.Combine(Application.dataPath, TestScriptName);
            
            // Create a dummy script file for testing
            File.WriteAllText(_testScriptPath, "public class OldContent {}");
            AssetDatabase.Refresh();
            _testScriptGuid = AssetDatabase.AssetPathToGUID($"Assets/{TestScriptName}");
            Assert.IsFalse(string.IsNullOrEmpty(_testScriptGuid), "Setup failed: Could not get GUID for test script.");
        }

        [TearDown]
        public void TearDown()
        {
            // Clean up the dummy script
            if (File.Exists(_testScriptPath))
            {
                File.Delete(_testScriptPath);
                File.Delete(_testScriptPath + ".meta");
                AssetDatabase.Refresh();
            }
        }

        [Test]
        public void Execute_WithValidInput_OverwritesScriptContent()
        {
            // Arrange
            var newContent = "public class NewContent {}";
            var parameters = new EditScriptParams { scriptIdentifier = _testScriptGuid, newScriptContent = newContent };
            var command = new EditScriptCommand(parameters.ToJson());

            // Act
            var outcome = command.Execute(_context);

            // Assert
            Assert.AreEqual(CommandOutcome.Success, outcome);
            var fileContent = File.ReadAllText(_testScriptPath);
            Assert.AreEqual(newContent, fileContent);
        }

        [Test]
        public void Execute_WithInvalidGuid_ReturnsError()
        {
            // Arrange
            var parameters = new EditScriptParams { scriptIdentifier = "InvalidGuid", newScriptContent = "some content" };
            var command = new EditScriptCommand(parameters.ToJson());

            LogAssert.Expect(LogType.Error, "[EditScriptCommand] Could not find a valid script with GUID 'InvalidGuid'.");

            // Act
            var outcome = command.Execute(_context);

            // Assert
            Assert.AreEqual(CommandOutcome.Error, outcome);
        }

        [Test]
        public void Execute_WithEmptyContent_ReturnsError()
        {
            // Arrange
            var parameters = new EditScriptParams { scriptIdentifier = _testScriptGuid, newScriptContent = "" };
            var command = new EditScriptCommand(parameters.ToJson());
            
            LogAssert.Expect(LogType.Error, "[EditScriptCommand] Invalid parameters. Script identifier and new content are required.");

            // Act
            var outcome = command.Execute(_context);

            // Assert
            Assert.AreEqual(CommandOutcome.Error, outcome);
        }
    }
}
