// 客户端
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
namespace AdamSync
{
    public class SyncCreateRoom
    {
        public static TcpClient client;
        public static NetworkStream stream;
        public static string serverReturnValue;

        public static Action<string> registRequset;
        public static Action<string> getusersRequset;
        public static Action<string> createRoomRequset;
        public static Action<string> getRoomsRequset;
        public static Action<string> getownRoomsRequset;
        public static Action<string> joinRoomRequset;
        public static Action<string> joinsRequset;
        public static Action<string> leaveRoomRequset;
        public static Action<string> closeRoomRequset;
        public static Action<ulong, string, string> playerInfoRequset;
        public static Action<string> getroomusersRequset;
        public static Action<string> send2roomRequset;
        public static Action<string> send2userRequset;
        public static Action<string> send2worldRequset;


        public static async Task StartLinkTCPServer(string serverIp, int serverPort)
        {
            client = new TcpClient();
            await client.ConnectAsync(serverIp, serverPort);
            stream = client.GetStream();
            await ReciveMessage();
        }


        public static async Task ReciveMessage()
        {
            CancellationTokenSource cts = new CancellationTokenSource();
            await ReadMessagesAsync(stream, cts.Token);
        }

        public static async Task SendMessageAsync(string message)
        {
            if (stream != null)
            {
                if (!string.IsNullOrEmpty(message))
                {
                    byte[] data = Encoding.UTF8.GetBytes($"{message}");
                    await stream.WriteAsync(data, 0, data.Length);
                }
            }
        }

        public static async Task ReadMessagesAsync(NetworkStream stream, CancellationToken cancellationToken)
        {
            byte[] buffer = new byte[8192];
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);
                    if (bytesRead > 0)
                    {
                        string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                        string[] commands = message.Split(' ');

                        if (commands.Length > 0)
                        {
                            //Debug.Log($"<color=green>commands[0]===={commands[0]}</color>");
                            switch (commands[0])
                            {
                                case "regist":
                                    registRequset?.Invoke(commands[1]);
                                    break;
                                case "getusers":
                                    getusersRequset?.Invoke(commands[1]);
                                    break;
                                case "createroom":
                                    createRoomRequset?.Invoke(commands[1]);
                                    break;
                                case "getrooms":
                                    getRoomsRequset?.Invoke(commands[1]);
                                    break;
                                case "getownrooms":
                                    getownRoomsRequset?.Invoke(commands[1]);
                                    break;
                                case "joinroom":
                                    joinRoomRequset?.Invoke(commands[1]);
                                    break;
                                case "joins":
                                    joinsRequset?.Invoke(commands[1]);
                                    break;
                                case "leaveroom":
                                    leaveRoomRequset?.Invoke(commands[1]);
                                    break;
                                case "closeroom":
                                    closeRoomRequset?.Invoke(commands[1]);
                                    break;
                                case "player":
                                    string[] data = commands[1].Split(';');
                                    if (data.Length == 3)
                                    {
                                        playerInfoRequset?.Invoke(ulong.Parse(data[0]), data[1], data[2]);
                                    }
                                    break;
                                case "getroomusers":
                                    getroomusersRequset?.Invoke(commands[1]);
                                    break;
                                case "send2room":
                                    send2roomRequset?.Invoke(commands[1]);
                                    break;
                                case "send2user":
                                    send2userRequset?.Invoke(commands[1]);
                                    break;
                                case "send2world":
                                    send2worldRequset?.Invoke(commands[1]);
                                    break;
                            }
                        }
                    }
                }
                catch (OperationCanceledException)
                {
                    // Ignore cancellation exceptions
                }
            }
        }

        public static void CloseClint()
        {
            client.Close();
            if (stream != null)
            {
                stream.Close();
                stream.Dispose();
            }
        }
    }
}