using UnityEngine;
using TMPro;
using RR.Common.Controls;
using RR.Common.Managers;
using RR.Common.Prizes;
using RR.Common.Settings;
namespace RR.Common.UI
{
///
/// UI-компонент для отображения ошибки выдачи приза хоппером.
/// Подписывается на PrizeSystem.OnPrizeResult и показывает сообщение об ошибке,
/// если выдача приза завершилась неудачно (таймаут датчика).
///
/// Зависит от настройки prizes.showPrizeError.
///
public class PrizeErrorDisplay : MonoBehaviour
{
[Header("UI")]
[Tooltip("Текст сообщения об ошибке. Если не задан, ищется на этом же объекте.")]
[SerializeField] private TextMeshProUGUI errorText;
[Tooltip("Объект-контейнер ошибки (для скрытия/показа). Если не задан, используется gameObject.")]
[SerializeField] private GameObject errorContainer;
[Header("Настройки")]
[Tooltip("Текст ошибки, который отображается игроку.")]
[SerializeField] private string errorMessage = "Ошибка выдачи приза!";
[Header("Анимация")]
[Tooltip("CanvasGroup для плавного появления/исчезновения.")]
[SerializeField] private CanvasGroup canvasGroup;
[Tooltip("Длительность анимации появления/исчезновения.")]
[SerializeField] private float fadeDuration = 0.3f;
private bool _enabled;
private bool _isShowing;
private Coroutine _fadeCoroutine;
private void OnEnable()
{
if (errorContainer == null) errorContainer = gameObject;
if (errorText == null) errorText = GetComponentInChildren();
Hide(instant: true);
_enabled = SettingsManager.Instance != null
&& SettingsManager.Instance.GetBool("prizes.showPrizeError");
if (SettingsManager.Instance != null)
SettingsManager.Instance.OnSettingChanged += OnSettingChanged;
PrizeSystem.OnPrizeResult += OnPrizeResult;
// Подписываемся на новую систему призов (если доступна)
if (PrizeSystemManager.Instance != null)
PrizeSystemManager.Instance.OnAnyPrizeResult += OnAnyPrizeResult;
}
private void OnDisable()
{
if (SettingsManager.Instance != null)
SettingsManager.Instance.OnSettingChanged -= OnSettingChanged;
PrizeSystem.OnPrizeResult -= OnPrizeResult;
if (PrizeSystemManager.Instance != null)
PrizeSystemManager.Instance.OnAnyPrizeResult -= OnAnyPrizeResult;
}
private void OnSettingChanged(string key, SettingValue value)
{
if (key != "prizes.showPrizeError") return;
_enabled = value.b;
if (!_enabled)
Hide(instant: true);
}
private void OnPrizeResult(bool success)
{
if (success)
{
if (_isShowing) Hide();
}
else
{
Show();
}
}
private void OnAnyPrizeResult(PrizeType type, bool success)
{
// Показываем ошибку только для хоппера и витрины
if (type == PrizeType.QRCode) return;
if (success)
{
if (_isShowing) Hide();
}
else
{
Show();
}
}
///
/// Показывает сообщение об ошибке выдачи приза.
///
public void Show()
{
if (!_enabled) return;
_isShowing = true;
if (errorText) errorText.text = errorMessage;
errorContainer.SetActive(true);
if (canvasGroup)
{
if (_fadeCoroutine != null) StopCoroutine(_fadeCoroutine);
_fadeCoroutine = StartCoroutine(Fade(0f, 1f, fadeDuration));
}
Debug.LogWarning("[PrizeErrorDisplay] Ошибка выдачи приза отображена.");
}
///
/// Скрывает сообщение об ошибке.
///
public void Hide(bool instant = false)
{
_isShowing = false;
if (_fadeCoroutine != null)
{
StopCoroutine(_fadeCoroutine);
_fadeCoroutine = null;
}
if (instant || !canvasGroup)
{
if (canvasGroup) canvasGroup.alpha = 0f;
errorContainer.SetActive(false);
}
else
{
_fadeCoroutine = StartCoroutine(FadeAndDisable());
}
}
private System.Collections.IEnumerator FadeAndDisable()
{
yield return Fade(canvasGroup.alpha, 0f, fadeDuration);
errorContainer.SetActive(false);
_fadeCoroutine = null;
}
private System.Collections.IEnumerator Fade(float from, float to, float duration)
{
if (!canvasGroup) yield break;
float elapsed = 0f;
canvasGroup.alpha = from;
while (elapsed < duration)
{
elapsed += Time.unscaledDeltaTime;
canvasGroup.alpha = Mathf.Lerp(from, to, elapsed / duration);
yield return null;
}
canvasGroup.alpha = to;
}
}
}