using UnityEngine;
using EventsAppQuest.Core;

namespace EventsAppQuest.Presentation
{
    /// <summary>
    /// Camada de gaze-like aiming: usa o alvo actual "à frente" da câmera/rig e acumula tempo de estabilidade.
    /// Quando o mesmo alvo permanece estável durante RequiredStabilitySeconds, repassa para targeting/hover.
    /// Não substitui raycast nem fallback; coexiste com prioridade configurável (AimingMode).
    /// </summary>
    public class QuestGazeLikeController : MonoBehaviour
    {
        [Tooltip("Tempo em segundos que o alvo deve permanecer no centro/forward para ser considerado estável.")]
        [SerializeField] private float _requiredStabilitySeconds = 0.5f;

        private QuestGazeLikeState _state;
        private string _lastTargetId;
        private float _stabilityAccumulator;

        /// <summary>Estado actual do gaze-like (pode ser null se inactivo).</summary>
        public QuestGazeLikeState CurrentState => _state;

        /// <summary>Tempo requerido de estabilidade em segundos.</summary>
        public float RequiredStabilitySeconds => _requiredStabilitySeconds;

        /// <summary>Define o tempo requerido de estabilidade.</summary>
        public void SetRequiredStabilitySeconds(float seconds)
        {
            _requiredStabilitySeconds = Mathf.Max(0.1f, seconds);
        }

        /// <summary>
        /// Actualiza o estado de gaze-like com o alvo actualmente à frente da câmera (ex.: do raycast ou simulado).
        /// Chamar cada frame após obter o hit/pointer.
        /// </summary>
        /// <param name="currentTargetIdInFront">Id do alvo no centro/forward (null se nenhum).</param>
        /// <param name="deltaTime">Tempo desde o último frame.</param>
        /// <param name="sourceDescription">Descrição da origem (ex.: "XRRaycast", "CenterScreenSimulated").</param>
        /// <returns>Estado actualizado (IsActive, CurrentGazeTargetId, StabilityElapsedSeconds, IsStableEnough).</returns>
        public QuestGazeLikeState UpdateGazeLike(string currentTargetIdInFront, float deltaTime, string sourceDescription = "CameraForward")
        {
            if (string.IsNullOrEmpty(currentTargetIdInFront))
            {
                _state = new QuestGazeLikeState
                {
                    IsActive = false,
                    CurrentGazeTargetId = null,
                    StabilityElapsedSeconds = 0f,
                    RequiredStabilitySeconds = _requiredStabilitySeconds,
                    IsStableEnough = false,
                    SourceDescription = sourceDescription
                };
                _lastTargetId = null;
                _stabilityAccumulator = 0f;
                return _state;
            }

            _state = _state ?? new QuestGazeLikeState();
            _state.IsActive = true;
            _state.RequiredStabilitySeconds = _requiredStabilitySeconds;
            _state.SourceDescription = sourceDescription;

            if (currentTargetIdInFront != _lastTargetId)
            {
                _lastTargetId = currentTargetIdInFront;
                _stabilityAccumulator = 0f;
            }

            _stabilityAccumulator += deltaTime;
            _state.CurrentGazeTargetId = currentTargetIdInFront;
            _state.StabilityElapsedSeconds = _stabilityAccumulator;
            _state.IsStableEnough = _stabilityAccumulator >= _requiredStabilitySeconds;
            return _state;
        }

        /// <summary>Progresso normalizado de estabilidade (0 a 1) para feedback visual.</summary>
        public float GetStabilityProgressNormalized()
        {
            if (_state == null || _requiredStabilitySeconds <= 0f) return 0f;
            return Mathf.Clamp01(_state.StabilityElapsedSeconds / _requiredStabilitySeconds);
        }
    }
}
