context: using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Threading.Tasks;
  using DZAIO_Reborn.Core;
  using DZAIO_Reborn.Helpers;
  using DZAIO_Reborn.Helpers.Entity;
  using DZAIO_Reborn.Helpers.Modules;
  using DZAIO_Reborn.Plugins.Champions.Ahri.Modules;
  using DZAIO_Reborn.Plugins.Interface;
  using DZLib.Core;
  using DZLib.Menu;
  using DZLib.MenuExtensions;
  using DZLib.Positioning;
  using LeagueSharp;
  using LeagueSharp.Common;
  using SPrediction;
  
  using EloBuddy; 
   using LeagueSharp.Common; 
   namespace DZAIO_Reborn.Plugins.Champions.Ahri
  {
      class Ahri : IChampion
      {
          public void OnLoad(Menu menu)
          {
              var comboMenu = new Menu(ObjectManager.Player.ChampionName + ": Combo", "dzaio.champion.ahri.combo");
              {
                  comboMenu.AddModeMenu(ModesMenuExtensions.Mode.Combo, new[] { SpellSlot.Q, SpellSlot.W, SpellSlot.E, SpellSlot.R }, new[] { true, true, true, true });
                  comboMenu.AddBool("dzaio.champion.ahri.combo.waitforE", "Wait for charm", true);
                  comboMenu.AddBool("dzaio.champion.ahri.combo.onlyInitR", "Only use First R (Only to initiate)", true);
  
                  menu.AddSubMenu(comboMenu);
              }
  
              var mixedMenu = new Menu(ObjectManager.Player.ChampionName + ": Mixed", "dzaio.champion.ahri.harrass");
              {
                  mixedMenu.AddModeMenu(ModesMenuExtensions.Mode.Harrass, new[] { SpellSlot.Q, SpellSlot.W }, new[] { true, true });
                  mixedMenu.AddSlider("dzaio.champion.ahri.mixed.mana", "Min Mana % for Harass", 30, 0, 100);
                  menu.AddSubMenu(mixedMenu);
              }
  
              var farmMenu = new Menu(ObjectManager.Player.ChampionName + ": Farm", "dzaio.champion.ahri.farm");
              {
                  farmMenu.AddModeMenu(ModesMenuExtensions.Mode.Laneclear, new[] { SpellSlot.Q, SpellSlot.W }, new[] { true, true });
  
                  farmMenu.AddSlider("dzaio.champion.ahri.farm.w.min", "Min Minions for W", 2, 1, 6);
                  farmMenu.AddSlider("dzaio.champion.ahri.farm.mana", "Min Mana % for Farm", 30, 0, 100);
                  menu.AddSubMenu(farmMenu);
              }
  
              var extraMenu = new Menu(ObjectManager.Player.ChampionName + ": Extra", "dzaio.champion.ahri.extra");
              {
                  extraMenu.AddBool("dzaio.champion.ahri.extra.interrupter", "Interrupter (E)", true);
                  extraMenu.AddBool("dzaio.champion.ahri.extra.antigapcloser", "Antigapcloser (E)", true);
                  extraMenu.AddBool("dzaio.champion.ahri.extra.autoQ", "Auto Q Stunned / Rooted", true);
                  extraMenu.AddBool("dzaio.champion.ahri.extra.autoQKS", "Auto Q KS", true);
              }
  
              Variables.Spells[SpellSlot.Q].SetSkillshot(0.25f, 100, 1600, false, SkillshotType.SkillshotLine);
              Variables.Spells[SpellSlot.E].SetSkillshot(0.25f, 60, 1200, true, SkillshotType.SkillshotLine);
          }
  
          public void RegisterEvents()
          {
              DZInterrupter.OnInterruptableTarget += OnInterrupter;
              DZAntigapcloser.OnEnemyGapcloser += OnGapcloser;
          }
  
          private void OnGapcloser(DZLib.Core.ActiveGapcloser gapcloser)
          {
              if (Variables.AssemblyMenu.GetItemValue<bool>("dzaio.champion.ahri.extra.antigapcloser")
                  && ObjectManager.Player.ManaPercent > 20
                  && gapcloser.End.Distance(ObjectManager.Player.ServerPosition) < 400
                  && gapcloser.Sender.IsValidTarget(Variables.Spells[SpellSlot.E].Range)
                  && Variables.Spells[SpellSlot.E].IsReady())
              {
                  Variables.Spells[SpellSlot.E].CastIfHitchanceEquals(gapcloser.Sender, HitChance.Medium);
              }
          }
  
          private void OnInterrupter(AIHeroClient sender, DZInterrupter.InterruptableTargetEventArgs args)
          {
              if (Variables.AssemblyMenu.GetItemValue<bool>("dzaio.champion.ahri.extra.interrupter")
                  && ObjectManager.Player.ManaPercent > 20
                  && args.DangerLevel > DZInterrupter.DangerLevel.Medium
                  && sender.IsValidTarget(Variables.Spells[SpellSlot.E].Range)
                  && Variables.Spells[SpellSlot.E].IsReady())
              {
                  Variables.Spells[SpellSlot.E].CastIfHitchanceEquals(sender, HitChance.High);
              }
          }
          public Dictionary<SpellSlot, Spell> GetSpells()
          {
              return new Dictionary<SpellSlot, Spell>
                        {
                              { SpellSlot.Q, new Spell(SpellSlot.Q, 925f) },
                              { SpellSlot.W, new Spell(SpellSlot.W, 700f) },
                              { SpellSlot.E, new Spell(SpellSlot.E, 875f) },
                              { SpellSlot.R, new Spell(SpellSlot.R, 400f) }
                        };
          }
  
          public List<IModule> GetModules()
          {
              return new List<IModule>()
              {
                 new AhriQKS(),
                 new AhriQRootStun()
              };
          }
  
          public void OnTick()
          {
  
          }
  
          public void OnCombo()
          {
              var comboTarget = TargetSelector.GetTarget(Variables.Spells[SpellSlot.E].Range, TargetSelector.DamageType.Magical);
              var charmedUnit = HeroManager.Enemies.Find(h => h.HasBuffOfType(BuffType.Charm) && h.IsValidTarget(Variables.Spells[SpellSlot.Q].Range));
  
              var finalTarget = charmedUnit ?? comboTarget;
  
              if (finalTarget.IsValidTarget())
              {
                  if (Variables.AssemblyMenu.GetItemValue<bool>("dzaio.champion.ahri.combo.waitforE"))
                  {
                      //Wait for Charm Combo
                      if (Variables.Spells[SpellSlot.E].IsEnabledAndReady(ModesMenuExtensions.Mode.Combo) &&
                          Variables.Spells[SpellSlot.Q].IsEnabledAndReady(ModesMenuExtensions.Mode.Combo) &&
                          !finalTarget.IsCharmed)
                      {
                          Variables.Spells[SpellSlot.E].CastIfHitchanceEquals(finalTarget, HitChance.High);
                      }
  
                      if (Variables.Spells[SpellSlot.Q].IsEnabledAndReady(ModesMenuExtensions.Mode.Combo) &&
                          (!Variables.Spells[SpellSlot.E].IsEnabledAndReady(ModesMenuExtensions.Mode.Combo) ||
                           ObjectManager.Player.ManaPercent <= 25))
                      {
                          Variables.Spells[SpellSlot.Q].CastIfHitchanceEquals(finalTarget, HitChance.High);
                      }
  
                      if (Variables.Spells[SpellSlot.W].IsEnabledAndReady(ModesMenuExtensions.Mode.Combo) &&
                          finalTarget.IsValidTarget(Variables.Spells[SpellSlot.W].Range) &&
                          (finalTarget.IsCharmed ||
                           (Variables.Spells[SpellSlot.W].GetDamage(finalTarget) +
                            Variables.Spells[SpellSlot.Q].GetDamage(finalTarget) > finalTarget.Health + 25)))
                      {
                          Variables.Spells[SpellSlot.W].Cast();
                      }
                  }
                  else
                  {
                      if (Variables.Spells[SpellSlot.E].IsEnabledAndReady(ModesMenuExtensions.Mode.Combo) &&
                          Variables.Spells[SpellSlot.Q].IsEnabledAndReady(ModesMenuExtensions.Mode.Combo) &&
                          !finalTarget.IsCharmed)
                      {
                          Variables.Spells[SpellSlot.E].CastIfHitchanceEquals(finalTarget, HitChance.High);
                      }
  
                      if (Variables.Spells[SpellSlot.Q].IsEnabledAndReady(ModesMenuExtensions.Mode.Combo))
                      {
                          Variables.Spells[SpellSlot.Q].CastIfHitchanceEquals(finalTarget, HitChance.High);
                      }
  
                      if (Variables.Spells[SpellSlot.W].IsEnabledAndReady(ModesMenuExtensions.Mode.Combo) &&
                          finalTarget.IsValidTarget(Variables.Spells[SpellSlot.W].Range) &&
                          ((Variables.Spells[SpellSlot.W].GetDamage(finalTarget) +
                            Variables.Spells[SpellSlot.Q].GetDamage(finalTarget) > finalTarget.Health + 25)))
                      {
                          Variables.Spells[SpellSlot.W].Cast();
                      }
                  }
  
                  if (Variables.Spells[SpellSlot.R].IsEnabledAndReady(ModesMenuExtensions.Mode.Combo))
                  {
                      HandleRLogic();
                  }
                  
              }
          }
  
          private void HandleRLogic()
          {
              if (CanUltiSafely())
              {
                  var mousePosition = Game.CursorPos;
                  var extendedPosition = ObjectManager.Player.ServerPosition.Extend(mousePosition, 450f);
  
                  Variables.Spells[SpellSlot.R].Cast(extendedPosition);
              }
          }
  
          private bool CanUltiSafely()
          {
              if (ObjectManager.Player.CountEnemiesInRange(550f) > 0)
              {
                  return true;
              }
  
              if (ObjectManager.Player.HasBuff("AhriTumble") &&
                  Variables.AssemblyMenu.GetItemValue<bool>("dzaio.champion.ahri.combo.onlyInitR"))
              {
                  return false;
              }
  
              var mousePosition = Game.CursorPos;
              var extendedPosition = ObjectManager.Player.ServerPosition.Extend(mousePosition, 450f);
  
              if (extendedPosition.GetEnemiesInRange(625f).Any())
              {
                  if (ObjectManager.Player.HasBuff("AhriTumble"))
                  {
                      return true;
                  }
  
                  var manaCheck = ObjectManager.Player.Mana >
                                  Variables.Spells[SpellSlot.Q].ManaCost + Variables.Spells[SpellSlot.E].ManaCost +
                                  Variables.Spells[SpellSlot.R].ManaCost;
  
                  if (manaCheck && Variables.Spells[SpellSlot.Q].IsEnabledAndReady(ModesMenuExtensions.Mode.Combo) &&
                      Variables.Spells[SpellSlot.E].IsEnabledAndReady(ModesMenuExtensions.Mode.Combo))
                  {
                      if (extendedPosition.IsSafe(450f))
                      {
                          return true;
                      }
                  }
  
              }
  
              return false;
          }
          public void OnMixed()
          {
              if (ObjectManager.Player.ManaPercent <
                  Variables.AssemblyMenu.GetItemValue<Slider>("dzaio.champion.ahri.mixed.mana").Value)
              {
                  return;
              }
              var comboTarget = TargetSelector.GetTarget(Variables.Spells[SpellSlot.E].Range, TargetSelector.DamageType.Magical);
              var charmedUnit = HeroManager.Enemies.Find(h => h.HasBuffOfType(BuffType.Charm) && h.IsValidTarget(Variables.Spells[SpellSlot.Q].Range));
  
              var finalTarget = charmedUnit ?? comboTarget;
  
              if (Variables.Spells[SpellSlot.Q].IsEnabledAndReady(ModesMenuExtensions.Mode.Combo))
              {
                  Variables.Spells[SpellSlot.Q].CastIfHitchanceEquals(finalTarget, HitChance.High);
              }
  
              if (Variables.Spells[SpellSlot.W].IsEnabledAndReady(ModesMenuExtensions.Mode.Combo) &&
                  finalTarget.IsValidTarget(Variables.Spells[SpellSlot.W].Range) &&
                  ((Variables.Spells[SpellSlot.W].GetDamage(finalTarget) +
                    Variables.Spells[SpellSlot.Q].GetDamage(finalTarget) > finalTarget.Health + 25)))
              {
                  Variables.Spells[SpellSlot.W].Cast();
              }
          }
  
          public void OnLastHit()
          { }
  
          public void OnLaneclear()
          {
              if (ObjectManager.Player.ManaPercent <
                  Variables.AssemblyMenu.GetItemValue<Slider>("dzaio.champion.ahri.farm.mana").Value)
              {
                  return;
              }
  
              if (Variables.Spells[SpellSlot.Q].IsEnabledAndReady(ModesMenuExtensions.Mode.Laneclear))
              {
                  var positions = MinionManager.GetMinions(Variables.Spells[SpellSlot.Q].Range,
                      MinionTypes.All, MinionTeam.NotAlly,
                      MinionOrderTypes.MaxHealth)
                      .Where(m => Variables.Spells[SpellSlot.Q].GetDamage(m) >= m.Health + 5)
                      .Select(m => m.ServerPosition.To2D()).ToList();
  
                  var lineFarmLocation = Variables.Spells[SpellSlot.Q].GetLineFarmLocation(positions);
  
  
gt:                 if (lineFarmLocation.MinionsHit >= 6)