#nullable enable

using UnityEngine;

namespace UVC.Extension
{
    /// <summary>
    /// Transform 클래스에 대한 확장 메소드를 제공하는 정적 클래스입니다.
    /// </summary>
    public static class TransformEx
    {
        /// <summary>
        /// 하위 자식까지 재귀적으로 확인해서 이름이 같은 오브젝트를 찾는다.
        /// </summary>
        /// <param name="t">검색을 시작할 부모 Transform</param>
        /// <param name="name">찾고자 하는 자식 GameObject의 이름</param>
        /// <returns>찾은 자식 Transform 또는 찾지 못한 경우 null</returns>
        /// <example>
        /// <code>
        /// // 사용 예시
        /// Transform parentTransform = gameObject.transform;
        /// Transform childTransform = parentTransform.FindChildren("TargetChild");
        /// 
        /// if (childTransform != null)
        /// {
        ///     // 찾은 자식 오브젝트 사용
        ///     childTransform.gameObject.SetActive(true);
        /// }
        /// </code>
        /// </example>
        public static Transform? FindChildren(this Transform t, string name)
        {

            Transform? child = null;

            int len = t.childCount;
            for (int i = 0; i < len; i++)
            {
                Transform c = t.GetChild(i);
                if (c.name == name)
                {
                    child = c;
                    break;
                }
                else
                {
                    Transform? result = FindChildren(c, name);
                    if (result != null)
                    {
                        child = result;
                        break;
                    }
                }
            }

            return child;
        }

        /// <summary>
        /// Transform의 X 좌표만 변경합니다.
        /// </summary>
        /// <param name="t">대상 Transform</param>
        /// <param name="x">설정할 X 좌표 값</param>
        /// <returns>변경된 Transform (메소드 체이닝 지원)</returns>
        /// <example>
        /// <code>
        /// // 사용 예시
        /// transform.SetPositionX(5f).SetPositionZ(3f);
        /// </code>
        /// </example>
        public static Transform SetPositionX(this Transform t, float x)
        {
            Vector3 position = t.position;
            position.x = x;
            t.position = position;
            return t;
        }

        /// <summary>
        /// Transform의 Y 좌표만 변경합니다.
        /// </summary>
        /// <param name="t">대상 Transform</param>
        /// <param name="y">설정할 Y 좌표 값</param>
        /// <returns>변경된 Transform (메소드 체이닝 지원)</returns>
        /// <example>
        /// <code>
        /// // 사용 예시
        /// transform.SetPositionY(5f).SetPositionZ(3f);
        /// </code>
        /// </example>
        public static Transform SetPositionY(this Transform t, float y)
        {
            Vector3 position = t.position;
            position.y = y;
            t.position = position;
            return t;
        }

        /// <summary>
        /// Transform의 Z 좌표만 변경합니다.
        /// </summary>
        /// <param name="t">대상 Transform</param>
        /// <param name="z">설정할 Z 좌표 값</param>
        /// <returns>변경된 Transform (메소드 체이닝 지원)</returns>
        /// <example>
        /// <code>
        /// // 사용 예시
        /// transform.SetPositionX(5f).SetPositionZ(3f);
        /// </code>
        /// </example>
        public static Transform SetPositionZ(this Transform t, float z)
        {
            Vector3 position = t.position;
            position.z = z;
            t.position = position;
            return t;
        }

        /// <summary>
        /// 하위 자식 중에서 특정 태그를 가진 오브젝트를 모두 찾습니다.
        /// </summary>
        /// <param name="t">검색을 시작할 부모 Transform</param>
        /// <param name="tag">찾고자 하는 태그</param>
        /// <returns>찾은 Transform 배열</returns>
        /// <example>
        /// <code>
        /// // 사용 예시
        /// Transform[] enemies = parentTransform.FindChildrenWithTag("Enemy");
        /// foreach (Transform enemy in enemies)
        /// {
        ///     // 찾은 적 오브젝트 처리
        ///     enemy.gameObject.SetActive(false);
        /// }
        /// </code>
        /// </example>
        public static Transform[] FindChildrenWithTag(this Transform t, string tag)
        {
            System.Collections.Generic.List<Transform> result = new System.Collections.Generic.List<Transform>();
            FindChildrenWithTagRecursive(t, tag, result);
            return result.ToArray();
        }

        private static void FindChildrenWithTagRecursive(Transform parent, string tag, System.Collections.Generic.List<Transform> result)
        {
            int childCount = parent.childCount;
            for (int i = 0; i < childCount; i++)
            {
                Transform child = parent.GetChild(i);
                if (child.CompareTag(tag))
                {
                    result.Add(child);
                }

                FindChildrenWithTagRecursive(child, tag, result);
            }
        }

        /// <summary>
        /// Transform을 기본 상태로 초기화합니다. (위치: 원점, 회전: 0, 크기: 1)
        /// </summary>
        /// <param name="t">초기화할 Transform</param>
        /// <returns>초기화된 Transform (메소드 체이닝 지원)</returns>
        /// <example>
        /// <code>
        /// // 사용 예시
        /// transform.ResetTransform();
        /// </code>
        /// </example>
        public static Transform ResetTransform(this Transform t)
        {
            t.localPosition = Vector3.zero;
            t.localRotation = Quaternion.identity;
            t.localScale = Vector3.one;
            return t;
        }

    }
}
