using UnityEngine; using UnityEngine.UI; using Subsystems; using GeoSus.Client; using System.Collections.Generic; using System; using TMPro; namespace Subsystems { /// /// Reads from GameManager_Network.State (the authoritative GameState) and drives /// all in-game canvas panels. No business logic lives here. /// public class GameManager_UI { private GameClient _gameClient; private GameState _state => GameManager.Instance?.networkSubsystem?.State; // ── Canvas refs (wired by BindClientScene from Client.unity) ────────── public Canvas ClientCreateJoinLobby; public Canvas ClientInLobby; public Canvas ClientLoadingScreen; public Canvas ClientGameScreen; // ── HUD element refs (resolved once in BindClientScene) ─────────────── private TMP_Text _roleText; private TMP_Text _taskListText; private TMP_Text _taskProgressText; private Button _actionButton; private TMP_Text _actionButtonText; private TMP_Text _killCooldownText; private GameObject _sabotagePanel; private TMP_Text _sabotageTimerText; private GameObject _meetingPanel; private TMP_Text _meetingHeader; private Transform _meetingScrollContent; private TMP_Text _meetingFallbackText; private GameObject _voteResultPanel; private TMP_Text _voteResultText; private GameObject _gameEndPanel; private TMP_Text _gameEndText; private RectTransform _returnToLobbyBtn; private TMP_Text _toastText; private GameObject _toastGO; // ── Internal state ──────────────────────────────────────────────────── private bool _isDead; private bool _commsBlackout; private DateTime _sabotageMeltdownDeadline; private bool _sabotageTimerActive; private volatile bool _lobbyDirty; // Meeting vote-row references rebuilt each meeting private readonly List _voteRows = new List(); private string _pendingVoteResultDisplay; // shown after voting public GameManager_UI(GameClient gameClient) { _gameClient = gameClient; } public void NotifyLobbyChanged() => _lobbyDirty = true; public bool IsCommsBlackout => _commsBlackout; public bool IsPlayerDead => _isDead; // ── Scene binding ───────────────────────────────────────────────────── public void BindClientScene(Canvas createJoin, Canvas inLobby, Canvas loading, Canvas game) { ClientCreateJoinLobby = createJoin; ClientInLobby = inLobby; ClientLoadingScreen = loading; ClientGameScreen = game; foreach (var c in new[] { createJoin, inLobby, loading, game }) EnsureCanvasReady(c); if (createJoin) createJoin.gameObject.SetActive(false); if (inLobby) inLobby.gameObject.SetActive(false); if (loading) loading.gameObject.SetActive(false); if (game) game.gameObject.SetActive(false); if (game == null) return; var t = game.transform; _roleText = FindTMP(t, "Role"); _taskListText = FindTMP(t, "TaskList"); _taskProgressText = FindTMP(t, "TaskProgress"); _killCooldownText = FindTMP(t, "KillCooldown"); _sabotageTimerText = FindTMP(t, "SabotageTimer"); _gameEndText = FindTMP(t, "GameEndText"); _toastText = FindTMP(t, "Toast"); _meetingHeader = FindTMP(t, "MeetingHeader"); _meetingFallbackText = FindTMP(t, "MeetingPlayerList"); _voteResultText = FindTMP(t, "VoteResult"); _meetingScrollContent = FindTransform(t, "MeetingContent"); var actionGO = t.Find("ActionButton"); if (actionGO != null) { _actionButton = actionGO.GetComponent