using System;
using Cybe;
using UniRx;
using UnityEngine;
using Zenject;

namespace Sources
{
    public class Gun : MonoBehaviour
    {
        [SerializeField] private Transform _owner;
        [SerializeField] private Bullet _bullet;
        [SerializeField] private Transform _shotPoint;

        [Inject] private AudioManager _audioManager;
        [Inject] private DiContainer _container;
        [Inject] private Player _player;

        private float _currentDamage;
        private float _currentCooldown;
        private float _currentFlySpeed;
        private bool _isAttacking;

        public void SubscribeDamage(ReactiveProperty<int> damageLevel)
        {
            damageLevel.ObserveEveryValueChanged(v => v.Value)
                .Subscribe(value => _currentDamage = (20 + 5 * _player.CurrentLevel) * Mathf.Pow(1.5f, value));
        }
        
        public void SubscribeCooldown(ReactiveProperty<int> cooldownLevel)
        {
            cooldownLevel.ObserveEveryValueChanged(v => v.Value)
                .Subscribe(value => _currentCooldown = 2 * Mathf.Pow(0.6f, value));
        }  
        
        public void SubscribeFlySpeed(ReactiveProperty<int> flySpeedLevel)
        {
            flySpeedLevel.ObserveEveryValueChanged(v => v.Value)
                .Subscribe(value => _currentFlySpeed = 1000 * (1 + value));
        }
        
        public void Attack(Vector3 target)
        {
            if (_isAttacking)
                return;
            
            _isAttacking = true;
            _audioManager.PlayFx(SoundType.BlasterShot);
            Observable.Timer(TimeSpan.FromSeconds(_currentCooldown)).Subscribe(_ => _isAttacking = false);

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