using UnityEngine;
using UnityEngine.UI;
using TMPro;
using Ashwild.Network;
using Ashwild.Player;
namespace Ashwild.UI
{
///
/// Lets the player paste a friend's session code and connect to their room. Validates the
/// code, launches the join through NetworkSessionManager, and mirrors the connection
/// progress (connecting / error) from the PlayerEvents bus into an on-screen status line.
///
public class JoinPanel : UIPanel
{
#region Serialized Fields
[Header("Code")]
[Tooltip("Where the player types/pastes the host's session code.")]
[SerializeField] private TMP_InputField codeInput;
[Header("Buttons")]
[SerializeField] private Button joinButton;
[SerializeField] private Button backButton;
[Header("Feedback")]
[Tooltip("Shows 'connecting…' / error messages. Optional.")]
[SerializeField] private TMP_Text statusText;
#endregion
#region State
///
/// True while a connection attempt is in flight (buttons locked, status shown).
///
private bool isConnecting;
#endregion
#region Unity Lifecycle
///
/// Wires the buttons and submit-on-enter; runs once.
///
protected override void Awake()
{
base.Awake();
joinButton.onClick.AddListener(AttemptJoin);
backButton.onClick.AddListener(() => UIManager.Instance.Back());
if (codeInput != null)
codeInput.onSubmit.AddListener(_ => AttemptJoin());
}
///
/// Subscribes to the session bus and resets the panel each time it is shown.
///
public override void Show()
{
base.Show();
PlayerEvents.SessionJoining += HandleSessionJoining;
PlayerEvents.SessionJoined += HandleSessionJoined;
PlayerEvents.SessionError += HandleSessionError;
ResetForInput();
}
///
/// Unsubscribes — mirrors Show exactly so the panel never reacts while hidden.
///
public override void Hide()
{
PlayerEvents.SessionJoining -= HandleSessionJoining;
PlayerEvents.SessionJoined -= HandleSessionJoined;
PlayerEvents.SessionError -= HandleSessionError;
base.Hide();
}
#endregion
#region Event Handlers
///
/// Connection attempt reached the transport — show progress.
///
private void HandleSessionJoining(string code) => SetStatus($"Connexion à {code}…");
///
/// Connected to the host — the networked scene load takes over from here.
///
private void HandleSessionJoined() => SetStatus("Connecté ! Chargement…");
///
/// Connection failed — surface the reason and re-enable input.
///
private void HandleSessionError(string reason)
{
SetStatus(reason);
isConnecting = false;
SetInteractable(true);
}
#endregion
#region Internal Helpers
///
/// Validates the typed code and launches the join through NetworkSessionManager.
///
private void AttemptJoin()
{
if (isConnecting) return;
string code = codeInput != null ? codeInput.text.Trim() : string.Empty;
if (string.IsNullOrEmpty(code))
{
SetStatus("Entre un code de session.");
return;
}
if (NetworkSessionManager.Instance == null)
{
Debug.LogError("[JoinPanel] NetworkSessionManager introuvable — la MenuScene doit contenir le NetworkManager.", this);
SetStatus("Erreur interne (NetworkManager manquant).");
return;
}
GameSession.Mode = GameSession.LaunchMode.Join;
GameSession.JoinCode = code;
isConnecting = true;
SetInteractable(false);
SetStatus("Connexion…");
NetworkSessionManager.Instance.JoinSession(code);
}
///
/// Clears the status line and re-enables input — used each time the panel opens.
///
private void ResetForInput()
{
isConnecting = false;
SetInteractable(true);
SetStatus(string.Empty);
}
///
/// Enables/disables the code field and join button during a connection attempt.
///
private void SetInteractable(bool interactable)
{
if (codeInput != null) codeInput.interactable = interactable;
if (joinButton != null) joinButton.interactable = interactable;
}
///
/// Writes a message to the optional status line.
///
private void SetStatus(string message)
{
if (statusText != null) statusText.text = message;
}
#endregion
}
}