#if USING_XRI

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.XR.Interaction.Toolkit.UI;
using System.Linq;
using Unity.XR.CoreUtils;
using UnityEngine.XR.Interaction.Toolkit;
using UnityEngine.UI;

namespace SimplifyXR
{

    public class XRIPanelConfiguration : IXRPanelConfig
    {
        public XRCompatibility Compatibility()
        {
            return XRCompatibility.XRI;
        }

        public void RemoveConfiguration(GameObject panel, XRPanelType panelType)
        {
            var canvas = panel.GetComponentInChildren<Canvas>();

            if (canvas != null)
            {
               
                var eventSystem = panel.GetComponentInChildren<EventSystem>();
                var xrui = eventSystem?.gameObject?.GetComponent<XRUIInputModule>();
                var trackedDeviceRaycaster = canvas.GetComponent<TrackedDeviceGraphicRaycaster>();

                if (xrui != null) MonoBehaviour.DestroyImmediate(xrui);
                if (trackedDeviceRaycaster != null) MonoBehaviour.DestroyImmediate(trackedDeviceRaycaster);

                var billboard = canvas.GetComponent<SimplifyXR.Billboard>();
                if (billboard != null) MonoBehaviour.DestroyImmediate(billboard);

                var xrorigin = Object.FindObjectOfType<XROrigin>();
                if (xrorigin != null)
                {
                    try
                    {
                        var es = xrorigin.gameObject.GetComponent<EventSystem>();
                        if (es != null && es.transform != xrorigin.transform) MonoBehaviour.DestroyImmediate(es);
                    }
                    catch (System.Exception e)
                    {

                    }
                   
                }

                var grabbable = canvas.gameObject.GetComponent<XRGrabInteractable>();
                var rb = canvas.gameObject.GetComponent<Rigidbody>();
                var bc = canvas.gameObject.GetComponent<BoxCollider>();

                if (grabbable != null) MonoBehaviour.DestroyImmediate(grabbable);
                if (rb != null) MonoBehaviour.DestroyImmediate(rb);
                if (bc) MonoBehaviour.DestroyImmediate(bc);

                RemoveInteractableButtons(canvas);
                UnconfigureSliders(canvas);
            }
        }

        public void RemoveConfiguration(List<Button> buttons)
        {
        }


        public void SetupEventSystems(GameObject panel)
        {


            var xrorigin = Object.FindObjectOfType<XROrigin>();
            var es = xrorigin.gameObject.GetOrAddNewComponent<EventSystem>();
            es.enabled = true;

            xrorigin?.gameObject?.GetOrAddNewComponent<XRUIInputModule>();
            var soi = panel?.gameObject?.GetComponentInChildren<StandaloneInputModule>();

            if (soi != null) MonoBehaviour.DestroyImmediate(soi);

            if (xrorigin != null)
            {
                var eventSystems = Object.FindObjectsOfType<EventSystem>();
                eventSystems.ToList().ForEach(es =>
                {
                    try
                    {
                        if(es.transform != xrorigin.transform) MonoBehaviour.DestroyImmediate(es);
                    }
                    catch (System.Exception e) { }
                });
            }

        }
    

        public void SetupConfiguration(GameObject panel, XRPanelType panelType)
        {
            var canvas = panel.GetComponentInChildren<Canvas>();

            if (canvas != null)
            {
                canvas.renderMode = RenderMode.WorldSpace;
                canvas.worldCamera = Camera.main;

                SetupEventSystems(panel);

                canvas.gameObject.GetOrAddNewComponent<SimplifyXR.Billboard>().PivotAxis = PivotAxis.Y;
                canvas.gameObject.GetOrAddNewComponent<TrackedDeviceGraphicRaycaster>();                


                var grabbable = canvas.gameObject.GetOrAddNewComponent<XRGrabInteractable>();
                var rb = canvas.gameObject.GetOrAddNewComponent<Rigidbody>();
                rb.isKinematic = true;
                var bc = canvas.gameObject.GetOrAddNewComponent<BoxCollider>();
                var rect = canvas.GetComponentInChildren<ElementRoot>().GetComponent<RectTransform>();

                grabbable.colliders.Clear();
                grabbable.colliders.Add(bc);

                SetBoxColliderToRectScale(bc, rect);
                SetupButtonsAsInteractable(canvas);
                SetupSliders(canvas);
            }

        }

        public void RemoveInteractableButtons(Canvas canvas)
        {
            var buttons = canvas.GetComponentsInChildren<Button>().ToList();
            buttons.ForEach(button =>
            {
                var bc = button.GetComponent<BoxCollider>();              
                var xs = button.GetComponent<XRISimpleInteractable>();
                var xcm = button.GetComponent<XRIClickMapping>();

                if (bc) MonoBehaviour.DestroyImmediate(bc);
                if (xs) MonoBehaviour.DestroyImmediate(xs);
                if (xcm) MonoBehaviour.DestroyImmediate(xcm);
            });
        }


        public void SetupButtonsAsInteractable(Canvas canvas)
        {
            var buttons = canvas.GetComponentsInChildren<Button>().ToList();
            buttons.ForEach(button =>
            {
                var bc = button.gameObject.GetOrAddNewComponent<BoxCollider>();
                var rect = button.GetComponent<RectTransform>();
                SetBoxColliderToRectScale(bc, rect, false);
                button.gameObject.GetOrAddNewComponent<XRISimpleInteractable>();
                button.gameObject.GetOrAddNewComponent<XRIClickMapping>();
            });
        }


        public void SetupSliders(Canvas canvas)
        {
            var sliders = canvas.GetComponentsInChildren<Slider>();
            sliders.ToList().ForEach(s => {
                s.gameObject.GetOrAddNewComponent<XRISliderMapping>();
            });
        }

        public void UnconfigureSliders(Canvas canvas)
        {
            var sliders = canvas.GetComponentsInChildren<Slider>();
            sliders.ToList().ForEach(s => {
                var sm = s.gameObject.GetComponent<XRISliderMapping>();
                if (sm) MonoBehaviour.DestroyImmediate(sm);
            });
        }


        public void SetBoxColliderToRectScale(BoxCollider collider, RectTransform rect, bool useLocalMutliplier = true) 
        {
            collider.size = new Vector3(
              rect.sizeDelta.x * (useLocalMutliplier ?
              rect.gameObject.transform.localScale.x : 1f),
              rect.sizeDelta.y *
              (useLocalMutliplier ? rect.gameObject.transform.localScale.y : 1),
              1
              );
        }


        public void SetupConfiguration(List<Button> buttons)
        {
        }
    }

}

#endif
