using System;
using Sirenix.OdinInspector;
using UnityEngine;

namespace VOID.Generic.AreaOfEffect
{
    [Serializable]
    public abstract class AbstractAreaOfEffect
    {
        [SerializeField] private bool fixedRotation;
        [SerializeField] [MinValue(-180), MaxValue(180)] private float offsetRotation;

        /// <summary>
        /// Calculates final rotation that include AOE offset rotation and/or fixed rotation.
        /// </summary>
        /// <param name="from">Position on AOE collider</param>
        /// <param name="to">Position where AOE collider should look</param>
        /// <returns>Quaternion to put into tranform.rotation</returns>
        public Quaternion GetRotation(Vector3 from, Vector3 to)
        {
            // Ignore look angle, we use only offset rotation
            if (fixedRotation) return Quaternion.Euler(new Vector3(0, offsetRotation, 0));
            
            // Include offset rotation into look rotation
            var directionNormalized = (new Vector2(to.x, to.z) - new Vector2(from.x, from.z)).normalized;
            var lookAngleY = Vector2.SignedAngle(Vector2.up, directionNormalized) * -1;
            return Quaternion.Euler(new Vector3(0, lookAngleY + offsetRotation, 0));
        }

        /// <summary>
        /// Returns mesh of this area of effect.
        /// </summary>
        public abstract Mesh GetMesh();
        
        /// <summary>
        /// Adds prepared collider to given GameObject.
        /// </summary>
        public abstract Collider AddCollider(GameObject gameObject);
    }
}