using System;
using Creaturelib.Generated;
using PkmnLibSharp.Library.Moves;
using PkmnLibSharp.Utilities;

namespace PkmnLibSharp.Library
{
    public class LearnableMoves : PointerWrapper
    {
        internal LearnableMoves(IntPtr ptr) : base(ptr)
        {
        }

        public LearnableMoves(byte maxLevel)
        {
            var ptr = IntPtr.Zero;
            Pkmnlib.Generated.LearnableMoves.Construct(ref ptr, maxLevel);
            Initialize(ptr);
        }
        
        public ReadOnlyNativePtrArray<MoveData> DistinctLevelMoves
        {
            get
            {
                if (_distinctLevelMoves != null) return _distinctLevelMoves;
                var count = LearnableAttacks.GetDistinctLevelAttacksCount(Ptr);
                var ptr = LearnableAttacks.GetDistinctLevelAttacks(Ptr);
                _distinctLevelMoves =
                    new ReadOnlyNativePtrArray<MoveData>(ptr, (int) count, Constructor.GenericType.LearnableMoves);
                return _distinctLevelMoves;
            }
        }
        
        public ReadOnlyNativePtrArray<MoveData> EggMoves
        {
            get
            {
                if (_eggMoves != null) return _eggMoves;
                var count = Pkmnlib.Generated.LearnableMoves.GetEggMovesCount(Ptr);
                var ptr = Pkmnlib.Generated.LearnableMoves.GetEggMoves(Ptr);
                _eggMoves = new ReadOnlyNativePtrArray<MoveData>(ptr, (int) count, Constructor.GenericType.MoveData);
                return _eggMoves;
            }
        }

        
        public ReadOnlyNativePtrArray<MoveData> GetMovesForLevel(byte level)
        {
            if (LearnableAttacks.HasAttacksForLevel(Ptr, level) != 1)
            {
                return new ReadOnlyNativePtrArray<MoveData>(Constructor.GenericType.MoveData);
            }
            var count = LearnableAttacks.GetAttacksForLevelCount(Ptr, level);
            var ptr = LearnableAttacks.GetAttacksForLevel(Ptr, level);
            return new ReadOnlyNativePtrArray<MoveData>(ptr, (int) count, Constructor.GenericType.MoveData);
        }
        
        public void AddLevelMove(byte level, MoveData move)
        {
            LearnableAttacks.AddLevelAttack(Ptr, level, move.Ptr);
        }
        public void AddEggMove(MoveData move)
        {
            Pkmnlib.Generated.LearnableMoves.AddEggMove(Ptr, move.Ptr);
        }



        private ReadOnlyNativePtrArray<MoveData>? _distinctLevelMoves;
        private ReadOnlyNativePtrArray<MoveData>? _eggMoves;
        protected override void DeletePtr()
        {
            LearnableAttacks.Destruct(Ptr);
        }
    }
}