using UnityEngine;

public class Turret : MonoBehaviour
{
    [Header("References")]
    [SerializeField] private TurretBullet _bulletPrefab;
    [SerializeField] private Transform _bulletSpawnPoint;
    [Header("Stats")]
    [SerializeField] private float _reloadTime = 1f;
    [SerializeField] private float _damage;
    [SerializeField] private float _distance = 3f;
    [Header("Economy")]
    [SerializeField] private int _price;
    [SerializeField] private float _sellingMultiplier = 0.5f;
    [Header("Upgrade")]
    [SerializeField] TurretUpgrade[] _upgrades;

    private float _reloadTimer;
    private int _lvl;

    public int Price => _price;
    public float Damage => _damage;
    public float Distance => _distance;
    public int SellPrice => Mathf.RoundToInt(_price * _sellingMultiplier);
    public int UpgradeCost
    {
        get
        {
            if (IsMaxLevel)
                return 0;

            return Mathf.RoundToInt(_price * _upgrades[_lvl].UpgradeConstMultiplier);
        }
    }
    public bool IsMaxLevel => _lvl >= _upgrades.Length;
    public int Level => _lvl + 1;
    public int MaxLevel => _upgrades.Length;

    private void Start()
    {
        if (_bulletSpawnPoint == null)
            _bulletSpawnPoint = transform;
    }

    public void Upgrade()
    {
        if (IsMaxLevel)
            return;

        var upgrade = _upgrades[_lvl++];
        if (upgrade.BulletPrefab != null)
            _bulletPrefab = upgrade.BulletPrefab;

        if (upgrade.UpgradeDistanceMultiplier != -1)
        {
            if (_damage == 0)
                _damage = upgrade.UpgradeDamageMultiplier;
            else
                _damage *= upgrade.UpgradeDamageMultiplier;
        }

        if (upgrade.UpgradeDistanceMultiplier != -1)
        {
            if (_distance == 0)
                _distance = upgrade.UpgradeDistanceMultiplier;
            else
                _distance *= upgrade.UpgradeDistanceMultiplier;
        }

        if (upgrade.UpgradeReloadTimeMultiplier != -1)
            _reloadTime *= upgrade.UpgradeReloadTimeMultiplier;
    }

    private void Update()
    {
        SpawnBullet(Vector3.forward);
        SpawnBullet(Vector3.back);
        SpawnBullet(Vector3.left);
        SpawnBullet(Vector3.right);

        _reloadTimer += Time.deltaTime;
    }

    private void SpawnBullet(Vector3 direction)
    {
        if (_reloadTimer < _reloadTime || !DetectEnemy(direction))
            return;

        _bulletPrefab.Spawn(this, _bulletSpawnPoint.position, direction);
        _reloadTimer = 0f;
    }

    private bool DetectEnemy(Vector3 direction) =>
        Physics.Raycast(transform.position, direction, out var hit, _bulletPrefab.Distance + _distance) &&
        hit.transform.TryGetComponent(out Enemy _);
}
