using System;
using System.Text;
using Schema;
using Sirenix.Utilities;
using UnityEngine;
using VOID.Generic.Objects.Unit;
using VOID.Generic.Util;

namespace VOID.Generic.AI.Schema.Conditionals
{
    [DarkIcon("Conditionals/d_IsNull")]
    [LightIcon("Conditionals/IsNull")]
    [Category(SchemaCategory.AnyUnit)]
    public class CanUnitMoveTo : Conditional
    {
        private enum MoveToType
        {
            Position,
            Unit
        }

        [SerializeField] private BlackboardEntrySelector<UnitObject> _unit;
        [SerializeField, Space(15)] private MoveToType _moveTo;
        [SerializeField] private BlackboardEntrySelector<Transform> _moveToPosition;
        [SerializeField] private BlackboardEntrySelector<UnitObject> _moveToUnit;
        [SerializeField, Space(15)] private BlackboardEntrySelector<float> _range;

        public override bool Evaluate(object nodeMemory, SchemaAgent agent)
        {
            var unitAgent = (UnitObjectSchemaAgent)agent;
            
            switch (_moveTo)
            {
                case MoveToType.Position:
                    _unit.value.unitNavAgent.CalculatePathTo(_moveToPosition.value.position,
                        _range.value + unitAgent.unit.basicData.radius);
                    break;
                case MoveToType.Unit:
                    _unit.value.unitNavAgent.CalculatePathTo(_moveToUnit.value.transform.position,
                        _range.value + unitAgent.unit.basicData.radius + _moveToUnit.value.basicData.radius);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            var path = _unit.value.unitNavAgent.GetCorrectedPath();

            // If somehow path isnt calculated - cant move
            if (path.IsNullOrEmpty()) return false;

            // Out of combat - costless move
            if (!_unit.value.basicState.turnManager) return true;

            // Calculate move cost when in turn combat
            var cost = NavMeshPathUtil.CalculatePathCost(path);
            return _unit.value.unitData.currentResources.movePoints >= cost;
        }

        public override GUIContent GetConditionalContent()
        {
            var sb = new StringBuilder();
            if (invert) sb.Append("<color=red>NOT</color> ");
            sb.Append($"If <color=red>{_unit.name}</color> can move to ");
            if (_moveTo is MoveToType.Position) sb.Append($"<color=red>{_moveToPosition.name}</color>");
            if (_moveTo is MoveToType.Unit) sb.Append($"<color=red>{_moveToUnit.name}</color>");
            return new GUIContent(sb.ToString());
        }
    }
}