using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading.Tasks;
using Unity.Services.Authentication;
using Unity.Services.Core;
using Sirenix.OdinInspector;
using System;
using Unity.Netcode;
using Unity.Services.Lobbies.Models;
using UnityEngine.Events;
#if UNITY_EDITOR
using ParrelSync;
#endif

public class NetworkingModule : MonoBehaviour
{
    public MatchmakingService matchmakingService;
    public string PlayerId;
	
	public UnityEvent OnSignedInEvent;
	public UnityEvent OnConnectingEvent;
	public UnityEvent OnEnterLobby;

	public void CreatePrivateLobby()
    {
		CreateLobby();
	}

	public void RandomMatching()
	{
		_ = _RandomMatching();
	}

	public void JoinPrivateLobby(Lobby lobby)
	{
		_ = JoinLobby(lobby);
	}

	public void LeaveLobby()
    {
        matchmakingService.LeaveLobby();
	}

	async Task _Login()
	{
		OnConnectingEvent.Invoke();
		await Authentication.Login();
		OnSignedInEvent.Invoke();
	}

	async Task _RandomMatching()
    {
		if (Authentication.IsLoggedIn() == false) {
			await Authentication.Login();
		}
		var allLobbies = await matchmakingService.GatherLobbies();
		if (allLobbies.Count > 0) {
			await JoinLobby(allLobbies[0]);
			return;
		}
		Debug.Log("Could not find match");
	}

	async void CreateLobby()
	{
		OnConnectingEvent.Invoke();

		MatchmakingService.LobbyData data;
		data.Name = "Lobby";
		data.MaxPlayers = 10;
		data.Difficulty = 0;
		data.Type = 0;
		data.MatchId = "";

		try {
            await matchmakingService.CreateLobbyWithAllocation(data);

			// Starting the host immediately will keep the relay server alive
			NetworkManager.Singleton.StartHost();

			NetworkSceneDirector.instance.LoadSingleScene("Lobby");
            OnEnterLobby.Invoke();
		}
		catch (Exception e) {
			Debug.LogError(e);
			CanvasUtilities.Instance.ShowError("Failed creating lobby");
			OnSignedInEvent.Invoke();//return to main connect menu
		}
	}

	async Task JoinLobby(Lobby lobby)
	{
		OnConnectingEvent.Invoke();

        if (NetworkManager.Singleton.IsClient || NetworkManager.Singleton.IsServer) {
            Debug.Log("Shutting Down Previous Match");
            NetworkManager.Singleton.Shutdown();
        }

        try {
			await matchmakingService.JoinLobbyWithAllocation(lobby.Id);

			NetworkManager.Singleton.StartClient();
			NetworkSceneDirector.instance.OnClientStarted(true);
			OnEnterLobby.Invoke();
		}
		catch (Exception e) {
			Debug.LogError(e);
			CanvasUtilities.Instance.ShowError("Failed joining lobby");
			OnSignedInEvent.Invoke();//return to main connect menu
		}
	}
}
