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

public class ChaseAttachedPowerUpEffect : AttachablePowerUpEffect
{
    private GameObject _player;
    private PlayerObjectShared _playerObjectShared;
    private Rigidbody _playerRigidBody;

    public float chargeForce;
    public float targetRange;
    public GameObject selectorGO;

    private GameObject _currentTarget;

    public float scanCooldown;
    private bool _scanCooldown;
    private TimerHelper _scanTimer;

    private Queue<GameObject> _scannedObjects = new Queue<GameObject>();

    // Start is called before the first frame update
    void Start()
    {
        _player = GameEngine.mainPlayer;
        _playerObjectShared = _player.GetComponent<PlayerObjectShared>();
        _playerRigidBody = _player.GetComponent<Rigidbody>();
        _abilityCooldown = false;
        _abilityCooldownTimer = new TimerHelper(abilityCooldown, false);
        _scanCooldown = false;
        _scanTimer = new TimerHelper(scanCooldown, false);
    }

    public override bool OnUseEffect()
    {
        if (!_abilityCooldown)
        {
            PlayerColliderManager playerCM = _player.GetComponent<PlayerColliderManager>();
            if (playerCM != null)
            {
                playerCM.SetImmune(2.0f);
            }

            if (_currentTarget != null)
            {
                Vector3 directionToTarget = _currentTarget.transform.position - _player.transform.position;
                _playerRigidBody.AddForce(directionToTarget.normalized * chargeForce, ForceMode.VelocityChange);
            }
            else
            {
                _playerRigidBody.AddForce(_player.transform.forward * chargeForce, ForceMode.VelocityChange);
            }            

            Transform particleEffect = powerUpModel.transform.Find("PowerUsed");
            if (particleEffect != null)
            {
                ParticleSystem particleSys = particleEffect.gameObject.GetComponent<ParticleSystem>();
                particleSys.Play();
            }

            if (onUseSFX != null)
            {
                _playerObjectShared.PlaySFX(onUseSFX);
            }

            _abilityCooldown = true;
            _abilityCooldownTimer.RestartTimer();
            return true;
        }
        else
        {
            return false;
        }
    }

    public override bool OnAltUseEffect()
    {
        if (!_abilityCooldown)
        {
            if (!_scanCooldown)
            {
                bool result = false;
                Queue<GameObject> currentScan = new Queue<GameObject>();
                RaycastHit[] raycastHits = Physics.SphereCastAll(_player.transform.position, 30.0f, _player.transform.forward, targetRange, LayerMask.GetMask("Enemies"));                
                if (raycastHits.Length > 0)
                {
                    foreach (RaycastHit currentHit in raycastHits)
                    {                        
                        GameObject currentGO = currentHit.transform.gameObject;
                        if (currentGO.tag != "Asteroid")
                        {
                            if (!currentScan.Contains(currentGO))
                            {
                                currentScan.Enqueue(currentGO);
                                if (!_scannedObjects.Contains(currentGO))
                                {
                                    _scannedObjects.Enqueue(currentGO);
                                }
                            }
                        }
                    }
                }

                 _scannedObjects = new Queue<GameObject>(_scannedObjects.Where(s => currentScan.Any(c => c == s)));

                if (_scannedObjects.Count > 0)
                {
                    if (_currentTarget != null)
                    {
                        Transform lastTargetGO = _currentTarget.transform.Find("ShipModel/Target");
                        if (lastTargetGO != null)
                        {
                            Destroy(lastTargetGO.gameObject);
                        }
                    }

                    _currentTarget = _scannedObjects.Dequeue();
                    if (_currentTarget != null)
                    {
                        Transform shipModel = _currentTarget.transform.Find("ShipModel");
                        if (shipModel != null)
                        {
                            GameObject newTarget = Instantiate(selectorGO, shipModel);
                            newTarget.name = "Target";
                        }
                    }
                    result = true;
                }
                else
                {
                    if (_currentTarget != null)
                    {
                        Transform lastTargetGO = _currentTarget.transform.Find("ShipModel/Target");
                        if (lastTargetGO != null)
                        {
                            Destroy(lastTargetGO.gameObject);
                        }
                    }
                    _currentTarget = null;
                }

                if (onAltSFX != null)
                {
                    _playerObjectShared.PlaySFX(onAltSFX);
                }

                _scanTimer.RestartTimer();
                _scanCooldown = true;

                return true;
            }
            else
            {
                return true;
            }
        }
        else
        {
            return false;
        }

        
    }

    private void OnDestroy()
    {
        if (_currentTarget != null)
        {
            Transform lastTargetGO = _currentTarget.transform.Find("ShipModel/Target");
            if (lastTargetGO != null)
            {
                Destroy(lastTargetGO.gameObject);
            }
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (_abilityCooldown)
        {
            if (_abilityCooldownTimer.HasTicked(Time.deltaTime))
            {
                _abilityCooldown = false;
            }
        }

        if (_scanCooldown)
        {
            if (_scanTimer.HasTicked(Time.deltaTime))
            {
                _scanCooldown = false;
            }
        }

        if (_currentTarget != null)
        {
            uiReadyText = "Target Locked!";
        }
        else
        {
            uiReadyText = "Charge Ready";
        }
    }
}
