using System;
using PkmnLibSharp.Utilities;

namespace PkmnLibSharp.Battling
{
    public class ExecutingMove : PointerWrapper
    {
        internal ExecutingMove(IntPtr ptr) : base(ptr){}

        public LearnedMove Move
        {
            get
            {
                if (_move != null) return _move;
                var ptr = Creaturelib.Generated.ExecutingAttack.GetAttack(Ptr);
                if (TryResolvePointer(ptr, out _move))
                    return _move!;
                _move = new LearnedMove(ptr);
                return _move;
            }
        }
        public Pokemon User
        {
            get
            {
                if (_user != null) return _user;
                var ptr = Creaturelib.Generated.ExecutingAttack.GetUser(Ptr);
                if (TryResolvePointer(ptr, out _user))
                    return _user!;
                _user = Constructor.Active.ConstructPokemon(ptr)!;
                return _user;
            }
        }

        /// <summary>
        /// Get the first hit for the first target. Honestly just here so I can quickly read hit info from my debugger.
        /// </summary>
        public HitData FirstHit => GetHitData(Targets[0]!, 0);

        public byte NumberOfHits => Creaturelib.Generated.ExecutingAttack.GetNumberOfHits(Ptr);

        public ReadOnlyNativePtrArray<Pokemon> Targets
        {
            get
            {
                if (_targets != null) return _targets;
                var size = Creaturelib.Generated.ExecutingAttack.GetTargetCount(Ptr);
                var ptr = Creaturelib.Generated.ExecutingAttack.GetTargets(Ptr);
                _targets = new ReadOnlyNativePtrArray<Pokemon>(ptr, size, Constructor.GenericType.Pokemon);
                return _targets;
            }
        }


        public HitData GetHitData(Pokemon target, byte index)
        {
            var ptr = IntPtr.Zero;
            Creaturelib.Generated.ExecutingAttack.GetHitData(ref ptr, Ptr, target.Ptr, index).Assert();
            return new HitData(ptr);
        }

        public bool IsPokemonTarget(Pokemon pokemon)
        {
            return Creaturelib.Generated.ExecutingAttack.IsCreatureTarget(Ptr, pokemon.Ptr) == 1;
        }

        private LearnedMove? _move;
        private Pokemon? _user;
        private ReadOnlyNativePtrArray<Pokemon>? _targets;
        protected override void DeletePtr()
        {
        }
    }
}