﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// import the unity AI library
using UnityEngine.AI;

[RequireComponent(typeof(NavMeshAgent))]
public class AICharacter : BaseCharacter
{
    // the target for the AI character to chase
    [SerializeField]
    private Transform target = null;

    // the max range at which to start chasing the target
    [SerializeField]
    private float targetChaseRange = 10.0f;

    // the distance within which to stop from the target
    [SerializeField]
    private float targetStoppingDistance = 2f;

    // indicates how long AI should stop and think (be idle) on reaching a destination waypoint (not target) so it is not constantly moving
    [SerializeField]
    private float thinkingTime = 5f;

    // used to cache the nav mesh agent component attached to this character
    private NavMeshAgent agent;

    // used to cache the waypoint controller component attached to this character
    WaypointController waypointController;

    // indicates if AI is currently in thinking mode
    private bool isThinking = false;

    // store the elapsed thinking (idle) time when AI is in thinking mode
    float elapsedThinkingTime = 0f;

    // The current target waypoint to visit
    Transform currentWaypoint;

    // The agent's current target destination, useful for checking if current destination is player or waypoint
    Transform currentDestination;

    //private bool isChasing;

    //private bool wasAttacking;

    // Start is called before the first frame update
    // Make start override Start method in base (inherited) class
    protected override void Start()
    {
        // Call the base (inherited) class start method first
        

        // Get and cache the nav mesh agent component attached to the game object this script is attached to
        

        // Get and cache the waypoint controller component attached to the game object this script is attached to
        

        // Set a new target waypoint to visit
        

        // Set the attack range to the target's stopping distance
        

        // Set non-combat mode based on setting
        
    }

    // Update is called once per frame
    void Update()
    {
        // if no Nav Mesh Agent component attached to game object, no need to continue, return and exit the method early
        if (agent == null) return;

        // Check if AI is attacking and if yes, attack
        // Else
        //      Check if AI is near enough to chase and if yes, update current destination to target
        //      Else if AO is thinking, update the thinking
        //      Else update the current way point
        //      Move the AI passing its movement (agent.velocity). Hint: see what you did in player


        
    }

    // Check if AI is in attack mode
    protected override bool IsAttacking()
    {
        // if target or non combat mode or current target destination not set, no one to attack
        // Otherwise, check if current destination is the target and agent is close enough (within attack range) to attack


        return false;
    }

    // Set the Nav Mash Agent's target destination
    private void SetCurrentDestination(Transform destination, float stoppingDistance)
    {
        // Update the current destination so you can use to check if current destination is target or player
        

        // Update the nav mesh agent's destination and stopping distance to the specified passed in parameters
        

        // make the AI agent resume movement to the updated destination
        
    }

    // Checks if target (player) is within chasing distance
    private bool IsTargetWithinRange()
    {
        // if no target has been set, no need to continue, return and exit the method early
        

        // calculate the position vector difference / offset
        Vector3 positionOffset;

        // As you only need to check if target is nearby, you do not need the actual distance value 
        // use squared magnitude instead of actual distance which uses square root which is computationally slower than squared magnitude
        // See more: https://docs.unity3d.com/ScriptReference/Vector3-sqrMagnitude.html
        return false; 
    }

    // Check if Nav Mesh Agent has reached its current target destination i.e. remaining distance is less than/equal stopping distance
    private bool HasReachedDestination(float stoppingDistance)
    {
        // Check if AI agent is NOT stopped AND the AI agent's remaining distance is less than the passed in stopping distance parameter
        // If yes, make the AI agent stop movement (set isStopped property) and return true
        // Else,  make the AI agent resume/continue movement to the destination and return false
        


        return false;
    }

    // Reset the thinking duration (elapsedThinkingTime)
    private void StartThinking()
    {
        // What do you think needs to happen to the elapsed thinking time and isThinking variables?
        
    }

    // Update the thinking duration
    private void UpdateThinking()
    {
        // Increase thinking counter by time elapsed since last frame
        

        // If the elapsed thinking time is greater than or equal the the thinking time, the AI agent can stop thinking
        // Update isThinking
        // Set a new target waypoint to visit - what method allows you to get and set a new waypoint or see what you did in Start
        

    }

    // Update Nav Mesh Agent's destination back to the current waypoint in case AI took a detour to chase the target (player)
    private void UpdateCurrentWaypoint()
    {
        // Update agent's destination to current waypoint in case it changed in the last last frame and set the stopping distance to the waypoint stopping distance (waypointController.StoppingDistance)
        
        
        // If agent has reached waypoint, start thinking
        

    }

    // Gets and sets a new waypoint to visit
    void SetNewWaypoint()
    {
        // If there is a waypoint controller script component attached (will be cached in waypointController)
        //      use the waypointController's Get Next Waypoint method to set (assign) a new currentWaypoint
        // currentWaypoint = ...
        

    }
}
