using JetBrains.Annotations;
using LLM.Editor.Core;
using LLM.Editor.Helper;
using UnityEditor;
using UnityEngine;

namespace LLM.Editor.Commands
{
    [System.Serializable]
    public class SetHierarchyParams
    {
        public string childIdentifier;
        public string parentIdentifier; // null or empty indicates root
        public int siblingIndex = -1; // -1 indicates end of list
    }

    [UsedImplicitly]
    public class SetHierarchyCommand : ICommand
    {
        private readonly SetHierarchyParams _params;

        public SetHierarchyCommand(string jsonParams)
        {
            _params = jsonParams?.FromJson<SetHierarchyParams>();
        }

        public CommandOutcome Execute(Data.CommandContext context)
        {
            if (_params == null || string.IsNullOrEmpty(_params.childIdentifier))
            {
                context.ErrorMessage = "Invalid parameters: childIdentifier is required.";
                return CommandOutcome.Error;
            }

            var childObject = CommandUtility.ResolveIdentifier(context, _params.childIdentifier);
            if (childObject is not GameObject childGo)
            {
                context.ErrorMessage = $"Could not find a valid child GameObject with logical name: '{_params.childIdentifier}'";
                return CommandOutcome.Error;
            }

            Transform parentTransform = null;
            if (!string.IsNullOrEmpty(_params.parentIdentifier))
            {
                var parentObject = CommandUtility.ResolveIdentifier(context, _params.parentIdentifier);
                if (parentObject is not GameObject parentGo)
                {
                    context.ErrorMessage = $"Could not find a valid parent GameObject with logical name: '{_params.parentIdentifier}'";
                    return CommandOutcome.Error;
                }
                parentTransform = parentGo.transform;
            }
            
            Undo.SetTransformParent(childGo.transform, parentTransform, "Reparent GameObject");

            if (_params.siblingIndex > -1)
            {
                childGo.transform.SetSiblingIndex(_params.siblingIndex);
            }
            
            // Update the identifier map with the new path
            if (context.IdentifierMap.TryGetValue(_params.childIdentifier, out var pId))
            {
                pId.path = CommandUtility.GetGameObjectPath(childGo);
                SessionManager.SaveIdentifierMap(context.IdentifierMap);
                Debug.Log($"[SetHierarchyCommand] Set parent of '{childGo.name}' to '{(parentTransform ? parentTransform.name : "root")}'. Path updated to '{pId.path}'.");
            }
            else
            {
                Debug.LogWarning($"[SetHierarchyCommand] Could not find logical name '{_params.childIdentifier}' in map to update its path.");
            }

            return CommandOutcome.Success;
        }
    }
}
