from src.gameplay.comboSpells.core import comboSpellDidMatch
from src.gameplay.core.tasks.castSpell import CastSpellTask
from src.gameplay.core.tasks.orchestrator import TasksOrchestrator
from src.gameplay.core.tasks.useSlotItem import UseSlotItemTask
from src.gameplay.healing.utils.potions import healthPotionTakesPriority
from src.gameplay.reaction import ReactionGate
from src.repositories.actionBar.core import hasCooldownByName
from src.repositories.gameWindow.creatures import getNearestCreaturesCount
from src.wiki.spells import spells
from .core.tasks.useComboHotkey import UseComboHotkeyTask
from .typings import Context


tasksOrchestrator = TasksOrchestrator()
comboGate = ReactionGate()


def _comboCastTask(context, spell):
    """Slot-Klick (Smart-Modus), sonst Chat-Zauber; ohne Hotkey immer
    Chat-Zauber, sonst klassischer Hotkey via UseComboHotkeyTask."""
    if context.get('ng_actionBar', {}).get('smartHotkeys'):
        if spell.get('slot'):
            return UseSlotItemTask(spell['slot'], delayAfterComplete=0.1)
        return CastSpellTask(spell['name'], delayAfterComplete=0.1)
    if not spell.get('hotkey'):
        return CastSpellTask(spell['name'], delayAfterComplete=0.1)
    return None


# TODO: do not execute algorithm when has no combo spells
# TODO: add unit tests
# TODO: check if spell is casted, if not try cast again
def comboSpells(context: Context):
    if context['ng_statusBar']['mana'] is None or context['ng_comboSpells']['enabled'] == False:
        return
    currentTask = tasksOrchestrator.getCurrentTask(context)
    if currentTask is not None:
        if currentTask.status == 'completed':
            tasksOrchestrator.reset()
        else:
            tasksOrchestrator.do(context)
            return
    nearestCreaturesCount = getNearestCreaturesCount(
        context['gameWindow']['monsters'])
    if nearestCreaturesCount == 0:
        return
    if healthPotionTakesPriority(context):
        return
    if context['ng_statusBar']['manaPercentage'] <= 30:
        return
    for key, comboSpell in enumerate(context['ng_comboSpells']['items']):
        if comboSpell['enabled'] == False:
            continue
        if comboSpellDidMatch(comboSpell, nearestCreaturesCount):
            spell = comboSpell['spells'][comboSpell['currentSpellIndex']]
            # TODO: JUST COMBO WHEN CAITING WITH PALADIN (NOT FOR NOW)
            if context['ng_cave']['isAttackingSomeCreature'] == False:
                return
            if context['ng_statusBar']['mana'] < spells[spell['name']]['manaNeeded']:
                return
            # TODO: ADD SPELL CATEGORY IN WIKI
            if spell['name'] in ['utito tempo', 'utamo tempo']:
                if hasCooldownByName(context['ng_screenshot'], 'support'):
                    return
            else:
                if hasCooldownByName(context['ng_screenshot'], 'attack'):
                    return
            if hasCooldownByName(context['ng_screenshot'], spell['name']):
                return
            if not comboGate.ready():
                return
            tasksOrchestrator.setRootTask(
                context, UseComboHotkeyTask(
                    spell['hotkey'], spell['name'],
                    useTask=_comboCastTask(context, spell)))
            return
