using System.Collections; using TMPro; using UnityEngine; using UnityEngine.UI; namespace MedievalShopkeeper { public class UIManager : MonoBehaviour { public static UIManager Instance { get; private set; } [Header("HUD Elements")] [Tooltip("Text element for showing Time of Day (e.g. 08:00)")] [SerializeField] private TextMeshProUGUI timeText; [Tooltip("Text element for showing current money")] [SerializeField] private TextMeshProUGUI moneyText; [Tooltip("Text element for showing customer count")] [SerializeField] private TextMeshProUGUI customersText; [Tooltip("Text element for showing event alerts (e.g. Goblin Raid!)")] [SerializeField] private TextMeshProUGUI alertText; [Header("Context Menu Panels")] [SerializeField] private GameObject shelfMenuPanel; [SerializeField] private GameObject npcMenuPanel; [SerializeField] private GameObject inventoryMenuPanel; [SerializeField] private GameObject tillMenuPanel; // Active context tracking private Shelf activeShelf; private CustomerNPC activeNPC; private PlayerController activePlayer; private ShopTill activeTill; [Header("Inventory Test Fields")] [Tooltip("Assign an ItemData here to test Buy/Sell/Discard buttons via the Inspector/UI until a full scrolling list is built.")] public ItemData testInventoryItem; public int testTransactionAmount = 5; private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; // Hide all menus initially CloseAllMenus(); if (alertText != null) alertText.gameObject.SetActive(false); } private void Start() { // Subscribe to GameManager events if (GameManager.Instance != null) { GameManager.Instance.OnTimeChanged += UpdateTimeUI; GameManager.Instance.OnMoneyChanged += UpdateMoneyUI; GameManager.Instance.OnCustomerCountChanged += UpdateCustomersUI; GameManager.Instance.OnRandomEventTriggered += ShowEventAlert; } else { Debug.LogWarning("[UIManager] GameManager.Instance is missing! HUD will not update."); } } private void OnDestroy() { if (GameManager.Instance != null) { GameManager.Instance.OnTimeChanged -= UpdateTimeUI; GameManager.Instance.OnMoneyChanged -= UpdateMoneyUI; GameManager.Instance.OnCustomerCountChanged -= UpdateCustomersUI; GameManager.Instance.OnRandomEventTriggered -= ShowEventAlert; } } #region HUD Updates private void UpdateTimeUI(int hour, int minute) { if (timeText != null) { timeText.text = $"{hour:D2}:{minute:D2}"; } } private void UpdateMoneyUI(int money) { if (moneyText != null) { moneyText.text = $"{money} G"; } } private void UpdateCustomersUI(int customers) { if (customersText != null) { customersText.text = $"Customers: {customers}"; } } private void ShowEventAlert(GameEvent gameEvent) { if (alertText == null) return; StopCoroutine(nameof(FadeAlertText)); StartCoroutine(FadeAlertText($"EVENT: {gameEvent}!")); } private IEnumerator FadeAlertText(string message) { alertText.text = message; alertText.gameObject.SetActive(true); alertText.alpha = 1f; // Wait 3 seconds yield return new WaitForSeconds(3f); // Fade out float fadeTime = 1.5f; float t = 0; while (t < fadeTime) { t += Time.deltaTime; alertText.alpha = Mathf.Lerp(1f, 0f, t / fadeTime); yield return null; } alertText.gameObject.SetActive(false); } #endregion #region Context Menus public void CloseAllMenus() { if (shelfMenuPanel != null) shelfMenuPanel.SetActive(false); if (npcMenuPanel != null) npcMenuPanel.SetActive(false); if (inventoryMenuPanel != null) inventoryMenuPanel.SetActive(false); if (tillMenuPanel != null) tillMenuPanel.SetActive(false); activeShelf = null; activeNPC = null; activePlayer = null; activeTill = null; } // --- SHELF MENU --- public void OpenShelfMenu(Shelf shelf, PlayerController player) { CloseAllMenus(); activeShelf = shelf; activePlayer = player; if (shelfMenuPanel != null) { shelfMenuPanel.SetActive(true); } else { Debug.LogWarning("[UIManager] Shelf Menu Panel is not assigned!"); } } public void UI_StockShelf() { if (activeShelf != null && activePlayer != null) { activeShelf.StockFromPlayer(activePlayer); } CloseAllMenus(); } public void UI_EmptyShelf() { if (activeShelf != null) { activeShelf.EmptyShelf(); } CloseAllMenus(); } public void UI_CheckShelf() { if (activeShelf != null) { string itemName = activeShelf.AssignedItem != null ? activeShelf.AssignedItem.itemName : "Empty"; Debug.Log($"[Shelf Status] Item: {itemName}, Stock: {activeShelf.CurrentStock}"); } } // --- NPC MENU --- public void OpenNPCMenu(CustomerNPC npc, PlayerController player) { CloseAllMenus(); activeNPC = npc; activePlayer = player; if (npcMenuPanel != null) { npcMenuPanel.SetActive(true); } else { Debug.LogWarning("[UIManager] NPC Menu Panel is not assigned!"); } } public void UI_TalkToNPC() { if (activeNPC != null) { activeNPC.TalkTo(); } CloseAllMenus(); } public void UI_KickOutNPC() { if (activeNPC != null) { activeNPC.KickOut(); } CloseAllMenus(); } public void UI_CheckNPC() { if (activeNPC != null) { Debug.Log($"[NPC Info] Name: {activeNPC.npcName}"); } } // --- TILL MENU --- public void OpenTillMenu(ShopTill till, System.Collections.Generic.List basket) { CloseAllMenus(); activeTill = till; if (tillMenuPanel != null) { tillMenuPanel.SetActive(true); // Here is where you would populate a dynamic UI list of icons. // Example debug output of what the UI should show: string basketContents = "Customer Basket: "; int total = 0; foreach(var item in basket) { if (item != null) { basketContents += $"[{item.itemName} ({item.sellPrice}G)] "; total += item.sellPrice; } } Debug.Log($"[UIManager] Till Opened. {basketContents} | Total: {total}G"); } else { Debug.LogWarning("[UIManager] Till Menu Panel is not assigned! Defaulting to auto-charge."); // Fallback if no UI panel if (activeTill != null) activeTill.ChargeCustomer(); } } public void UI_ChargeCustomer() { if (activeTill != null) { activeTill.ChargeCustomer(); } CloseAllMenus(); } // --- INVENTORY MENU --- public void OpenInventoryMenu(PlayerController player = null) { CloseAllMenus(); activePlayer = player; if (inventoryMenuPanel != null) { inventoryMenuPanel.SetActive(true); } else { Debug.LogWarning("[UIManager] Inventory Menu Panel is not assigned!"); } } public void UI_BuyTestItem() { if (testInventoryItem != null && ShopInventory.Instance != null) { bool success = ShopInventory.Instance.BuyStock(testInventoryItem, testTransactionAmount); if (success) { PlayerController targetPlayer = activePlayer != null ? activePlayer : FindObjectOfType(); if (targetPlayer != null) { ShopInventory.Instance.WithdrawToPlayer(testInventoryItem, testTransactionAmount, targetPlayer); CloseAllMenus(); } } } } public void UI_SellTestItem() { // Sell logic usually requires NPC interaction, but if selling back to supplier: if (testInventoryItem != null && ShopInventory.Instance != null) { if (ShopInventory.Instance.RemoveStock(testInventoryItem, testTransactionAmount)) { int totalSale = testInventoryItem.sellPrice * testTransactionAmount; GameManager.Instance.AddMoney(totalSale); Debug.Log($"[UIManager] Sold {testTransactionAmount}x {testInventoryItem.itemName} for {totalSale} G."); } } } public void UI_DiscardTestItem() { if (testInventoryItem != null && ShopInventory.Instance != null) { if (ShopInventory.Instance.RemoveStock(testInventoryItem, testTransactionAmount)) { Debug.Log($"[UIManager] Discarded {testTransactionAmount}x {testInventoryItem.itemName}."); } } } #endregion } }