using System;
using UnityEngine;
using UnityEditor;
using NUnit.Framework;
using LLM.Editor.Analysis;
using System.Collections.Generic;
using Object = UnityEngine.Object;

namespace LLM.Editor.Tests.Unit
{
    [TestFixture]
    public class SelectionProviderTests
    {
        private GameObject _testSceneObject;

        [SetUp]
        public void SetUp()
        {
            _testSceneObject = new GameObject("TestSceneObject");
        }

        [TearDown]
        public void TearDown()
        {
            if (_testSceneObject != null)
            {
                Object.DestroyImmediate(_testSceneObject);
            }
            // Clear selection to ensure no pollution between tests
            Selection.objects = Array.Empty<Object>();
        }

        [Test]
        public void GetContext_WithNoSelection_ReturnsStringMessage()
        {
            // Arrange
            Selection.objects = Array.Empty<Object>();
            var provider = new SelectionProvider();

            // Act
            var context = provider.GetContext(null, null);

            // Assert
            Assert.IsInstanceOf<string>(context);
            Assert.AreEqual("No objects are currently selected in the editor.", context);
        }

        [Test]
        public void GetContext_WithSceneObjectSelected_ReturnsCorrectData()
        {
            // Arrange
            Selection.activeObject = _testSceneObject;
            var provider = new SelectionProvider();

            // Act
            var context = provider.GetContext(null, null);

            // Assert
            Assert.IsInstanceOf<List<SelectionProvider.SelectionResult>>(context);
            var results = (List<SelectionProvider.SelectionResult>)context;
            Assert.AreEqual(1, results.Count);

            var result = results[0];
            Assert.AreEqual("TestSceneObject", result.name);
            Assert.AreEqual(_testSceneObject.GetInstanceID().ToString(), result.id);
            Assert.AreEqual("UnityEngine.GameObject", result.type);
            Assert.IsTrue(result.isSceneObject);
            Assert.IsNull(result.assetPath);
        }

        [Test]
        public void GetContext_WithAssetSelected_ReturnsCorrectData()
        {
            // Arrange
            var guids = AssetDatabase.FindAssets("t:ScriptableObject AnalyzerSettings");
            Assume.That(guids, Is.Not.Empty, "Required 'AnalyzerSettings.asset' not found for test.");
            var path = AssetDatabase.GUIDToAssetPath(guids[0]);
            var asset = AssetDatabase.LoadAssetAtPath<Object>(path);
            Selection.activeObject = asset;
            
            var provider = new SelectionProvider();

            // Act
            var context = provider.GetContext(null, null);

            // Assert
            Assert.IsInstanceOf<List<SelectionProvider.SelectionResult>>(context);
            var results = (List<SelectionProvider.SelectionResult>)context;
            Assert.AreEqual(1, results.Count);

            var result = results[0];
            Assert.AreEqual("AnalyzerSettings", result.name);
            Assert.AreEqual(guids[0], result.id);
            Assert.AreEqual("IntelligentProjectAnalyzer.Analyzer.AnalyzerSettings", result.type);
            Assert.IsFalse(result.isSceneObject);
            Assert.AreEqual(path, result.assetPath);
        }
    }
}