using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Unity.XR.CoreUtils;
using UnityEngine;
using UnityEngine.XR;
using UnityEngine.XR.Interaction.Toolkit;

public class StencilPortal : MonoBehaviour
{
    public bool destroyAfterTeleport;
    public StencilPortal targetPortal;
    public Transform normalVisible;
    public Transform normalInvisible;
    public LayerMask defaultLayer;
    public LayerMask portalLayer;
    public PortalScene portalScene;
    public OcclusionPortal occlusionPortal;

    public bool _shouldTeleport;

    public TeleportationProvider teleportationProvider; // Reference to TeleportationProvider

    public static Vector3 TransformPositionBetweenPortals(StencilPortal sender, StencilPortal target, Vector3 position)
    {
        return target.normalInvisible.TransformPoint(sender.normalVisible.InverseTransformPoint(position));
    }

    public static Quaternion TransformRotationBetweenPortals(StencilPortal sender, StencilPortal target, Quaternion rotation)
    {
        return target.normalInvisible.rotation * Quaternion.Inverse(sender.normalVisible.rotation) * rotation;
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.GetComponent<XROrigin>() == null) return;

        if (occlusionPortal != null)
        {
            occlusionPortal.open = !occlusionPortal.open;
        }

        if (!_shouldTeleport)
        {
            if (destroyAfterTeleport)
            {
                Destroy(gameObject, 0.5f);
            }
            return;
        }

        Debug.Log(transform.name + " player entered and should teleport");
        targetPortal._shouldTeleport = false;

        if (teleportationProvider != null)
        {
            Vector3 targetPosition = TransformPositionBetweenPortals(this, targetPortal, other.transform.position);
            Quaternion targetRotation = TransformRotationBetweenPortals(this, targetPortal, other.transform.rotation);

            TeleportRequest request = new TeleportRequest
            {
                destinationPosition = targetPosition,
                destinationRotation = targetRotation,
                matchOrientation = MatchOrientation.TargetUpAndForward
            };

            teleportationProvider.QueueTeleportRequest(request);
            other.transform.rotation = TransformRotationBetweenPortals(this, targetPortal, other.transform.rotation);
        }
        else
        {
            Debug.LogWarning("TeleportationProvider is not assigned!", this);
            other.transform.position = TransformPositionBetweenPortals(this, targetPortal, other.transform.position);
            other.transform.rotation = TransformRotationBetweenPortals(this, targetPortal, other.transform.rotation);
        }

        if (destroyAfterTeleport)
        {
            Destroy(gameObject, 0.5f);
        }
    }

    private void OnTriggerExit(Collider other)
    {
        AllowTeleport();
        if (!_shouldTeleport || IsInvoking(nameof(AllowTeleport))) return;
        if (!other.CompareTag("Player")) return;
        Debug.Log(transform.name + " player exited");
        Invoke(nameof(AllowTeleport), 1f);
    }

    private void AllowTeleport()
    {
        _shouldTeleport = true;
    }

    public StencilPortal TargetPortal => targetPortal;
    public LayerMask DefaultLayer => defaultLayer;
    public LayerMask PortalLayer => portalLayer;
}