using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using BaseGames.Core;
using BaseGames.Core.Events;
using BaseGames.Player;
namespace BaseGames.UI
{
///
/// 能力解锁总览面板(数据驱动)。据 列出全部能力 + 已解锁/未解锁态。
/// 在场景中找 读 ;
/// 订阅 (EVT_AbilityUnlocked) 实时刷新解锁态。
/// 策划改 UI_AbilityMeta 即增删/重排能力、改标签图标;美术改 UI_AbilityCell / 面板预制件改样式。
///
public class DataDrivenAbilityPanel : MonoBehaviour
{
[Header("数据 / 单元格")]
[SerializeField] private AbilityMetaSO _meta;
[Tooltip("能力格的父节点(通常挂 GridLayoutGroup)。")]
[SerializeField] private Transform _container;
[SerializeField] private AbilityCellView _cellPrefab;
[Header("引用")]
[SerializeField] private Button _btnClose;
[Header("Event Channels")]
[Tooltip("能力解锁广播(AbilityType payload),用于实时刷新。对应 EVT_AbilityUnlocked。")]
[SerializeField] private AbilityTypeEventChannelSO _onAbilityUnlocked;
private readonly List<(AbilityCellView view, AbilityType type)> _cells = new();
private readonly CompositeDisposable _subs = new();
private PlayerStats _stats;
private void Awake() => _btnClose?.onClick.AddListener(OnClose);
private void OnEnable()
{
_onAbilityUnlocked?.Subscribe(_ => RefreshStates()).AddTo(_subs);
_stats = FindObjectOfType(true); // 游戏内有玩家;菜单态为 null(全部显示未解锁)
BuildList();
}
private void OnDisable() => _subs.Clear();
/// 据 AbilityMetaSO 重建能力格(public 以便编辑器/测试)。
public void BuildList()
{
ClearList();
if (_meta == null || _container == null || _cellPrefab == null) return;
foreach (var item in _meta.Items)
{
var cell = Instantiate(_cellPrefab, _container);
cell.gameObject.SetActive(true);
cell.Bind(item.labelKey, item.icon, IsUnlocked(item.type));
_cells.Add((cell, item.type));
}
}
private void RefreshStates()
{
if (_stats == null) _stats = FindObjectOfType(true);
foreach (var (view, type) in _cells)
if (view != null) view.SetUnlocked(IsUnlocked(type));
}
private bool IsUnlocked(AbilityType type) => _stats != null && _stats.HasAbility(type);
private void ClearList()
{
_cells.Clear();
if (_container == null) return;
for (int i = _container.childCount - 1; i >= 0; i--)
{
var c = _container.GetChild(i).gameObject;
if (Application.isPlaying) Destroy(c); else DestroyImmediate(c);
}
}
private void OnClose()
{
var uiMgr = ServiceLocator.GetOrDefault();
if (uiMgr != null) uiMgr.CloseTopPanel();
else gameObject.SetActive(false);
}
}
}