namespace Grunt_gun
{
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.AI;


    public class Enemy_1 : MonoBehaviour
    {
        private StateMachine stateMachine;
        [SerializeField]private GameObject player;
        [SerializeField]private NavMeshAgent agent;
        private string currentState;
        private float losePlayerCooldown = 3f;
        private float losePlayerTimer = 0f;

        public GameObject enemy;
        public NavMeshAgent Agent { get { return agent; } }
        public GameObject Player { get { return player; } }
        public Path path;
        public Path Path { get { return path; } }
        [Header("Sight Values")]
        public float sightDistance = 20f;
        public float feildOfView = 180f;
        public float eyeHeight = 0;
        [Header("Weapon Values")]
        public Transform Fuzil;
        [Range(0.1f, 10f)]
        public float fireRate;




        // Start is called before the first frame update
        void Start()
        {
            Debug.Log("Enemy_1 Start() method called.");
            player = GameObject.FindGameObjectWithTag("Player");
            enemy = gameObject;
            if (enemy != null && player != null)
            {
                stateMachine = GetComponent<StateMachine>();

                if (stateMachine == null)
                {
                    Debug.LogError("StateMachine component is not found in Enemy_1.");
                }
                else
                {
                    Debug.Log("StateMachine component found in Enemy_1.");
                }
                agent = GetComponent<NavMeshAgent>();
                stateMachine.Initialize(path, EnemyType.Grunt_gun);
                
                if (agent == null)
                {
                    Debug.LogError("NavMeshAgent component is not found in Enemy_1.");
                }
            }
            else
            {
                Debug.LogError("Enemy or Player reference is null!");
            }
        }

        // Update is called once per frame
        void Update()
        {
            //Debug.Log("stateMachine: " + stateMachine);
            //Debug.Log("player: " + player);
            //Debug.Log("agent: " + agent);

            bool playerDetected = CanSeePlayer();
            Debug.Log("CanSeePlayer result:" + CanSeePlayer());
            // Update current state if state machine exists
            if (stateMachine != null)
            {
                //Update current state if state machine exists
                currentState = stateMachine.activeState.ToString();
            }
            else
            {
                //Update current state if state machine exists
                currentState = "None" ;
            }
            // Check if state machine and active state are not null
            if (stateMachine != null && stateMachine.activeState != null)
            {
                
                //Update current state field
                currentState = stateMachine.activeState.GetType().Name;
                // Check if active state is PatrolState
                if (stateMachine.activeState.GetType() == typeof(PatrolState))

                {
                    if (enemy != null)
                    {
                        // turns activestate to patrolState, get next waypoint for patrol and set destination for navmeshAgent
                        PatrolState patrolState = (PatrolState)stateMachine.activeState;
                        Vector3 nextWaypoint = patrolState.GetNextWaypoint();
                        agent.SetDestination(nextWaypoint);
                        Debug.Log("Player detected by CanSeePlayer method");
                        if (playerDetected)// Check if player is detected
                        {
                            Debug.Log("Player detected in patrolState. changing to attackstate.");
                            stateMachine.ChangeGunState(new AttackState(this)); //transition to attackstate                           
                        }
                        else
                        {
                            Debug.Log("Player not detected by CanSeePlayer method");
                            losePlayerTimer += Time.deltaTime;// Increment losePlayerTimer
                            if (losePlayerTimer >= losePlayerCooldown)// Check if player is lost and transition to PatrolState
                            {
                                Debug.Log("Player lost, changing to patrolstate.");
                                TransitionToPatrolState();
                                losePlayerTimer = 0f;
                            }
                        }
                    }
                }
                else
                {
                    // Set current state to "None" if active state is not PatrolState
                    currentState = "None";
                }
            }
            else
            {
                Debug.LogWarning("StateMachine or activestate is null in enemy_1 update()");
            }
        }

        public void TransitionToPatrolState()
        {
            stateMachine.ChangeGunState(new PatrolState(path, this));
        }

        public void TransitionToAttackState()
        {
            stateMachine.ChangeGunState(new AttackState(this));
        }

        public bool CanSeePlayer()

        {
            if (player != null)
            {
                if (Vector3.Distance(transform.position, player.transform.position) < sightDistance)
                {
                    Vector3 targetDirection = player.transform.position - transform.position - (Vector3.up * eyeHeight);
                    float angleToPlayer = Vector3.Angle(targetDirection, transform.forward);
                     //Check if player is in field of view
                    if (angleToPlayer >= -feildOfView && angleToPlayer <= feildOfView)
                    {
                        Ray ray = new Ray(transform.position + (Vector3.up * eyeHeight), targetDirection);
                        RaycastHit hitInfo = new RaycastHit();
                        if (Physics.Raycast(ray, out hitInfo, sightDistance))
                        {
                            if (hitInfo.transform.gameObject == player)
                            {
                                //Debug.Log("Player detected by CanSeePlayer method.");
                                Debug.DrawRay(ray.origin, ray.direction * sightDistance);
                                return true;
                            }
                        }
                        //Debug.DrawRay(ray.origin, ray.direction * sightDistance, Color.red);
                        //Debug.DrawRay(ray.origin, ray.direction * sightDistance, Color.green);
                    }
                }
            }
            //Debug.Log("Player not detected by CanSeePlayer method.");
            return false;
        }

    }
}