using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text;
namespace Zerolauncher.Manager
{
    internal class WebApiManager
    {
        static HttpListener listener = new HttpListener();
        static CancellationTokenSource cts = new CancellationTokenSource();
        public static async Task StartListener()
        {
            listener.Prefixes.Add("http://127.0.0.1:7233/");
            listener.Start();
            Trace.WriteLine("Listening...");

            while (!cts.Token.IsCancellationRequested)
            {
                HttpListenerContext context = await listener.GetContextAsync();
                HttpListenerRequest request = context.Request;
                HttpListenerResponse response = context.Response;
                var raw = request.RawUrl;
                ResponesBody? rb = null;
                if (raw != null && raw.Contains("?")) 
                {
                    var lines = raw.Split("?");
                    var args = request.QueryString;
                    var nick = args["name"];
                    if (nick != null)
                    {
                        var acc = TeamManager.Nick2Acc(nick);
                        if (acc != null)
                        {
                            switch (lines[0])
                            {
                                case "/CloseGame":
                                    {
                                        if (EngineManager.ExitGame(acc))
                                        {
                                            rb = new ResponesBody(1, 0, $"Account [{nick}] successful to close.");
                                        }
                                        else
                                        {
                                            rb = new ResponesBody($"Account [{nick}] is unluacher.");
                                            break;
                                        }
                                    }
                                    break;
                                case "/ToNormalSize":
                                    {
                                        switch (EngineManager.TurnGameSizeNormal(acc))
                                        {
                                            case 2:
                                                rb = new ResponesBody(1, 0, $"Account [{nick}] now is normal size.");
                                                break;
                                            case 1:
                                                rb = new ResponesBody(0, 0, $"Account [{nick}] is loading, please wait.");
                                                break;
                                            case 0:
                                                rb = new ResponesBody($"Account [{nick}] is unluacher.");
                                                break;
                                        }
                                    }
                                    break;
                                case "/ToMiniSize":
                                    {
                                        switch (EngineManager.TurnGameSizeMini(acc))
                                        {
                                            case 2:
                                                rb = new ResponesBody(1, 0, $"Account [{nick}] now is mini size.");
                                                break;
                                            case 1:
                                                rb = new ResponesBody(0, 0, $"Account [{nick}] is loading, please wait.");
                                                break;
                                            case 0:
                                                rb = new ResponesBody($"Account [{nick}] is unluacher.");
                                                break;
                                        }
                                    }
                                    break;
                                case "/LoginGame":
                                    {
                                        if (EngineManager.CreateGame(acc))
                                        {
                                            rb = new ResponesBody(0, 0, $"Account [{nick}] successful to start.");
                                        }
                                        else
                                        {
                                            int hwnd = EngineManager.CheckGameState(acc);
                                            if (hwnd <= 0)
                                            {
                                                rb = new ResponesBody(0, 0, $"Account [{nick}] is loading, please wait.");
                                            }
                                            else
                                            {
                                                rb = new ResponesBody(1, hwnd, $"Account [{nick}] now is running.");
                                            }
                                        }
                                    }
                                    break;
                                default:
                                    rb = new ResponesBody($"commad [{lines[0]}] undefind.");
                                    break;
                            }
                        }
                        else
                        {
                            rb = new ResponesBody($"Account [{nick}] undefind.");
                        }
                    }
                    else
                    {
                        rb = new ResponesBody("args is missing.");
                    }

                }
                if (rb == null) 
                {
                    rb = new ResponesBody();
                }
                byte[] buffer = Encoding.UTF8.GetBytes(rb.Encode());

                response.ContentLength64 = buffer.Length;
                Stream output = response.OutputStream;
                await output.WriteAsync(buffer, 0, buffer.Length);
                output.Close();
            }
            listener.Stop();
        }

        public static void StopListener() { cts.Cancel(); }
    }

    class ResponesBody
    {
        public int status;
        public int hwnd;
        public string message;

        public ResponesBody(string message)
        {
            this.status = -1;
            this.hwnd = 0;
            this.message = message;
        }

        public ResponesBody(int status=-1, int hwnd=0, string message= "Hello, World!")
        {
            this.status = status;
            this.hwnd = hwnd;
            this.message = message;
        }

        public string Encode()
        {
            return $"{{\"state\": {status}, \"hwnd\": {hwnd}, \"message\": \"{message}\"}}";
        }
    }
}
