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

[assembly: RegisterValidator(typeof(ComplexAreaValidator))]

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

        private void ValidateIsInRootPrefab(ValidationResult result)
        {
            var prefabRoot = Value.transform.root.gameObject;
            if (prefabRoot != Value.gameObject)
            {
                result.AddError($"{nameof(ComplexArea)} is not in prefab root!");
            }
        }

        private void ValidatePosition(ValidationResult result)
        {
            if (Value.gameObject.transform.localPosition != Vector3.zero)
            {
                result.AddError($"{nameof(ComplexArea)}'s position in prefab must be {Vector3.zero}!");
            }
        }

        private void ValidateIsAtLeastOneAreaDefined(ValidationResult result)
        {
            var areas = Value.areas;

            if (areas.IsNullOrEmpty())
            {
                result.AddError($"{nameof(ComplexArea)} does not have any {nameof(Area)} defined!");
            }
        }

        private void ValidateAreAllAreasHandled(ValidationResult result)
        {
            var areas = Value.areas;
            var areasInPrefab = Value.transform.root.GetComponentsInChildren<Area>().ToList();
            var areasDiff = areasInPrefab.Except(areas).ToList();
            
            if (!areasDiff.IsNullOrEmpty())
            {
                result.AddError($"{nameof(ComplexArea)} does not contain all {nameof(Area)} defined in this prefab!");
            }
        }
    }
}