using System;
using UnityEngine;
using VOID.Generic.Objects.Abstract;
using VOID.Generic.Triggers;

namespace VOID.Generic.Turn
{
    public class TurnManagerArea : MonoBehaviour, IDynamicTrigger
    {
        private TurnManager _turnManager;
        private Transform _stickTo;

        public static TurnManagerArea BuildGameObject(TurnManager turnManager, Vector3 position, float sphereRadius)
            => BuildGameObject(turnManager, null, position, sphereRadius, default);

        public static TurnManagerArea BuildGameObject(TurnManager turnManager, Vector3 position, Vector3 boxExtents)
            => BuildGameObject(turnManager, null, position, default, boxExtents);

        public static TurnManagerArea BuildGameObject(TurnManager turnManager, Transform stickTo, float sphereRadius)
            => BuildGameObject(turnManager, stickTo, stickTo.position, sphereRadius, default);

        public static TurnManagerArea BuildGameObject(TurnManager turnManager, Transform stickTo, Vector3 boxExtents)
            => BuildGameObject(turnManager, stickTo, stickTo.position, default, boxExtents);

        private static TurnManagerArea BuildGameObject(
            TurnManager turnManager,
            Transform stickTo,
            Vector3 position,
            float? sphereRadius,
            Vector3? boxExtents)
        {
            var gameObject = new GameObject(nameof(TurnManagerArea));
            gameObject.transform.SetParent(turnManager.gameObject.transform, true);
            gameObject.transform.position = position;
            gameObject.layer = LayerManager.TriggerIndex;
            var turnManagerArea = gameObject.AddComponent<TurnManagerArea>();
            turnManagerArea._turnManager = turnManager;
            turnManagerArea._stickTo = stickTo;
            if (sphereRadius.HasValue)
            {
                var collider = gameObject.AddComponent<SphereCollider>();
                collider.radius = sphereRadius.Value;
                collider.isTrigger = true;
            }
            else if (boxExtents.HasValue)
            {
                var collider = gameObject.AddComponent<BoxCollider>();
                collider.size = boxExtents.Value * 2;
                collider.isTrigger = true;
            }
            else
            {
                throw new Exception($"{nameof(TurnManagerArea)}: one of arguments '{nameof(sphereRadius)}' or '{nameof(boxExtents)}' is required");
            }

            return turnManagerArea;
        }

        public void ChangeTurnManager(TurnManager turnManager)
        {
            _turnManager = turnManager;
            _stickTo = turnManager.transform;
            transform.parent = _stickTo;
        }

        private void FixedUpdate()
        {
            if (_stickTo) transform.position = _stickTo.transform.position;
        }

        public void OnObjectEnter(AbstractObject obj)
        {
            _turnManager.ObjectEnter(obj);
        }

        public void OnObjectExit(AbstractObject obj)
        {
        }
    }
}