using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using LLM.Editor.Data;

namespace LLM.Editor.Commands
{
    [Serializable]
    public class GetProjectSettingSchemaCommand : ICommand
    {
        public string apiClassName;

        public CommandOutcome Execute(CommandContext context)
        {
            if (string.IsNullOrEmpty(apiClassName))
            {
                context.ErrorMessage = "Error: 'apiClassName' is required (e.g., 'UnityEngine.Time', 'UnityEngine.QualitySettings').";
                return CommandOutcome.Error;
            }

            var type = FindType(apiClassName);
            if (type == null)
            {
                context.ErrorMessage = $"Error: Could not find a class named '{apiClassName}'. Please ensure you are using the full, case-sensitive name.";
                return CommandOutcome.Error;
            }

            var schema = new Dictionary<string, object>();

            var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Static);
            foreach (var prop in properties)
            {
                if (!prop.CanRead) continue;
                try
                {
                    schema[prop.Name] = new
                    {
                        type = prop.PropertyType.FullName,
                        value = prop.GetValue(null),
                        isReadOnly = !prop.CanWrite
                    };
                }
                catch { /* Ignore properties that throw exceptions on read */ }
            }

            var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static);
            foreach (var field in fields)
            {
                try
                {
                    schema[field.Name] = new
                    {
                        type = field.FieldType.FullName,
                        value = field.GetValue(null),
                        isReadOnly = field.IsInitOnly || field.IsLiteral
                    };
                }
                catch { /* Ignore fields that throw exceptions on read */ }
            }

            context.CurrentSubject = schema;
            return CommandOutcome.Success;
        }

        private Type FindType(string typeName)
        {
            return AppDomain.CurrentDomain.GetAssemblies()
                .Where(a => a.FullName.StartsWith("UnityEngine"))
                .SelectMany(a => a.GetTypes())
                .FirstOrDefault(t => t.FullName != null && t.FullName.Equals(typeName, StringComparison.OrdinalIgnoreCase));
        }
    }
}
