fix all weaknesses, odd logic, horrible methods and more

using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class UICollisionInstantiate : MonoBehaviour
{
    [Header("Target UI Image to detect collision with")]
    public RectTransform targetRectTransform;

    [Header("Prefab to instantiate")]
    public GameObject prefabToInstantiate;

    [Header("Parent Transform for instantiated prefab")]
    public Transform prefabParentTransform;

    private RectTransform rectTransform;

    // Variables to store original transform and hierarchy information
    private Vector3 originalLocalPosition;
    private Quaternion originalLocalRotation;
    private Vector3 originalLocalScale;
    private Transform originalParent;
    private int originalSiblingIndex;
    public TMP_InputField LyricsInput;

    // Flag to ensure the instantiation and reset only happens once per overlap
    private bool hasInstantiatedAndReturned = false;

    void Awake()
    {
        rectTransform = GetComponent<RectTransform>();

        if (rectTransform == null)
        {
            Debug.LogError("This script must be attached to a GameObject with a RectTransform.");
            enabled = false;
            return;
        }

        if (targetRectTransform == null)
        {
            Debug.LogError("Target RectTransform is not assigned.");
            enabled = false;
            return;
        }

        if (prefabToInstantiate == null)
        {
            Debug.LogError("Prefab to instantiate is not assigned.");
            enabled = false;
            return;
        }

        if (prefabParentTransform == null)
        {
            Debug.LogWarning("Prefab parent transform is not assigned. Using current object's parent.");
            prefabParentTransform = transform.parent;
        }

        // Save initial transform and hierarchy info
        originalLocalPosition = transform.localPosition;
        originalLocalRotation = transform.localRotation;
        originalLocalScale = transform.localScale;
        originalParent = transform.parent;
        originalSiblingIndex = transform.GetSiblingIndex();
    }

    void Update()
    {
        if (!hasInstantiatedAndReturned && IsRectTransformOverlapping(rectTransform, targetRectTransform))
        {
            // Instantiate the prefab
            GameObject ICO = Instantiate(prefabToInstantiate, prefabParentTransform);
            Image icoImage = ICO.GetComponent<Image>();

            if (icoImage != null)
            {
                Image originalImage = gameObject.GetComponent<Image>();
                if (originalImage != null)
                {
                    icoImage.sprite = originalImage.sprite;
                }
            }
            ICO.name = gameObject.name;

            string[] allowedNames = { "Male Singer", "Female Singer" };
            if (System.Array.Exists(allowedNames, n => n == gameObject.name))
            {
                LyricsInput.gameObject.SetActive(true);
            }

            // Reset this object's transform and hierarchy info
            transform.SetParent(originalParent);
            transform.SetSiblingIndex(originalSiblingIndex);
            transform.localPosition = originalLocalPosition;
            transform.localRotation = originalLocalRotation;
            transform.localScale = originalLocalScale;

            // Disable the GameObject
            gameObject.SetActive(false);

            hasInstantiatedAndReturned = true;
        }
    }

    // Checks if two UI RectTransforms overlap
    public static bool IsRectTransformOverlapping(RectTransform rect1, RectTransform rect2)
    {
        Rect rectA = GetScreenRect(rect1);
        Rect rectB = GetScreenRect(rect2);

        return rectA.Overlaps(rectB);
    }

    // Convert RectTransform to Screen Space Rect
    public static Rect GetScreenRect(RectTransform rectTransform)
    {
        Vector3[] corners = new Vector3[4];
        rectTransform.GetWorldCorners(corners);

        // Bottom-left and top-right corners in screen space
        Vector3 bottomLeft = RectTransformUtility.WorldToScreenPoint(null, corners[0]);
        Vector3 topRight = RectTransformUtility.WorldToScreenPoint(null, corners[2]);

        return new Rect(bottomLeft, topRight - bottomLeft);
    }
}