using System;
using Cybe;
using Sources;
using Sources.Enemies;
using UniRx;
using UnityEngine;
using Zenject;
using Random = UnityEngine.Random;

public class Hawk : AggrableEnemy
{
    [SerializeField] private Rigidbody _rb;
    [SerializeField] private float _speed = 50;
    [SerializeField] private float _turning = 50;
    [SerializeField] private float _cooldown = 0.2f;
    [SerializeField] private float _attackDistance = 10;
    [SerializeField] private float _damage = 5;
    [SerializeField] private Bullet _bullet;
    [SerializeField] private Transform _shotPoint;

    [Inject] private AudioManager _audioManager;
    [Inject] private DiContainer _container;
    
    private Vector3 _moveDirection;
    private Vector3 _initialPosition;
    private bool _isAttacking;

    protected override void OnStart()
    {
        base.OnStart();

        _initialPosition = transform.position;

        _moveDirection = Random.rotation * Vector3.forward;
        _moveDirection.y = 0;
        _moveDirection = _moveDirection.normalized;
    }

    protected override void OnUpdate()
    {
        base.OnUpdate();

        ProcessAI();

        if (Target && Vector3.Distance(Target.transform.position, transform.position) <= _attackDistance)
        {
            Attack(Target.transform.position);
        }

        _rb.velocity = _moveDirection * _speed;
        transform.rotation = Quaternion.LookRotation(_moveDirection);
    }

    private void ProcessAI()
    {
        Vector3 dirToTarget;

        if (Target)
        {
            dirToTarget = Target.transform.position - transform.position;
        }
        else
        {
            dirToTarget = _initialPosition - transform.position;
        }

        dirToTarget.y = 0;
        dirToTarget = dirToTarget.normalized;

        var dot = Vector3.Dot(_moveDirection, dirToTarget);
        if (dot > 0.99f)
            return;

        var rotationDir = Vector3.Angle(dirToTarget, _moveDirection) > 180 ? 1 : -1;
        var turnAngle = rotationDir * _turning * Time.deltaTime;
        _moveDirection = Quaternion.Euler(0, turnAngle, 0) * _moveDirection;
    }
    
    private void Attack(Vector3 target)
    {
        if (_isAttacking)
            return;
            
        _isAttacking = true;
        _audioManager.PlayFx(SoundType.BlasterShot);
        Observable.Timer(TimeSpan.FromSeconds(_cooldown)).Subscribe(_ => _isAttacking = false);

        var shootDirection = target - _shotPoint.position;
        var bullet = _container.InstantiatePrefabForComponent<Bullet>(_bullet, _shotPoint.position, Quaternion.LookRotation(shootDirection), null);
            
        bullet.Shoot(_damage, shootDirection, transform);
    }
}