using System;
using Creaturelib.Generated;
using PkmnLibSharp.Library.Moves;
using PkmnLibSharp.Utilities;
using GrowthRateLibrary = PkmnLibSharp.Library.GrowthRates.GrowthRateLibrary;
using ItemLibrary = PkmnLibSharp.Library.Items.ItemLibrary;

namespace PkmnLibSharp.Library
{
    public class PokemonLibrary : PointerWrapper
    {
        private LibrarySettings? _settings;

        public LibrarySettings Settings
        {
            get
            {
                if (_settings != null) return _settings;
                var ptr = DataLibrary.GetSettings(Ptr);
                if (TryResolvePointer(ptr, out _settings))
                    return _settings!;
                _settings = new LibrarySettings(ptr);
                return _settings;
            }
        }

        private SpeciesLibrary? _species;

        public SpeciesLibrary SpeciesLibrary
        {
            get
            {
                if (_species != null) return _species;
                var ptr = DataLibrary.GetSpeciesLibrary(Ptr);
                if (TryResolvePointer(ptr, out _species))
                    return _species!;
                _species = new SpeciesLibrary(ptr);
                return _species;
            }
        }

        private MoveLibrary? _moves;

        public MoveLibrary MoveLibrary
        {
            get
            {
                if (_moves != null) return _moves;
                var ptr = DataLibrary.GetAttackLibrary(Ptr);
                if (TryResolvePointer(ptr, out _moves))
                    return _moves!;
                _moves = new MoveLibrary(ptr);
                return _moves;
            }
        }

        private ItemLibrary? _items;

        public ItemLibrary ItemLibrary
        {
            get
            {
                if (_items != null) return _items;
                var ptr = DataLibrary.GetItemLibrary(Ptr);
                if (TryResolvePointer(ptr, out _items))
                    return _items!;
                _items = new ItemLibrary(ptr);
                return _items;
            }
        }

        private GrowthRateLibrary? _growthRateLibrary;

        public GrowthRateLibrary GrowthRateLibrary
        {
            get
            {
                if (_growthRateLibrary != null) return _growthRateLibrary;
                var ptr = DataLibrary.GetGrowthRates(Ptr);
                if (TryResolvePointer(ptr, out _growthRateLibrary))
                    return _growthRateLibrary!;
                _growthRateLibrary = new GrowthRateLibrary(ptr);
                return _growthRateLibrary;
            }
        }

        private TypeLibrary? _typeLibrary;

        public TypeLibrary TypeLibrary
        {
            get
            {
                if (_typeLibrary != null) return _typeLibrary;
                var ptr = DataLibrary.GetTypeLibrary(Ptr);
                if (TryResolvePointer(ptr, out _typeLibrary))
                    return _typeLibrary!;
                _typeLibrary = new TypeLibrary(ptr);
                return _typeLibrary;
            }
        }

        private NatureLibrary? _natureLibrary;

        public NatureLibrary NatureLibrary
        {
            get
            {
                if (_natureLibrary != null) return _natureLibrary;
                var ptr = Pkmnlib.Generated.PokemonLibrary.GetNatureLibrary(Ptr);
                if (TryResolvePointer(ptr, out _natureLibrary))
                    return _natureLibrary!;
                _natureLibrary = new NatureLibrary(ptr);
                return _natureLibrary;
            }
        }


        public PokemonLibrary(IntPtr ptr) : base(ptr)
        {
        }

        public PokemonLibrary(LibrarySettings settings, SpeciesLibrary species, MoveLibrary moves,
            ItemLibrary items,
            GrowthRateLibrary growthRates, TypeLibrary types, NatureLibrary natures)
        {
            var ptr = IntPtr.Zero;
            Pkmnlib.Generated.PokemonLibrary.Construct(ref ptr, settings.Ptr, species.Ptr, moves.Ptr, items.Ptr,
                growthRates.Ptr, types.Ptr, natures.Ptr).Assert();
            Initialize(ptr);
            _settings = settings;
            _species = species;
            _moves = moves;
            _items = items;
            _growthRateLibrary = growthRates;
            _typeLibrary = types;
            _natureLibrary = natures;
        }

        protected override void DeletePtr()
        {
            Pkmnlib.Generated.PokemonLibrary.Destruct(Ptr);
        }

        protected internal override void MarkAsDeleted()
        {
            base.MarkAsDeleted();
            _settings?.MarkAsDeleted();
            _species?.MarkAsDeleted();
            _moves?.MarkAsDeleted();
            _items?.MarkAsDeleted();
            _growthRateLibrary?.MarkAsDeleted();
            _typeLibrary?.MarkAsDeleted();
            _natureLibrary?.MarkAsDeleted();
        }
    }
}