using System;
using System.Text;
using Schema;
using Sirenix.OdinInspector;
using UnityEngine;
using VOID.Generic.Dict;
using VOID.Generic.Objects.Unit;

namespace VOID.Generic.AI.Schema.Conditionals
{
    [DarkIcon("Conditionals/d_IsNull")]
    [LightIcon("Conditionals/IsNull")]
    [Category(SchemaCategory.AnyUnit)]
    public class IsUnitResource : Conditional
    {
        private enum ComparisonType
        {
            Greater,
            Less
        }

        private enum ValueType
        {
            Value,
            Percent
        }

        [SerializeField] private BlackboardEntrySelector<UnitObject> _unit;
        [SerializeField, Space(15)] private UnitResourceType _resourceType;
        [SerializeField] private ComparisonType _comparisonType;
        [SerializeField, ShowIf(nameof(_compareBy), ValueType.Value)] private BlackboardEntrySelector<int> _value = new(1);
        [SerializeField, ShowIf(nameof(_compareBy), ValueType.Value)] private BlackboardEntrySelector<int> _percent = new(50);
        [SerializeField] private ValueType _compareBy;

        private void OnValidate()
        {
            _percent.inspectorValue = Mathf.Min(Mathf.Max(_percent.inspectorValue, 0), 100);
            _value.inspectorValue = Mathf.Max(_value.inspectorValue, 0);
        }

        public override bool Evaluate(object nodeMemory, SchemaAgent agent)
        {
            return _compareBy switch
            {
                ValueType.Percent => CompareByPercent(),
                ValueType.Value => CompareByValue(),
                _ => throw new ArgumentOutOfRangeException()
            };
        }

        private bool CompareByValue()
        {
            var currentResource = _unit.value.unitData.currentResources.Get(_resourceType);

            return _comparisonType switch
            {
                ComparisonType.Greater => currentResource > _value.value,
                ComparisonType.Less => currentResource < _value.value,
                _ => throw new ArgumentOutOfRangeException()
            };
        }

        private bool CompareByPercent()
        {
            var currentResource = _unit.value.unitData.currentResources.Get(_resourceType);
            var maxResource = _unit.value.unitData.maxResources.Get(_resourceType);
            var currentPercent = currentResource / maxResource * 100;

            return _comparisonType switch
            {
                ComparisonType.Greater => currentPercent > _percent.value,
                ComparisonType.Less => currentPercent < _percent.value,
                _ => throw new ArgumentOutOfRangeException()
            };
        }

        public override GUIContent GetConditionalContent()
        {
            var sb = new StringBuilder();
            if (invert) sb.Append("<color=red>NOT</color> ");
            sb.Append(
                $"If <color=red>{_unit.name}</color> {nameof(UnitObjectData)}'s <color=red>{_resourceType}</color>");
            sb.Append(_comparisonType == ComparisonType.Greater ? " > " : " < ");
            if (_compareBy is ValueType.Percent) sb.Append($"<color=red>{_percent.name}</color>%");
            if (_compareBy is ValueType.Value) sb.Append($"<color=red>{_value.name}</color>");
            return new GUIContent(sb.ToString());
        }
    }
}