using System;
using System.Linq;
using Actions;
using UnityEngine;

public class EnemyAI : MonoBehaviour {
    private float timer;
    private State CurrentState { get; set; }

    private void Awake() => CurrentState = State.WaitingForEnemyTurn;
    private void Start() => TurnSystem.Instance.OnTurnChanged += TurnSystem_OnTurnChanged;

    private void Update() {
        if (TurnSystem.Instance.IsPlayerTurn) return;

        switch (CurrentState) {
            case State.WaitingForEnemyTurn:
                break;
            case State.TakingTurn:
                timer -= Time.deltaTime;
                if (timer <= 0f) {
                    if (TryTakeEnemyAIAction(SetStateTakingTurn)) {
                        CurrentState = State.Busy;
                    }
                    else {
                        TurnSystem.Instance.NextTurn(); // No more enemies have actions they can take, end enemy turn
                    }
                }

                break;
            case State.Busy:
                break;
        }
    }

    private void SetStateTakingTurn() {
        timer = .5f;
        CurrentState = State.TakingTurn;
    }

    private void TurnSystem_OnTurnChanged(object sender, EventArgs e) {
        if (TurnSystem.Instance.IsPlayerTurn) return;
        CurrentState = State.TakingTurn;
        timer = 2f;
    }

    private static bool TryTakeEnemyAIAction(Action onEnemyAIActionComplete) 
        => UnitManager.Instance.EnemyUnitList.Any(enemyUnit => TryTakeEnemyAIAction(enemyUnit, onEnemyAIActionComplete));

    private static bool TryTakeEnemyAIAction(Unit enemyUnit, Action onEnemyAIActionComplete) {
        EnemyAIAction bestEnemyAIAction = null;
        BaseAction bestBaseAction = null;

        foreach (BaseAction baseAction in enemyUnit.BaseActionArray) {
            if (enemyUnit.ActionPoints < baseAction.ActionPointsCost) continue; //Enemy cannot afford this action
            if (bestEnemyAIAction == null) {
                bestEnemyAIAction = baseAction.GetBestEnemyAIAction();
                bestBaseAction = baseAction;
            }
            else {
                EnemyAIAction testEnemyAIAction = baseAction.GetBestEnemyAIAction();
                if (testEnemyAIAction == null || testEnemyAIAction.ActionValue <= bestEnemyAIAction.ActionValue) continue;
                bestEnemyAIAction = testEnemyAIAction;
                bestBaseAction = baseAction;
            }
        }

        if (bestEnemyAIAction != null && enemyUnit.TrySpendActionPointsToTakeAction(bestBaseAction)) {
            bestBaseAction.TakeAction(bestEnemyAIAction.GridPosition, onEnemyAIActionComplete);
            return true;
        }
        else {
            return false;
        }
    }

    private enum State {
        WaitingForEnemyTurn,
        TakingTurn,
        Busy
    }
}