using System.Collections.Generic;
using System.IO;
using System.Text;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using RR.Common.Managers;
using RR.Common.Prizes;
namespace RR.Common.UI
{
///
/// Страница правил, которая динамически выводит призы за уровни из настроек призовой системы.
/// Повесьте компонент на GameObject страницы и назначьте TMP_Text либо оставьте поле пустым,
/// чтобы компонент нашёл первый TMP_Text в дочерних объектах.
///
[DisallowMultipleComponent]
public sealed class RulesPrizeListPage : MonoBehaviour
{
[Header("Text")]
[SerializeField] private TMP_Text targetText;
[Header("Content")]
[SerializeField] private string title = "Призы за уровни";
[SerializeField] private string emptyPrizeText = "без приза";
[SerializeField] private string noLevelsText = "Уровни не найдены.";
[SerializeField] private string unavailableText = "Настройки призов недоступны.";
[SerializeField] private bool showTitle = true;
[SerializeField] private bool showLevelsWithoutPrize = true;
[Header("Levels")]
[SerializeField] private bool includeOnlyLevelsFolder = true;
[SerializeField] private string levelsFolderName = "Levels";
[SerializeField] private List ignoredSceneNames = new() { "MainMenu", "Level UI" };
private void Awake()
{
ResolveText();
}
private void OnEnable()
{
Refresh();
}
[ContextMenu("Refresh Prize List")]
public void Refresh()
{
ResolveText();
if (targetText == null)
{
Debug.LogWarning($"[{nameof(RulesPrizeListPage)}] TMP_Text не найден на странице правил.", this);
return;
}
PrizeSystemManager manager = PrizeSystemManager.Instance;
PrizeDatabase database = manager != null ? manager.Database : null;
if (database == null)
{
targetText.text = unavailableText;
return;
}
List levels = GetLevelSceneNames();
if (levels.Count == 0)
{
levels.AddRange(database.GetAll().Keys);
levels.Sort();
}
if (levels.Count == 0)
{
targetText.text = noLevelsText;
return;
}
StringBuilder builder = new();
if (showTitle && !string.IsNullOrWhiteSpace(title))
{
builder.AppendLine(title);
builder.AppendLine();
}
for (int i = 0; i < levels.Count; i++)
{
string levelName = levels[i];
LevelPrizeConfig config = database.GetConfig(levelName);
if (!showLevelsWithoutPrize && (config == null || config.type == PrizeType.None))
{
continue;
}
builder.Append(levelName);
builder.Append(" — ");
builder.Append(BuildPrizeText(manager, config));
if (i < levels.Count - 1)
{
builder.AppendLine();
}
}
string result = builder.ToString().TrimEnd();
targetText.text = string.IsNullOrWhiteSpace(result) ? noLevelsText : result;
}
private void ResolveText()
{
if (targetText == null)
{
targetText = GetComponent();
}
if (targetText == null)
{
targetText = GetComponentInChildren(true);
}
}
private List GetLevelSceneNames()
{
List result = new();
int sceneCount = SceneManager.sceneCountInBuildSettings;
for (int i = 0; i < sceneCount; i++)
{
string scenePath = SceneUtility.GetScenePathByBuildIndex(i);
if (string.IsNullOrWhiteSpace(scenePath))
{
continue;
}
string normalizedPath = scenePath.Replace("\\", "/");
if (includeOnlyLevelsFolder)
{
string folderToken = $"/{levelsFolderName}/";
if (!normalizedPath.Contains(folderToken))
{
continue;
}
}
string sceneName = Path.GetFileNameWithoutExtension(scenePath);
if (ignoredSceneNames != null && ignoredSceneNames.Contains(sceneName))
{
continue;
}
result.Add(sceneName);
}
return result;
}
private string BuildPrizeText(PrizeSystemManager manager, LevelPrizeConfig config)
{
if (config == null || config.type == PrizeType.None)
{
return emptyPrizeText;
}
return config.type switch
{
PrizeType.QRCode => BuildQrPrizeText(manager, config.qrTier),
PrizeType.Hopper => $"хоппер, капсул: {Mathf.Max(1, config.hopperCapsuleCount)}",
PrizeType.PrizeStand => BuildPrizeStandText(manager),
_ => config.type.ToString()
};
}
private static string BuildQrPrizeText(PrizeSystemManager manager, QRTier tier)
{
string tierText = tier switch
{
QRTier.Bronze => "бронзовый QR-код",
QRTier.Silver => "серебряный QR-код",
QRTier.Gold => "золотой QR-код",
_ => "QR-код"
};
string prizeText = manager != null ? manager.GetQRCodeModalPrizeText(tier) : string.Empty;
return string.IsNullOrWhiteSpace(prizeText)
? tierText
: $"{tierText}: {prizeText.Trim()}";
}
private static string BuildPrizeStandText(PrizeSystemManager manager)
{
PrizeStandSettings settings = manager != null ? manager.GetPrizeStandSettings() : null;
int boxCount = settings?.boxes != null ? settings.boxes.Count : 0;
return boxCount > 0 ? $"призовая витрина, ячеек: {boxCount}" : "призовая витрина";
}
}
}