using UnityEngine;

public class MineColliderManager : ColliderManager
{
    public AudioClip mineHitSFX;
    public ParticleSystem effectA;
    public ParticleSystem effectB;

    public float explosionDistance;

    private GameObject _player;

    // Bool checks if the mine has been hit, this is because the ships are made of multiple collision boxes and would trigger more than once.
    private bool _mineHit = false;

    public float magnetizedTime;
    private bool _magnetHit = false;
    private TimerHelper _magnetizeTime;
    public Material magnetizedMaterial;

    public float spawnImmunityTime;
    private TimerHelper _immuneTimer;
    private bool _spawnImmune;

    public bool Hit
    {
        get
        {
            return _mineHit;
        }
    }

    private void Start()
    {
        _player = GameObject.Find("Player");
        _magnetizeTime = new TimerHelper(magnetizedTime, false);
        _spawnImmune = true;
        _immuneTimer = new TimerHelper(spawnImmunityTime, false);
    }

    public override void ProcessCollision(CollisionDirection direction, Collision collision, bool wasChild)
    {
        if (collision.gameObject.tag == "Enemy")
        {
            EnemyColliderManager enemyColliderManager = collision.gameObject.GetComponent<EnemyColliderManager>();
            if (enemyColliderManager != null)
            {
                if (enemyColliderManager.Magnetized)
                {
                    magnetizeMine();
                }
            }            
        }
        HitMine();
    }

    public void magnetizeMine()
    {
        if (!_magnetHit)
        {
            if (magnetizedMaterial != null)
            {
                Transform mineChild = gameObject.transform.Find("MineAlt");
                if (mineChild != null)
                {
                    MeshRenderer mineModel = mineChild.gameObject.GetComponent<MeshRenderer>();
                    if (mineModel != null)
                    {
                        Material[] materials = new Material[mineModel.materials.Length];
                        mineModel.materials.CopyTo(materials, 0);
                        materials[0] = magnetizedMaterial;
                        mineModel.materials = materials;
                    }
                }
            }
            explosionDistance *= 1.3f;
            _magnetHit = true;
            _magnetizeTime.RestartTimer();
        }
    }

    private void Update()
    {
        if (_magnetHit)
        {
            if (_magnetizeTime.HasTicked(Time.deltaTime))
            {
                HitMine();
            }
        }
        if (_spawnImmune)
        {
            if (_immuneTimer.HasTicked(Time.deltaTime))
            {
                _spawnImmune = false;
            }
        }
    }

    /// <summary>
    /// Process the mine exploding and destroy the mine object.
    /// </summary>
    public void HitMine()
    {
        // If the mine has been hit ignore it.
        if (!_mineHit && !_spawnImmune)
        {
            if (_magnetHit)
            {
                Collider[] collidersInRange = Physics.OverlapSphere(gameObject.transform.position, explosionDistance);
                foreach (Collider currentCollider in collidersInRange)
                {
                    Rigidbody colliderRB = currentCollider.attachedRigidbody;
                    if (colliderRB != null)
                    {
                        GameObject colliderGO = currentCollider.attachedRigidbody.gameObject;
                        if (colliderGO.CompareTag("Enemy"))
                        {
                            EnemyColliderManager currentColliderManager = colliderGO.GetComponent<EnemyColliderManager>();
                            if (currentColliderManager != null)
                            {
                                currentColliderManager.DestoryEnemy(true);
                            }

                        }
                        else if (colliderGO.CompareTag("Mine"))
                        {
                            MineColliderManager currentMineCM = colliderGO.GetComponent<MineColliderManager>();
                            if (currentMineCM != null && !currentMineCM.Hit)
                            {
                                currentMineCM.magnetizeMine();
                            }
                        }
                    }                    
                }
            }

            float playerDistance = (_player.transform.position - transform.position).magnitude;

            _mineHit = true;
            AudioSource.PlayClipAtPoint(mineHitSFX, transform.position);
            ParticleSystem boomboom = Instantiate(effectA);
            ParticleSystem boomboom2 = Instantiate(effectB);
            boomboom.transform.position = transform.position;
            boomboom2.transform.position = transform.position;
            boomboom.transform.localScale = boomboom.transform.localScale * explosionDistance;
            boomboom2.transform.localScale = boomboom2.transform.localScale * explosionDistance;
            if (playerDistance <= explosionDistance)
            {
                PlayerColliderManager playerColliderManager = _player.GetComponent<PlayerColliderManager>();
                if (playerColliderManager)
                {
                    playerColliderManager.PlayerHit();
                }
            }

            if (transform.childCount > 0)
            {
                for (int i = 0; i < transform.childCount; i++)
                {
                    transform.GetChild(i).gameObject.SetActive(false);
                }
            }

            gameObject.layer = LayerMask.NameToLayer("ExplodedMine");
            Destroy(gameObject, 2.0f);
        }
    }
}
