using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class Monster : MonoBehaviour
{
    private Building _target = null;
    [SerializeField] private float _speedMps = 1.0f;
    [SerializeField] private float _life = 0.0f;
    [SerializeField] private float _maxRange = 0.1f;
    [SerializeField] private float _damagePerHit = 1.0f;

    [SerializeField] private float _damageCooldown = 0.5f;
    [Header("Noise")]
    [SerializeField] private float _durationNoise = 0.1f;
    [SerializeField] private float _amplitudeOnKill = 0.1f;
    [SerializeField] private float _frequenceOnKill = 1.0f;

    public GameObject _view;
    private Animator _animator;
    private SpriteRenderer _spriteRendered;
    private bool _movement = false;
    private float _damageCooldownTimer = 0.0f;
    private bool _isKilled = false;
    private BuildingManager _buildingManager = null;

    [SerializeField] private UnityEvent _onMonsterKilled = null;

    #region Events
    private event Action<Monster> _onKilledEvent = null;
    public event Action<Monster> OnKilled
    {
        add
        {
            _onKilledEvent -= value;
            _onKilledEvent += value;
        }
        remove
        {
            _onKilledEvent -= value;
        }
    }
    #endregion Events



    public void Initiliaze()
    {
        _buildingManager = GameSceneManager.Instance.BuildingManager;
        _target = _buildingManager.GetRandomBuild();
        _target.Attacked(this);
        _movement = true;
		_animator = _view.GetComponent<Animator>();
		_spriteRendered = _view.GetComponent<SpriteRenderer>();
    }

    private void Update()
    {
        if (_isKilled || GameManager.Instance.IsGamePlaying == false)
            return;
        if (_movement)
        {
			_animator.SetBool("Move", true);
            Vector2 dir = (Vector2)(_target.transform.position - transform.position);
            Vector2 velocity = dir;
			_spriteRendered.flipX = dir.x < 0;
            if (velocity.magnitude > _speedMps * Time.deltaTime)
            {
                velocity = dir.normalized * _speedMps * Time.deltaTime;
            }
            transform.position += (Vector3)(velocity);
            Debug.DrawRay((Vector2)transform.position, dir);
            if (dir.magnitude < _maxRange)
            {
                _movement = false;
				_animator.SetBool("Move", false);
				_animator.SetBool("Attack", true);
            }
        }
        else
        {
            if (_damageCooldownTimer > _damageCooldown)
            {
                _damageCooldownTimer = 0.0f;
                _target.Damage(_damagePerHit);
            }
            else
            {
                _damageCooldownTimer += Time.deltaTime;
            }
        }
    }


    public void OnBuildingKilled()
    {
        _target = _buildingManager.GetRandomBuild();
        _target.Attacked(this);
        _movement = true;
    }

    public void Hurt(float damage)
    {
        _life -= damage;
        if (_life <= 0.0f)
        {
            _isKilled = true;
            _target.OnMonsterKilled(this);
            _onMonsterKilled?.Invoke();
            _onKilledEvent?.Invoke(this);
            GameObject.Destroy(gameObject, 2.0f);
            NoiseManager.Instance.PlayNoise(_amplitudeOnKill, _frequenceOnKill, _durationNoise);
        }
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (_isKilled)
            return;
        if (collision.TryGetComponent(out IMonsterKiller drill))
        {
            if (drill.Enable)
            {
                Hurt(drill.Damage);
            }
        }
    }
}
