using UnityEngine;

namespace Shooter.Gameplay
{
    /// <summary>
    /// Базовый класс любого оружия в игре. Хранит характеристики (урон, темп
    /// стрельбы, боезапас, разброс) и умеет стрелять очередями с отдачей и
    /// тряской камеры.
    ///
    /// ВАЖНО: конкретные пушки наследуются от этого класса — <see cref="PWeapon_Pistol"/>
    /// и <see cref="PWeapon_Shotgun"/>. Они переопределяют <see cref="FireWeapon"/>
    /// (свой рисунок разброса) и заводят собственный Update (свой темп стрельбы).
    /// Поэтому встроенная ниже система очередей — это «поведение по умолчанию» для
    /// простого оружия, а не то, что работает у боевых пистолета и дробовика.
    /// </summary>
    public class Weapon_Base : MonoBehaviour
    {
        [Header("Идентификация")]
        [Tooltip("Числовой ID оружия (для сохранений и каталога)")]
        public int WpnID = 0;
        [Tooltip("Название оружия, видно игроку в интерфейсе")]
        public string Title = "SMG 1";
        [Tooltip("Иконка оружия для HUD")]
        public Sprite WeaponIcon;

        [Header("Темп стрельбы")]
        [Tooltip("Автоматическое оружие стреляет, пока зажата кнопка огня")]
        public bool AutoFire = true;
        [Tooltip("Пауза между выстрелами внутри очереди, сек")]
        public float FireDelay = 0.2f;
        [Tooltip("Пауза между очередями, сек")]
        public float BurstDelay = .5f;
        [Tooltip("Сколько выстрелов в одной очереди")]
        public int BurstFireCount = 3;
        [Tooltip("Как быстро гаснет отдача (больше — быстрее)")]
        public float RecoilSpeed = 5;

        [Header("Боезапас")]
        [Tooltip("Патронов при получении оружия")]
        public int InitAmmo = 80;
        [Tooltip("Максимум патронов")]
        public int MaxAmmo = 80;
        [Tooltip("Сколько патронов добавляет один пикап")]
        public int AddAmmo = 10;
        [Tooltip("Максимум патронов в усиленном режиме")]
        public int PowerWeaponMaxAmmo = 80;
        [Tooltip("Бесконечные патроны (для отладки/боссов)")]
        public bool InfiniteAmmo = false;

        [Header("Пуля и урон")]
        [Tooltip("Урон одной пули")]
        public float Damage = 1;
        [Tooltip("Скорость полёта пули")]
        public float ProjectileSpeed = 200;
        [Tooltip("Дальность выстрела")]
        public float Range = 100;
        [Tooltip("Сколько пуль вылетает за один выстрел (1 — точно, 3 — веер)")]
        public int SpreadCount = 3;
        [Tooltip("Угол между соседними пулями веера, градусы")]
        public float SpreadAngleStep = 10f;
        [Tooltip("Через сколько секунд исчезает пуля, если ни во что не попала")]
        public float BulletLifetime = 5f;

        [Header("Эффект выстрела")]
        [Tooltip("Через сколько секунд удаляется эффект (вспышка) выстрела")]
        public float EffectLifetime = 3f;
        [Tooltip("Длительность тряски камеры при выстреле игрока")]
        public float ShakeDuration = .2f;
        [Tooltip("Сила тряски камеры при выстреле игрока")]
        public float ShakeStrength = 1f;

        [Header("Префабы и точки")]
        [Tooltip("Модель оружия в руках")]
        public GameObject WeaponModelPrefab;
        [Tooltip("Префаб пули")]
        public GameObject BulletPrefab;
        [Tooltip("Префаб эффекта выстрела (вспышка)")]
        public GameObject EffectPrefab;
        [Tooltip("Точка, откуда вылетают пули")]
        public Transform m_FirePoint;
        [Tooltip("Точка крепления эффекта выстрела")]
        public Transform m_ParticlePoint;
        [Tooltip("Кто стреляет (объект игрока/врага) — передаётся пуле как источник урона")]
        public GameObject m_Owner;

        // --- Состояние во время игры (не задаётся в Инспекторе) ---
        [HideInInspector] public bool WeaponEnable = true;    // оружие выдано и готово
        [HideInInspector] public int AmmoCount = 50;          // текущие патроны
        [HideInInspector] public PlayerControl Owner;         // владелец-игрок (если стреляет игрок)
        [HideInInspector] public bool Input_FireHold = false; // в этом кадре зажата кнопка огня
        [HideInInspector] public Vector3 Forward;             // направление ствола
        [HideInInspector] public int m_PowerLevel = 0;        // 0 — обычный режим, 1 — усиленный

        // Таймеры считаются к нулю в Update; нулевой таймер = «готово».
        [HideInInspector] public float FireDelayTimer = 0;    // задержка до следующего выстрела
        [HideInInspector] public float BurstDelayTimer = 0;   // задержка до следующей очереди
        [HideInInspector] public int BurstFireCounter = 0;    // сделано выстрелов в текущей очереди
        [HideInInspector] public float RecoilTimer = 0;       // текущая отдача (1 = максимум, гаснет к 0)

        void Update()
        {
            // Гасим все таймеры к нулю.
            FireDelayTimer = Mathf.Max(0, FireDelayTimer - Time.deltaTime);
            BurstDelayTimer = Mathf.Max(0, BurstDelayTimer - Time.deltaTime);
            RecoilTimer = Mathf.Max(0, RecoilTimer - RecoilSpeed * Time.deltaTime);

            // Стреляем, только если кнопка зажата и оба таймера «отпустили».
            if (Input_FireHold && FireDelayTimer == 0 && BurstDelayTimer == 0)
            {
                if (AmmoCount > 0 || InfiniteAmmo)
                {
                    // Тряска камеры — только когда стреляет именно игрок.
                    if (Owner == PlayerControl.MainPlayerController)
                        CameraControl.m_Current.StartShake(ShakeDuration, ShakeStrength);

                    FireWeapon();
                    AmmoCount -= 1;
                    RecoilTimer = 1;            // запускаем импульс отдачи
                    BurstFireCounter++;

                    // Очередь закончилась — уходим на паузу между очередями.
                    if (BurstFireCounter >= BurstFireCount)
                    {
                        BurstDelayTimer = BurstDelay;
                        BurstFireCounter = 0;
                    }
                }

                FireDelayTimer = FireDelay; // ждём перед следующим выстрелом
            }

            // Ввод действует один кадр: владелец заново выставит его в следующем.
            Input_FireHold = false;
        }

        /// <summary>
        /// Делает один выстрел: пускает веер из <see cref="SpreadCount"/> пуль и
        /// создаёт эффект вспышки. Наследники переопределяют этот метод, чтобы
        /// задать свой рисунок стрельбы.
        /// </summary>
        public virtual void FireWeapon()
        {
            // Центрируем веер относительно направления ствола: для 3 пуль и шага
            // 10° углы получаются −10°, 0°, +10°.
            float half = (SpreadCount - 1) / 2f;
            for (int i = 0; i < SpreadCount; i++)
            {
                float angle = (i - half) * SpreadAngleStep;

                GameObject bullet = Instantiate(BulletPrefab);
                bullet.transform.position = m_FirePoint.position;
                bullet.transform.forward = Quaternion.Euler(0, angle, 0) * m_FirePoint.forward;

                Projectile_Base proj = bullet.GetComponent<Projectile_Base>();
                proj.Creator = m_Owner;
                proj.Speed = ProjectileSpeed;
                proj.Damage = Damage;
                // Примечание: дальность (proj.m_Range) здесь не задаётся — пуля берёт
                // её из своего префаба. Наследники (пистолет/дробовик) задают явно.

                Destroy(bullet, BulletLifetime);
            }

            // Вспышка выстрела.
            GameObject effect = Instantiate(EffectPrefab);
            effect.transform.position = m_FirePoint.position;
            effect.transform.forward = m_FirePoint.forward;
            Destroy(effect, EffectLifetime);
        }
    }
}
