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

namespace LLM.Editor.Tests.Unit
{
    [TestFixture]
    public class RequestAnalysisContextCommandTests
    {
        private CommandContext _context;
        private bool _eventFired;
        private RequestAnalysisContextParams _receivedParams;

        [SetUp]
        public void SetUp()
        {
            _context = new CommandContext();
            _eventFired = false;
            _receivedParams = null;
            // Subscribe to the event before each test
            RequestAnalysisContextCommand.OnAnalysisContextRequested += HandleAnalysisContextRequested;
        }

        [TearDown]
        public void TearDown()
        {
            // Unsubscribe to prevent test pollution
            RequestAnalysisContextCommand.OnAnalysisContextRequested -= HandleAnalysisContextRequested;
        }

        private void HandleAnalysisContextRequested(RequestAnalysisContextParams parameters)
        {
            _eventFired = true;
            _receivedParams = parameters;
        }

        [Test]
        public void Execute_WithValidRoles_FiresEventWithCorrectParameters()
        {
            // Arrange
            var roles = new[] { "Character", "Weapon" };
            var parameters = new RequestAnalysisContextParams { subjectRoles = roles };
            var command = new RequestAnalysisContextCommand(parameters.ToJson());

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

            // Assert
            Assert.AreEqual(CommandOutcome.Success, outcome);
            Assert.IsTrue(_eventFired, "The OnAnalysisContextRequested event should have been fired.");
            Assert.IsNotNull(_receivedParams, "The received parameters should not be null.");
            Assert.IsTrue(roles.SequenceEqual(_receivedParams.subjectRoles), "The subject roles in the event should match the input.");
        }

        [Test]
        public void Execute_WithNullRoles_ReturnsErrorAndDoesNotFireEvent()
        {
            // Arrange
            var parameters = new RequestAnalysisContextParams { subjectRoles = null };
            var command = new RequestAnalysisContextCommand(parameters.ToJson());

            LogAssert.Expect(LogType.Error, "[RequestAnalysisContextCommand] Invalid parameters. Subject roles are required.");

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

            // Assert
            Assert.AreEqual(CommandOutcome.Error, outcome);
            Assert.IsFalse(_eventFired, "The OnAnalysisContextRequested event should not be fired for invalid parameters.");
        }

        [Test]
        public void Execute_WithEmptyRoles_ReturnsErrorAndDoesNotFireEvent()
        {
            // Arrange
            var parameters = new RequestAnalysisContextParams { subjectRoles = new string[0] };
            var command = new RequestAnalysisContextCommand(parameters.ToJson());

            LogAssert.Expect(LogType.Error, "[RequestAnalysisContextCommand] Invalid parameters. Subject roles are required.");

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

            // Assert
            Assert.AreEqual(CommandOutcome.Error, outcome);
            Assert.IsFalse(_eventFired, "The OnAnalysisContextRequested event should not be fired for empty roles.");
        }
    }
}
