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

public class SubGoal
{
    public Dictionary<string, int> goals;
    public bool shouldRemove;

    public SubGoal(string goalName, int value, bool shouldRemove)
    {
        goals = new Dictionary<string, int>
        {
            { goalName, value }
        };
        this.shouldRemove = shouldRemove;
    }
}

public class AI_Agent : MonoBehaviour
{
    public List<AI_Action> actions = new List<AI_Action>();
    public Dictionary<SubGoal, int> goals = new Dictionary<SubGoal, int>();
    public AI_Inventory inventory = new AI_Inventory();
    public AIStates agentWorldStates = new AIStates();

    public float taskRange = 2.5f;

    protected AI_Planner planner;
    protected Queue<AI_Action> actionQueue;
    protected AI_Action currentAction;
    protected SubGoal currentGoal;
    protected bool actionInvoked;

    protected virtual void Start()
    {
        AI_Action[] actionsArray = GetComponents<AI_Action>();
        foreach (AI_Action action in actionsArray) 
        {
            actions.Add(action);
        }
    }

    private void CompleteAction()
    { 
        currentAction.isRunning = false;
        currentAction.PostPerform();
        actionInvoked = false;
    }
    
    private void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.yellow;
        Gizmos.DrawWireSphere(transform.position, taskRange);
    }

    private void LateUpdate()
    {
        if(currentAction != null && currentAction.isRunning)
        {
            float distanceToTarget = Vector3.Distance(currentAction.target.transform.position, transform.position);
            if(currentAction.agent.hasPath && distanceToTarget < taskRange)
            {
                if(!actionInvoked)
                {
                    Invoke(nameof(CompleteAction), currentAction.duration);
                    actionInvoked = true;
                }
            }
            return;
        }

        if(planner == null || actionQueue == null)
        {
            planner = new AI_Planner();

            var sortedGoals = from entry in goals orderby entry.Value descending select entry;

            foreach(KeyValuePair<SubGoal, int> subGoal in sortedGoals)
            {
                actionQueue = planner.Plan(actions, subGoal.Key.goals, agentWorldStates);
                if (actionQueue != null)
                {
                    currentGoal = subGoal.Key;
                    break;
                }
            }
        }

        if(actionQueue != null && actionQueue.Count == 0)
        {
            if(currentGoal.shouldRemove)
            {
                goals.Remove(currentGoal);
            }
            planner = null;
        }

        if (actionQueue != null && actionQueue.Count > 0)
        {
            currentAction = actionQueue.Dequeue();
            if (currentAction.PrePerform())
            {
                if (currentAction.target == null && !string.IsNullOrEmpty(currentAction.targetTag))
                {
                    currentAction.target = GameObject.FindWithTag(currentAction.targetTag);
                }

                if (currentAction.target != null)
                {
                    currentAction.isRunning = true;

                    // Check for AI_Area component
                    AI_Area area = currentAction.target.GetComponent<AI_Area>();
                    Vector3 destination;

                    if (area != null)
                    {
                        destination = area.GetRandomPointInArea();
                    }
                    else
                    {
                        destination = currentAction.target.transform.position;
                    }

                    currentAction.agent.SetDestination(destination);
                }
            }
            else
            {
                actionQueue = null;
            }
        }
    }
}