using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using MegaKoop.Steam;
using MegaKoop.Networking;
using MegaKoop.Game.Networking;
using TMPro;
namespace MegaKoop.UI
{
///
/// UGUI Multiplayer Lobby Controller integrated with SteamLobbyService.
/// Builds players list dynamically, handles host/join/invite/kick/ready/start.
///
public class UGUIMultiplayerLobbyController : MonoBehaviour
{
// Panels
[Header("Optional Root Ref (assigned by builder)")]
[SerializeField] private GameObject panelLobbyRef;
private GameObject panelLobby;
private GameObject groupJoin;
private GameObject groupHost;
[Header("Manual Wiring - Header & Code")]
[SerializeField] private TMP_Text textStatus;
[SerializeField] private TMP_Text textLobbyCodeValue;
[SerializeField] private Button btnCopyCode;
[Header("Manual Wiring - Tabs")]
[SerializeField] private Button btnHostTab;
[SerializeField] private Button btnJoinTab;
[Header("Manual Wiring - Join Section")]
[SerializeField] private TMP_InputField inputLobbyCode;
[SerializeField] private Button btnConnect;
[Header("Manual Wiring - Host Section")]
[SerializeField] private TMP_Dropdown ddMaxPlayers;
[SerializeField] private Toggle tgPublicLobby;
[SerializeField] private Button btnCreateLobby;
[Header("Manual Wiring - Players List")]
[SerializeField] private TMP_Text textPlayerCount;
[SerializeField] private ScrollRect scrollPlayers;
[SerializeField] private Transform contentPlayers;
[SerializeField] private GameObject playerItemTemplate;
[SerializeField] private GameObject emptyPlayers;
[Header("Manual Wiring - Friends Picker")]
[SerializeField] private GameObject panelFriends;
[SerializeField] private Transform contentFriends;
[SerializeField] private GameObject emptyFriends;
[SerializeField] private Button btnBackFromFriends;
[SerializeField] private Button btnCloseFriendsOverlay;
[Header("Manual Wiring - Host Controls")]
[SerializeField] private Button btnInviteFriends;
[SerializeField] private Button btnKickSelected;
[Header("Manual Wiring - Footer")]
[SerializeField] private Button btnToggleReady;
[SerializeField] private Button btnStartGame;
[SerializeField] private Button btnLeaveLobby;
[SerializeField] private Button btnBackFromLobby;
[Header("Player Ready Styling")]
[SerializeField] private Color readyBorderColor = new Color(0.2f, 0.82f, 0.35f, 1f);
[SerializeField] private Color notReadyBorderColor = new Color(0.85f, 0.25f, 0.25f, 1f);
[SerializeField] private float avatarBorderThickness = 12f;
// Selection
private string selectedPlayerSteamId = string.Empty;
// Cached readiness state per member
private readonly Dictionary memberReadyCache = new Dictionary();
// Steam service
private SteamLobbyService steam;
private LobbyGameSceneCoordinator lobbyGameCoordinator;
private SteamCoopNetworkManager coopNetworkManager;
// Local state cache
private bool IsInLobby => steam != null && steam.IsInLobby;
private bool IsHost => steam != null && steam.IsHost;
private string LobbyCode => steam != null ? steam.LobbyCode : string.Empty;
private bool clientStartedFromSignal = false;
private bool leftDueToKick = false;
private bool inviteOverlayRequested = false;
private void Awake()
{
// Find UI (including inactive)
panelLobby = EnsureGO(panelLobby, "Panel_Lobby");
groupJoin = EnsureGO(groupJoin, "Group_Join");
groupHost = EnsureGO(groupHost, "Group_Host");
textStatus = EnsureText(textStatus, "Text_Status");
textLobbyCodeValue = EnsureText(textLobbyCodeValue, "Text_LobbyCodeValue");
btnCopyCode = EnsureButton(btnCopyCode, "Button_CopyCode");
btnHostTab = EnsureButton(btnHostTab, "Button_HostTab");
btnJoinTab = EnsureButton(btnJoinTab, "Button_JoinTab");
inputLobbyCode = EnsureInput(inputLobbyCode, "Input_LobbyCode");
btnConnect = EnsureButton(btnConnect, "Button_Connect");
ddMaxPlayers = EnsureDropdown(ddMaxPlayers, "Dropdown_MaxPlayers");
tgPublicLobby = EnsureToggle(tgPublicLobby, "Toggle_PublicLobby");
btnCreateLobby = EnsureButton(btnCreateLobby, "Button_CreateLobby");
textPlayerCount = EnsureText(textPlayerCount, "Text_PlayerCount");
scrollPlayers = EnsureScroll(scrollPlayers, "Scroll_Players");
contentPlayers = EnsureTransform(contentPlayers, "Content_PlayersList");
emptyPlayers = EnsureGO(emptyPlayers, "Empty_Players");
playerItemTemplate = EnsureGO(playerItemTemplate, "PlayerItemTemplate");
btnInviteFriends = EnsureButton(btnInviteFriends, "Button_InviteFriends");
btnKickSelected = EnsureButton(btnKickSelected, "Button_KickSelected");
btnToggleReady = EnsureButton(btnToggleReady, "Button_ToggleReady");
btnStartGame = EnsureButton(btnStartGame, "Button_StartGame");
btnLeaveLobby = EnsureButton(btnLeaveLobby, "Button_LeaveLobby");
btnBackFromLobby = EnsureButton(btnBackFromLobby, "Button_BackFromLobby");
// Friends picker
panelFriends = EnsureGO(panelFriends, "Panel_Friends");
contentFriends = EnsureTransform(contentFriends, "Content_FriendsList");
emptyFriends = EnsureGO(emptyFriends, "Empty_Friends");
btnBackFromFriends = EnsureButton(btnBackFromFriends, "Button_BackFromFriends");
btnCloseFriendsOverlay = EnsureButton(btnCloseFriendsOverlay, "Button_CloseFriendsOverlay");
EnsureSteamServices();
RegisterSteamEvents();
WireButtonEvents();
ValidateUI();
// Initial view: Host tab
ShowHostTab();
UpdateUI();
}
private void ShowFriendsPanel()
{
if (panelFriends) panelFriends.SetActive(true);
EnsureFriendsGridSetup();
RebuildFriendsList();
}
private void HideFriendsPanel()
{
if (panelFriends) panelFriends.SetActive(false);
}
private void RebuildFriendsList()
{
if (contentFriends == null || steam == null) return;
// Clear existing
var toDestroy = new List();
foreach (Transform child in contentFriends) toDestroy.Add(child.gameObject);
foreach (var go in toDestroy) DestroyImmediate(go);
var friends = steam.GetFriends();
if (friends.Count == 0)
{
if (emptyFriends) emptyFriends.SetActive(true);
return;
}
if (emptyFriends) emptyFriends.SetActive(false);
foreach (var f in friends)
{
// Icon button cell only
var cell = new GameObject($"Friend_{f.steamId}", typeof(RectTransform), typeof(Image), typeof(Button));
cell.transform.SetParent(contentFriends, false);
var img = cell.GetComponent();
if (steam.TryGetAvatarSprite(f.steamId, out var spr, false)) { img.sprite = spr; img.color = Color.white; img.preserveAspect = true; }
else { img.sprite = null; img.color = new Color(0.3f,0.6f,0.3f,1f); }
var rt = (RectTransform)cell.transform; rt.sizeDelta = new Vector2(72,72);
var btn = cell.GetComponent