using UnityEngine;
using UnityEditor;
using System.IO;
using UniHumanoid;
using UniGLTF;

[System.Serializable]
public class HumanPoseData
{
    public Vector3 bodyPosition;
    public Quaternion bodyRotation;
    public float[] muscles;
}

public class HumanPoseClipApplier : EditorWindow
{
    private Animator targetAnimator;
    private HumanPoseClip poseClip;
    private string jsonPath;
    private bool useJsonFile = false;

    [MenuItem("Tools/Animation/Apply Human Pose Clip")]
    public static void ShowWindow()
    {
        GetWindow<HumanPoseClipApplier>("Human Pose Clip Applier");
    }

    private void OnGUI()
    {
        GUILayout.Label("Apply Human Pose Clip to Animator", EditorStyles.boldLabel);
        
        EditorGUILayout.Space();
        
        targetAnimator = (Animator)EditorGUILayout.ObjectField("Target Animator", targetAnimator, typeof(Animator), true);
        
        EditorGUILayout.Space();
        
        useJsonFile = EditorGUILayout.Toggle("Use JSON File", useJsonFile);
        
        if (useJsonFile)
        {
            EditorGUILayout.BeginHorizontal();
            jsonPath = EditorGUILayout.TextField("JSON File Path", jsonPath);
            if (GUILayout.Button("Browse", GUILayout.Width(60)))
            {
                string path = EditorUtility.OpenFilePanel("Select JSON File", "", "json");
                if (!string.IsNullOrEmpty(path))
                {
                    jsonPath = path;
                }
            }
            EditorGUILayout.EndHorizontal();
        }
        else
        {
            poseClip = (HumanPoseClip)EditorGUILayout.ObjectField("Pose Clip", poseClip, typeof(HumanPoseClip), false);
        }
        
        EditorGUILayout.Space();
        
        bool canApply = targetAnimator != null && 
                       ((useJsonFile && !string.IsNullOrEmpty(jsonPath)) || (!useJsonFile && poseClip != null));
        GUI.enabled = canApply;
        if (GUILayout.Button("Apply Pose Clip"))
        {
            ApplyPoseClip();
        }
        GUI.enabled = true;
    }

    private void ApplyPoseClip()
    {
        if (targetAnimator == null)
        {
            EditorUtility.DisplayDialog("Error", "Please select an Animator!", "OK");
            return;
        }

        HumanPose pose;
        if (useJsonFile)
        {
            if (string.IsNullOrEmpty(jsonPath) || !File.Exists(jsonPath))
            {
                EditorUtility.DisplayDialog("Error", "Please select a valid JSON file!", "OK");
                return;
            }
            // JSON 파일에서 데이터 로드
            string jsonContent = File.ReadAllText(jsonPath);
            HumanPoseData poseData = JsonUtility.FromJson<HumanPoseData>(jsonContent);
            
            // HumanPose로 변환
            pose = new HumanPose
            {
                bodyPosition = poseData.bodyPosition,
                bodyRotation = poseData.bodyRotation,
                muscles = poseData.muscles
            };
        }
        else if (poseClip != null)
        {
            pose = poseClip.GetPose();
        }
        else
        {
            EditorUtility.DisplayDialog("Error", "Please select a Pose Clip!", "OK");
            return;
        }

        var animator = targetAnimator;
        var avatar = animator.avatar;
        
        if (avatar == null || !avatar.isHuman)
        {
            EditorUtility.DisplayDialog("Error", "Selected Animator must have a Humanoid Avatar!", "OK");
            return;
        }

        try
        {
            // HumanPoseHandler를 사용하여 포즈 데이터 적용
            var handler = new HumanPoseHandler(avatar, animator.transform);
            
            // 포즈 적용
            handler.SetHumanPose(ref pose);

            // 변경사항 저장
            EditorUtility.SetDirty(animator);
            
            Debug.Log("Pose clip has been applied to the Animator");
            EditorUtility.DisplayDialog("Success", "Pose clip has been applied to the Animator", "OK");
        }
        catch (System.Exception e)
        {
            Debug.LogError($"Error applying pose clip: {e.Message}");
            EditorUtility.DisplayDialog("Error", $"Failed to apply pose clip: {e.Message}", "OK");
        }
    }
} 