using System;
using UnityEngine;

namespace Escape_Room_Engine.Portal
{
    [RequireComponent(typeof(Collider), typeof(Rigidbody))]
    public class PortalDriver : MonoBehaviour
    {
        /// <summary>
        /// The object that will be transported through the portal. Usually either this object or a parent offset object.
        /// If left empty, it will default to this object.
        /// </summary>
        [SerializeField] private Transform traveller;

        /// <summary>
        /// The side of the portal this became tracked on.
        /// </summary>
        [HideInInspector] public int entrySide;
        
        /// <summary>
        /// A reference to the collider of this portal driver.
        /// </summary>
        public Collider Collider { get; private set; }

        private Rigidbody _rigidbody;

        private void Awake()
        {
            // check whether the collider is set up correctly
            Collider = GetComponent<Collider>();
            if (Collider.isTrigger) throw new Exception("Collider must not be a trigger.");
            
            // check whether the traveller is set
            if (!traveller) traveller = transform;
            
            // get the rigidbody if there is one
            _rigidbody = GetComponent<Rigidbody>();
        }

        public void Teleport(Portal from, Portal to)
        {
            var m = to.transform.localToWorldMatrix * Portal.HalfRotation * from.transform.worldToLocalMatrix *
                    traveller.localToWorldMatrix;
            traveller.transform.SetPositionAndRotation(m.GetPosition(), m.rotation);
            if (_rigidbody)
            {
                _rigidbody.velocity = to.transform.TransformDirection(
                    Portal.HalfRotation.rotation * from.transform.InverseTransformDirection(_rigidbody.velocity));
            }
        }
    }
}
