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 & Code
private TMP_Text textStatus;
private TMP_Text textLobbyCodeValue;
private Button btnCopyCode;
// Tabs
private Button btnHostTab;
private Button btnJoinTab;
// Join
private TMP_InputField inputLobbyCode;
private Button btnConnect;
// Host
private TMP_Dropdown ddMaxPlayers;
private Toggle tgPublicLobby;
private Button btnCreateLobby;
// Players
private TMP_Text textPlayerCount;
private ScrollRect scrollPlayers;
private Transform contentPlayers;
private GameObject playerItemTemplate;
private GameObject emptyPlayers;
// Friends picker (fallback when overlay unavailable)
private GameObject panelFriends;
private Transform contentFriends;
private GameObject emptyFriends;
private Button btnBackFromFriends;
private Button btnCloseFriendsOverlay;
// Host controls
private Button btnInviteFriends;
private Button btnKickSelected;
// Ready & footer
private Button btnToggleReady;
private Button btnStartGame;
private Button btnLeaveLobby;
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 void Awake()
{
// Find UI (including inactive)
panelLobby = FindAnyGO("Panel_Lobby");
groupJoin = FindAnyGO("Group_Join");
groupHost = FindAnyGO("Group_Host");
textStatus = FindText("Text_Status");
textLobbyCodeValue = FindText("Text_LobbyCodeValue");
btnCopyCode = FindButton("Button_CopyCode");
btnHostTab = FindButton("Button_HostTab");
btnJoinTab = FindButton("Button_JoinTab");
inputLobbyCode = FindInput("Input_LobbyCode");
btnConnect = FindButton("Button_Connect");
ddMaxPlayers = FindDropdown("Dropdown_MaxPlayers");
tgPublicLobby = FindToggle("Toggle_PublicLobby");
btnCreateLobby = FindButton("Button_CreateLobby");
textPlayerCount = FindText("Text_PlayerCount");
scrollPlayers = FindScroll("Scroll_Players");
contentPlayers = FindAnyGO("Content_PlayersList")?.transform;
emptyPlayers = FindAnyGO("Empty_Players");
playerItemTemplate = FindAnyGO("PlayerItemTemplate");
btnInviteFriends = FindButton("Button_InviteFriends");
btnKickSelected = FindButton("Button_KickSelected");
btnToggleReady = FindButton("Button_ToggleReady");
btnStartGame = FindButton("Button_StartGame");
btnLeaveLobby = FindButton("Button_LeaveLobby");
btnBackFromLobby = FindButton("Button_BackFromLobby");
// Friends picker
panelFriends = FindAnyGO("Panel_Friends");
contentFriends = FindAnyGO("Content_FriendsList")?.transform;
emptyFriends = FindAnyGO("Empty_Friends");
btnBackFromFriends = FindButton("Button_BackFromFriends");
btnCloseFriendsOverlay = FindButton("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