using GeoSus.Client;
using System.Collections;
using System.Threading.Tasks;
using UnityEngine;
using System.Collections.Generic;
using Subsystems;
using System.Linq;

namespace Subsystems
{
    public class GameManager_Network
    {
        private const string _serverAddress = "geosus.honzuvkod.dev";
        private const int _serverPort = 7777;
        private GameClient _gameClient;
        private GameManager_Map _mapSubsystem;
        public async void OpenConection()
        {
            while (true)
            {
                Task<bool> state = _gameClient.ConnectAsync(_serverAddress, _serverPort);
                await state;
                if (state.Result)
                {
                    Debug.Log("Connected to server.");
                    break;
                }
                else
                {
                    Debug.Log("Failed to connect to server");
                }
                await Task.Delay(5000);
            }
        }
        public GameManager_Network(GameClient gameClient)
        {
            _gameClient = gameClient;
            RegisterEventHandlers();
        }
        public void RegisterEventHandlers()
        {
            _gameClient.OnConnected += OnConnected;
            _gameClient.OnDisconnected += OnDisconnected;
            _gameClient.OnError += OnError;
            _gameClient.OnMessage += OnMessage;
            _gameClient.OnGameEvent += OnGameEvent;
        }
        private void OnConnected()
        {
            Debug.Log("Successfully connected to the server.");
        }
        private void OnDisconnected(string reason)
        {
            Debug.Log($"Host disconnected due to {reason}");
        }
        private void OnError(string error)
        {
            Debug.LogError($"Network error: {error}");
        }
        private void OnMessage(Message message)
        {
            switch (message.Type)
            {
                case "GameEvent":
                    OnGameEvent(message as GameEvent);
                    break;
                case "CreateLobbyResponse":
                    Debug.Log("Received CreateLobbyResponse message");
                    HandleCreateLobbyResponse(message as CreateLobbyResponse);
                    break;
                case "JoinLobbyResponse":
                    Debug.Log("Received JoinLobbyResponse message");
                    HandleJoinLobbyResponse(message as JoinLobbyResponse);
                    break;
                case "Ack":
                    Debug.Log("Received Ack message");
                    break;
                default:
                    Debug.Log("Received message of type: " + message.Type);
                    break;
            }
        }
        private void OnGameEvent(GameEvent gameEvent)
        {
            switch (gameEvent.EventType)
            {
                case "PlayerJoined":
                    Debug.Log($"Player {gameEvent.GetPayload<PlayerJoinedPayload>().DisplayName} joined");
                    break;
                case "PlayerLeft":
                    Debug.Log($"Player {gameEvent.GetPayload<PlayerLeftPayload>()} left");
                    break;
                case "GameStarting":
                    Debug.Log("Game is starting!");
                    break;
                case "GameStarted":
                    Debug.Log("Game started");
                    break;
                case "MapDataReady":
                    Debug.Log("Map data ready");
                    break;
                case "PlayerMapDataReceived":
                    Debug.Log("Player map data recieved");
                    break;
                case "MapDataError":
                    Debug.Log("Received MapData server error");
                    break;
                default:
                    Debug.Log("Received GameEvent of type: " + gameEvent.EventType);
                    break;
            }
        }
        private void HandleCreateLobbyResponse(CreateLobbyResponse message)
        {
            if (message.Success)
            {
                Debug.Log("Lobby created successfully. Join Code: " + message.JoinCode + ", Lobby ID: " + message.LobbyId);
            }
            else
            {
                Debug.LogError("Failed to create lobby: " + message.Error);
            }
        }
        private void HandleJoinLobbyResponse(JoinLobbyResponse message)
        {
            if (message.Success)
            {
                Debug.Log("Lobby created successfully." + ", Lobby ID: " + message.LobbyId);
            }
            else
            {
                Debug.LogError("Failed to create lobby: " + message.Error);
            }
        }
        public void CrateLobby(double lat, double lon)
        {
            _gameClient.CreateLobby(new Position(lat, lon));
        }
        public void JoinLobby(string joinCode)
        {
            try
            {
                _gameClient.JoinLobby(joinCode);
            }
            catch (System.Exception ex)
            {
                Debug.LogError("Error joining lobby: " + ex.Message);
            }
        }
        public void LeaveLobby()
        {
            _gameClient.Disconnect();
            Application.Quit();
        }
        public void StartGame()
        {
            _gameClient.StartGame();

        }
    }
}

