﻿namespace AlqoholicTahmKench.Managers
{
    #region Using Directives

    using System;
    using System.Collections.Generic;
    using System.Linq;

    using AlqoholicTahmKench.Menu;
    using AlqoholicTahmKench.Spells;

    using LeagueSharp;
    using LeagueSharp.Common;

    #endregion

    internal class SpellManager
    {
        #region Fields

        /// <summary>
        ///     List of Spells
        /// </summary>
        private readonly List<SpellBase> spells = new List<SpellBase>();

        #endregion

        #region Constructors and Destructors

        /// <summary>
        ///     SpellManager Constructor
        /// </summary>
        internal SpellManager()
        {
            try
            {
                this.LoadSpells(new List<SpellBase>() { new Q(), new W(), new E(), new R() });
                Console.WriteLine("[AlqoholicTahmKench] Spells Loaded");
                Spells.Q = new Q();
                Spells.W = new W();
                Spells.E = new E();
                Spells.R = new R();
            }
            catch (Exception e)
            {
                Console.WriteLine("@SpellManager.cs: Cannot initialise the spells - {0}", e);
            }

            Game.OnUpdate += this.Game_OnUpdate;
        }

        #endregion

        #region Methods

        /// <summary>
        ///     OnUpdated Event
        /// </summary>
        /// <param name="args">args</param>
        private void Game_OnUpdate(EventArgs args)
        {
            var predictionMode = AlqoholicMenu.MainMenu.Item("prediction.mode").GetValue<StringList>().SelectedIndex;

            switch (Program.Orbwalker.ActiveMode)
            {
                case Orbwalking.OrbwalkingMode.Combo:

                    this.spells.Where(spell => CanCast(spell.SpellSlot, Orbwalking.OrbwalkingMode.Combo))
                        .ToList()
                        .ForEach(spell => spell.Combo(predictionMode));
                    break;

                case Orbwalking.OrbwalkingMode.Mixed:

                    this.spells.Where(spell => CanCast(spell.SpellSlot, Orbwalking.OrbwalkingMode.Mixed))
                        .ToList()
                        .ForEach(spell => spell.Harass());
                    break;

                case Orbwalking.OrbwalkingMode.LaneClear:

                    if (AlqoholicMenu.MainMenu.Item("farmspells").GetValue<KeyBind>().Active)
                    {
                        this.spells.Where(spell => CanCast(spell.SpellSlot, Orbwalking.OrbwalkingMode.LaneClear))
                            .ToList()
                            .ForEach(spell => spell.Farm());
                    }

                    break;

                case Orbwalking.OrbwalkingMode.LastHit:

                    this.spells.Where(spell => CanCast(spell.SpellSlot, Orbwalking.OrbwalkingMode.LastHit))
                        .ToList()
                        .ForEach(spell => spell.LastHit());
                    break;
            }
        }

        private static bool CanCast(SpellSlot spell, Orbwalking.OrbwalkingMode orbwalkingMode)
        {
            var orbwalkingModeLower = Program.Orbwalker.ActiveMode.ToString().ToLower();
            var spellLower = spell.ToString().ToLower();
            
            if (Program.Orbwalker.ActiveMode != orbwalkingMode || !spell.IsReady())
            {
                return false;
            }

            try
            {
                return AlqoholicMenu.MainMenu.Item(orbwalkingModeLower + spellLower + "use").GetValue<bool>()
                       && AlqoholicMenu.MainMenu.Item(orbwalkingModeLower + spellLower + "mana")
                              .GetValue<Slider>()
                              .Value <= ObjectManager.Player.ManaPercent;
            }
            catch (Exception e)
            {
                Console.WriteLine("@SpellManager.cs: Cannot get CanCast for slot {0} - {1}", spell, e);
                throw;
            }
        }



        /// <summary>
        ///     Load Spells Method
        /// </summary>
        /// <param name="spellList">
        ///     The Spells
        /// </param>
        private void LoadSpells(IEnumerable<SpellBase> spellList)
        {
            foreach (var spell in spellList)
            {
                AlqoholicMenu.GenerateSpellMenu(spell.SpellSlot);
                Console.WriteLine("[AlqoholicTahmKench] {0} Menu Loaded", spell.SpellSlot);

                this.spells.Add(spell);
            }
        }

        #endregion
    }
}