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

public class ConnectMatchModule : MonoBehaviour
{
    public MatchmakingService matchmakingService;

    public TextMeshProUGUI statusText;
    public UnityEvent OnDidJoinMatch;

    Task task;

    private CancellationTokenSource cancelToken;

    public void JoinMatch(Lobby match)
    {
        task = _JoinMatch(match);
    }

    public void Cancel()
    {
        cancelToken?.Cancel();
        Debug.Log("Cancel Join Match");
        NetworkManager.Singleton.Shutdown();
    }

    async Task _JoinMatch(Lobby match)
    {
        cancelToken = new CancellationTokenSource();
        while (!cancelToken.IsCancellationRequested) {
            if (NetworkManager.Singleton.IsClient || NetworkManager.Singleton.IsServer) {
                Debug.Log("Shutting Down Previous Match");
                NetworkManager.Singleton.Shutdown();
            }

            try {
                statusText.text = "Joining Match...";
                Debug.Log("Will join match");
                await matchmakingService.JoinLobbyWithAllocation(match.Id);

                if (NetworkManager.Singleton.StartClient() == false) {
                    statusText.text = "Could not join match, trying again...";
                    await UniTask.Delay(TimeSpan.FromMilliseconds(2000), ignoreTimeScale: false);
                    continue;
                }
                NetworkSceneDirector.instance.OnClientStarted(true);
                Debug.Log("Did join match");
                statusText.text = "Did join Match...";
                OnDidJoinMatch?.Invoke();
                return;
            }
            catch (Exception e) {
                Debug.LogError(e);
            }

            Debug.Log("Could not find match");
            statusText.text = "Could join Match, trying again...";
            await UniTask.Delay(TimeSpan.FromMilliseconds(2000), ignoreTimeScale: false);
        }
    }
}
