using Cysharp.Threading.Tasks;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using TMPro;
using Unity.Netcode;
using Unity.Services.Authentication;
using UnityEngine;
using UnityEngine.Events;

public class StartHostModule : MonoBehaviour
{
    public MatchmakingService matchmakingService;
    public TextMeshProUGUI statusText;
    public UnityEvent OnDidStartHost;

    private CancellationTokenSource cancelToken;

    public void Cancel()
    {
        cancelToken?.Cancel();
        Debug.Log("Cancel Starting Host");
        NetworkManager.Singleton.Shutdown();
        if (AuthenticationService.Instance.IsSignedIn) {
            AuthenticationService.Instance.SignOut();
        }
    }

    public async void StartHost(MatchmakingService.LobbyData data)
    {
        cancelToken = new CancellationTokenSource();
        while (!cancelToken.IsCancellationRequested) {
            Debug.Log("Join Quick Match");
            statusText.gameObject.SetActive(true);
            if (Authentication.IsLoggedIn() == false) {
                Debug.Log("Will log in");
                statusText.text = "logging in...";
                await Authentication.Login();
                statusText.text = "Did log in";
                Debug.Log("Did log in");
            }
            Debug.Log("Will create lobby");
            statusText.text = "Creating Lobby...";
            await matchmakingService.CreateLobbyWithAllocation(data);
            statusText.text = "Created Lobby";
            try {
                Debug.Log("Will host match");

                statusText.text = "Starting Host...";
                // Starting the host immediately will keep the relay server alive
                if (NetworkManager.Singleton.StartHost() == false) {
                    statusText.text = "failed to start host";
                    await UniTask.Delay(TimeSpan.FromMilliseconds(2000), ignoreTimeScale: false);
                    continue;
                }

                statusText.text = "started host";
                OnDidStartHost?.Invoke();
                NetworkSceneDirector.instance.LoadSingleScene("Lobby", () => { });
                return;
            }
            catch (Exception e) {
                statusText.text = "Error: " + e.ToString();
                await UniTask.Delay(TimeSpan.FromMilliseconds(2000), ignoreTimeScale: false);
                Debug.LogError(e);
                continue;
            }
        }
    }
}
