using System;
using Movement;
using UnityEngine;

namespace Platforms
{
    public class MovingPlatform : MonoBehaviour, IMovement
    {
        public float xOffset;
        public float yOffset;
        public float speed;

        private Vector3 _originalPos;
        private Vector3 _futurePos;
        private const float VerificationOffset = 0.04f;

        private bool _goingToFuturePos;

        private Rigidbody2D _platformRigidbody;
        private CollisionChecker _movingPlatformTrigger;

        private void Awake()
        {
            _platformRigidbody = GetComponent<Rigidbody2D>();
            _movingPlatformTrigger = GetComponentInChildren<CollisionChecker>();
        }

        private void Start()
        {
            _originalPos = transform.position;
            _futurePos = new Vector3(_originalPos.x + xOffset, _originalPos.y + yOffset, _originalPos.z);
            _goingToFuturePos = true;
        }

        private void FixedUpdate()
        {
            if (!IsPaused)
                Move(BaseSpeed);
        }

        // PAUSING METHODS

        public bool IsPaused { get; private set; }

        public void Pause()
        {
            IsPaused = true;
            _platformRigidbody.simulated = !IsPaused;
        }

        public void Resume()
        {
            IsPaused = false;
            _platformRigidbody.simulated = !IsPaused;
        }

        // MOVEMENT METHODS

        public float BaseSpeed { get; set; }

        public void Move(float value)
        {
            //var position = transform.position;
            switch (_goingToFuturePos)
            {
                case true:
                    //_platformRigidbody.MovePosition(new Vector2(position.x + speed * GetDecision(xOffset),
                    //position.y + speed * GetDecision(yOffset)));

                    transform.position = Vector3.MoveTowards(transform.position, _futurePos, speed * Time.deltaTime);
                    if (Math.Abs(_futurePos.x - transform.position.x) < VerificationOffset &&
                        Math.Abs(_futurePos.y - transform.position.y) < VerificationOffset)
                        _goingToFuturePos = false;
                    break;
                case false:
                    //_platformRigidbody.MovePosition(new Vector2(position.x + speed * -GetDecision(xOffset),
                    //position.y + speed * -GetDecision(yOffset)));
                    transform.position = Vector3.MoveTowards(transform.position, _originalPos, speed * Time.deltaTime);
                    if (Math.Abs(_originalPos.x - transform.position.x) < VerificationOffset &&
                        Math.Abs(_originalPos.y - transform.position.y) < VerificationOffset)
                        _goingToFuturePos = true;
                    break;
            }
        }

        private static float GetDecision(float value)
        {
            switch (value)
            {
                case < 0:
                    return -1.0f;
                case > 0:
                    return 1.0f;
            }

            return 0.0f;
        }

        private void OnCollisionEnter2D(Collision2D other)
        {
            if (other.gameObject.CompareTag("Player"))
                other.transform.SetParent(transform);
        }

        private void OnCollisionExit2D(Collision2D other)
        {
            if (other.gameObject.CompareTag("Player"))
                other.transform.SetParent(null);
        }
    }
}
