using LLM.Editor.Commands;
using LLM.Editor.Data;
using NUnit.Framework;
using UnityEngine;

namespace LLM.Editor.Tests.Unit
{
    [TestFixture]
    public class SetProjectSettingValueCommandTests
    {
        private CommandContext _context;
        private float _originalFixedDeltaTime;

        [SetUp]
        public void SetUp()
        {
            _context = new CommandContext();
            _originalFixedDeltaTime = Time.fixedDeltaTime;
        }

        [TearDown]
        public void TearDown()
        {
            Time.fixedDeltaTime = _originalFixedDeltaTime;
        }

        [Test]
        public void Execute_SetsWritablePropertyCorrectly()
        {
            // Arrange
            var command = new SetProjectSettingValueCommand
            {
                apiClassName = "UnityEngine.Time",
                memberName = "fixedDeltaTime",
                value = 0.05
            };

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

            // Assert
            Assert.AreEqual(CommandOutcome.Success, result);
            Assert.AreEqual(0.05f, Time.fixedDeltaTime, 0.0001f);
        }

        [Test]
        public void Execute_WithInvalidApiClass_ReturnsError()
        {
            // Arrange
            var command = new SetProjectSettingValueCommand
            {
                apiClassName = "UnityEngine.NonExistentClass",
                memberName = "someMember",
                value = 123
            };

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

            // Assert
            Assert.AreEqual(CommandOutcome.Error, result);
            Assert.IsTrue(_context.ErrorMessage.Contains("Could not find a class"));
        }

        [Test]
        public void Execute_WithInvalidMember_ReturnsError()
        {
            // Arrange
            var command = new SetProjectSettingValueCommand
            {
                apiClassName = "UnityEngine.Time",
                memberName = "nonExistentMember",
                value = 123
            };

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

            // Assert
            Assert.AreEqual(CommandOutcome.Error, result);
            Assert.IsTrue(_context.ErrorMessage.Contains("Could not find a writable public static member"));
        }

        [Test]
        public void Execute_OnReadOnlyProperty_ReturnsError()
        {
            // Arrange
            var command = new SetProjectSettingValueCommand
            {
                apiClassName = "UnityEngine.Time",
                memberName = "time", // time is read-only
                value = 100f
            };

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

            // Assert
            Assert.AreEqual(CommandOutcome.Error, result);
            Assert.IsTrue(_context.ErrorMessage.Contains("is read-only"));
        }
    }
}
