using Sirenix.OdinInspector.Editor.Validation;
using Sirenix.Utilities;
using UnityEngine;
using VOID.Editor.AttributeValidator;
using VOID.Generic.World;

[assembly: RegisterValidator(typeof(AreaValidator))]

namespace VOID.Editor.AttributeValidator
{
    public class AreaValidator : ValueValidator<Area>
    {
        protected override void Validate(ValidationResult result)
        {
            if (Value == null) return;
            
            // Validate only ASSET - skip scene
            if (!Value.gameObject.scene.path.IsNullOrWhitespace()) return;
            
            ValidateIsInComplexAreaPrefab(result);
            ValidatePosition(result);
        }

        private void ValidateIsInComplexAreaPrefab(ValidationResult result)
        {
            if (Value.transform.root.gameObject.GetComponent<ComplexArea>() == null)
            {
                result.AddError(
                    $"{nameof(Area)} needs to be placed inside prefab with component {nameof(ComplexArea)}!"
                );
            }
        }
        
        private void ValidatePosition(ValidationResult result)
        {
            var complexArea = Value.transform.root.gameObject.GetComponent<ComplexArea>();
            if (!complexArea) return;
            
            var relativePosition = complexArea.transform.position - Value.transform.position; 
            var xValid = relativePosition.x % Area.Size < Vector3.kEpsilon;
            var yValid = relativePosition.y % Area.Size < Vector3.kEpsilon;
            var zValid = relativePosition.z % Area.Size < Vector3.kEpsilon;
            if (!xValid || !yValid || !zValid)
            {
                result.AddError(
                    $"'{Value.name}' is placed in invalid position."
                    + $"\nRelative position to ComplexArea is {relativePosition} and is not dividable by {Area.Size}!"
                );
            }
        }
    }
}