using FishNet;
using FishNet.Discovery;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class NetworkMenuUI : MonoBehaviour
{
    [Header("UI References")]
    public Button startPlayingButton;
    public Button joinMultiplayerButton;
    public Transform serverListContainer;
    public GameObject serverListItemPrefab;
    public TMP_Text statusText;

    [Header("Networking")]
    public NetworkDiscovery networkDiscovery;
    public Camera uiCamera; // Optional, disable if connecting

    private readonly List<IPEndPoint> foundServers = new();

    private void Start()
    {
        if (networkDiscovery == null)
            networkDiscovery = FindObjectOfType<NetworkDiscovery>();

        startPlayingButton.onClick.AddListener(OnStartPlaying);
        joinMultiplayerButton.onClick.AddListener(OnJoinMultiplayer);

        networkDiscovery.ServerFoundCallback += OnServerFound;
    }

    private void OnStartPlaying()
    {
        statusText.text = "Starting host...";
        StartCoroutine(HostAndSearchRoutine());
    }


    private void OnJoinMultiplayer()
    {
        statusText.text = "Searching for servers...";
        ClearServerList();
        foundServers.Clear();
        networkDiscovery.StartSearchingForServers();
    }

    private void OnServerFound(IPEndPoint endPoint)
    {
        if (foundServers.Contains(endPoint)) return;
        foundServers.Add(endPoint);

        // Auto-join if started as host
        if (InstanceFinder.IsServer)
        {
            //networkDiscovery.StopAdvertisingServer();
            networkDiscovery.StopSearchingForServers();

            uiCamera.enabled = false;

            InstanceFinder.ClientManager.StartConnection("192.168.42.212");
            statusText.text = $"Joined server: {endPoint.Address}";
            return;
        }

        // Display in UI for manual joining
        GameObject item = Instantiate(serverListItemPrefab, serverListContainer);
        TMP_Text label = item.GetComponentInChildren<TMP_Text>();
        label.text = endPoint.Address.ToString();

        Button btn = item.GetComponent<Button>();
        btn.onClick.AddListener(() =>
        {
            networkDiscovery.StopSearchingForServers();
            if (uiCamera != null) uiCamera.enabled = false;
            InstanceFinder.ClientManager.StartConnection(endPoint.Address.ToString());
            statusText.text = $"Joined server: {endPoint.Address}";
        });
    }
    private Coroutine joinRoutine;

    private IEnumerator HostAndSearchRoutine()
    {
        // Step 1: Start hosting
        InstanceFinder.ServerManager.StartConnection();

        // Step 2: Start advertising
        yield return new WaitForSeconds(0.5f); // Let the server settle
        networkDiscovery.StartAdvertisingServer();

        // Step 3: Begin searching
        yield return new WaitForSeconds(0.5f); // Let advertisement initialize
        networkDiscovery.StartSearchingForServers();

        // Step 4: Try to find and join a better server
        yield return new WaitForSeconds(0.5f); // Give discovery a moment
        StartJoinRoutine();
    }


    public void StartJoinRoutine()
    {
        if (joinRoutine != null) StopCoroutine(joinRoutine);
        joinRoutine = StartCoroutine(TryJoinServerRepeatedly());
    }

    private IEnumerator TryJoinServerRepeatedly()
    {
        float timeout = 10f;
        float timer = 0f;

        while (timer < timeout)
        {
            if (foundServers.Count > 0)
            {
                var firstServer = foundServers[0];
                //networkDiscovery.StopAdvertisingServer();
                networkDiscovery.StopSearchingForServers();
                InstanceFinder.ClientManager.StartConnection(firstServer.Address.ToString());
                statusText.text = $"Joined server: {firstServer.Address}";
                yield break;
            }

            statusText.text = $"Searching for servers... ({Mathf.FloorToInt(timer)}s)";
            yield return new WaitForSeconds(1f);
            timer += 1f;
        }


        statusText.text = "No servers found. Acting as host.";
        // You can optionally start your own server here
    }

    private void ClearServerList()
    {
        foreach (Transform child in serverListContainer)
        {
            Destroy(child.gameObject);
        }
    }
}