using System;
using UnityEngine;
using UnityEngine.UI;

using BestHTTP;
using BestHTTP.WebSocket;
using System.Text;
using System.Text.RegularExpressions;

public class DemoUI : MonoBehaviour
{
    public GameObject console_window;
    public string Openid;
    public string Key;
    public string Pfkey;
    public int Port;

    public string CommandLine;
    public string[] CommandLineArgs;
    public  Text logList;
    public InputField inputReq;
    public InputField req_buy_vip_Input;
    public InputField req_pay_Input;
    public InputField start_path;

    private WebSocket webSocket;    //demo使用的是从网上download下来的besthttp库给游戏参考（未测试过兼容性），游戏可使用自己的websocket库

    // Start is called before the first frame update
    void Start()
    {
        CommandLine = Environment.CommandLine;
        CommandLineArgs = Environment.GetCommandLineArgs();

        if(CommandLine == "")
        {
            Debug.Log("启动命令行参数为空! 请检查测试环境");
            return;
        }

        Debug.Log("启动命令行参数：" + CommandLine);
        //解析命令行参数
        for (int i = 0; i < CommandLineArgs.Length; i++)
        {
            if (CommandLineArgs[i].Contains("port"))
            {
                string temppat = Regex.Replace(CommandLineArgs[i], @"[^0-9]+", "");
                Port = int.Parse(temppat);
                Debug.Log("解析到port=" + temppat);
            }
            if (CommandLineArgs[i].Contains("id="))
            {
                Openid = Regex.Replace(CommandLineArgs[i], "id=", "");
                Debug.Log("解析到Openid=" + Openid);
            };
            if (CommandLineArgs[i].Contains("key="))
            {
                Key = Regex.Replace(CommandLineArgs[i], "key=", "");
            };
            if (CommandLineArgs[i].Contains("pfkey="))
            {
                Pfkey = Regex.Replace(CommandLineArgs[i], "pfkey=", "");
            };
        }

        if(Port == 0 || Openid == "")
        {
            Debug.Log("未检查到openid和端口号! 请检查游戏是否配置了websocket启动");
            return;
        }
        
        init();
        Connect();
    }

    void Awake()
    {
        Application.logMessageReceived += HandleLog;
    }

    // Update is called once per frame
    void Update()
    {

    }

    void init() 
    {
        //大厅作为websocket服务端，Url由Port和Openid拼接
        string url = "ws://localhost:" + Port + "/websocket/" + Openid;
        Debug.Log("Url=" + url);

        webSocket = new WebSocket(new Uri(url));
        webSocket.OnOpen += OnOpen;
        webSocket.OnMessage += OnHallMessageReceived;
        webSocket.OnError += OnError;
        webSocket.OnClosed += OnClosed;
    }

    private void finalize()
    {
        webSocket.OnOpen = null;
        webSocket.OnMessage = null;
        webSocket.OnError = null;
        webSocket.OnClosed = null;
        webSocket = null;
    }

    private void OutputConsoleMsg(string msg)
    {
        Debug.Log(msg);
    }

    private void Connect()
    {
        webSocket.Open();
    }

    public void ReConnect()
    {
        if(webSocket != null && webSocket.IsOpen)
        {
            return;
        }

        init();
        Connect();
    }

    public void Close()
    {
        if(webSocket != null && webSocket.IsOpen)
        {
            webSocket.Close();
            finalize();
        }
    }

    public void SendMessageToHall(string cmd)
    {
        if (webSocket != null && webSocket.IsOpen)
        {
            webSocket.Send(cmd);
            OutputConsoleMsg("发送请求：" + cmd);
        }
        else
        {
            OutputConsoleMsg("连接已断开，消息发送失败");
        }
    }

    /// <summary>
    /// Called when the web socket is open, and we are ready to send and receive data
    /// </summary>
    void OnOpen(WebSocket ws)
    {
        OutputConsoleMsg("连接建立成功");
    }


    //接收到大厅的消息
    void OnHallMessageReceived(WebSocket ws, string message)
    {
        OutputConsoleMsg("收到大厅消息：" + message);
    }

    /// <summary>
    /// Called when the web socket closed
    /// </summary>
    void OnClosed(WebSocket ws, UInt16 code, string message)
    {
        OutputConsoleMsg("连接关闭：" + message);
    }

    /// <summary>
    /// Called when an error occured on client side
    /// </summary>
    void OnError(WebSocket ws, Exception ex)
    {
        string errorMsg = string.Empty;
        if (ws.InternalRequest.Response != null)
            errorMsg = string.Format("Status Code from Server: {0} and Message: {1}", ws.InternalRequest.Response.StatusCode, ws.InternalRequest.Response.Message);

        OutputConsoleMsg(errorMsg);
    }

    private void OnDestroy()
    {
        //游戏退出
        SendMessageToHall("{'cmd':'game_exit'}");

        if (webSocket != null && webSocket.IsOpen)
        {
            webSocket.Close();
            finalize();
        }
    }

    void HandleLog(string condition, string stackTrace, LogType type)
    {
        if (type == LogType.Error || type == LogType.Exception || type == LogType.Log)
        {
            string message = "==================================\n";
            if (type == LogType.Log)
            {
                message = condition;
            }
            else
            {
                message = "<color=red>" + string.Format("condition = {0} \n ", condition) + "</color>";
            }
            logList.text += message + "\n";
        }
    }


    //蓝钻请求测试，购买蓝钻参数参考文档 <https://open.qqgame.qq.com/wiki/24/35/46/51/51.html>
    /*例如拼接好的Param参数的JSON如下：{action: "openVip", appid: 1109981688, openid: "F855D0937EA8923653A19ECD5497CFA0", openkey: "2A8E06A921A923EC4E2F544DBAE6A0D9"}
     经过urlencode编码后：%7B%22action%22%3A%22openVip%22%2C%22appid%22%3A1109981688%2C%22openid%22%3A%22F855D0937EA8923653A19ECD5497CFA0%22%2C%22openkey%22%3A%222A8E06A921A923EC4E2F544DBAE6A0D9%22%7D*/
    public void buy_vip_test() {
        //param填入的为encode之后的字符串
        string param = req_buy_vip_Input.text;
        SendMessageToHall(" {\"cmd\":\"buy_vip\",\"param\":\"" + param + "\"}");
    }

    //支付请求测试, 支付参数请参考文档 <https://open.qqgame.qq.com/wiki/24/35/46/51/51.html>
    /*例如拼接好的Param参数的JSON如下：{"action":"buy","appid":1109981688,"goodstokenurl":"/v1/r/1109981688/mobile_goods_info?token_id=32E897DBE2D202E3C3B848E1A866A49E18880&transaction_id=32E897DBE2D202E3C3B848E1A866A49E18880&out_trade_no=&new_cpay=1&offer_type=0","openid":"F855D0937EA8923653A19ECD5497CFA0","openkey":"2A8E06A921A923EC4E2F544DBAE6A0D9"}
     经过urlencode编码后：%7B%22action%22%3A%22buy%22%2C%22appid%22%3A1109981688%2C%22goodstokenurl%22%3A%22%2Fv1%2Fr%2F1109981688%2Fmobile_goods_info%3Ftoken_id%3D32E897DBE2D202E3C3B848E1A866A49E18880%26transaction_id%3D32E897DBE2D202E3C3B848E1A866A49E18880%26out_trade_no%3D%26new_cpay%3D1%26offer_type%3D0%22%2C%22openid%22%3A%22F855D0937EA8923653A19ECD5497CFA0%22%2C%22openkey%22%3A%222A8E06A921A923EC4E2F544DBAE6A0D9%22%7D*/
    public void pay_test() {
        //param填入的为encode之后的字符串
        string param = req_pay_Input.text;
        SendMessageToHall("{ \"cmd\":\"pay\", \"param\":\"" + param + "\"}");
    }

    //自定义请求，如：可以请求大厅打开一个web页面：{"cmd":"open_web", "url":"https://qqgame.qq.com"}
    public void custom_msg_test()
    {
        string param = inputReq.text;
        if(param == "")
        {
            param = "{\"cmd\":\"open_web\", \"url\":\"http://www.qq.com\"}";
        }
        SendMessageToHall(param);
    }

    public void start_process()
    {
        string cmdline = "";
        for (int i = 1; i < CommandLineArgs.Length; i++)
        {
            cmdline += CommandLineArgs[i] + " ";
        }

        if (start_path.text != null && start_path.text != "")
        {
            Debug.Log("启动应用：" + start_path.text + " " + cmdline);
            System.Diagnostics.Process.Start(start_path.text, @cmdline);
        }
        else
        {
            string exepath = Environment.CurrentDirectory + "\\QQGameDemo.exe";
            Debug.Log("启动应用：" + exepath + " " + cmdline);
            System.Diagnostics.Process.Start(exepath, @cmdline);
        }
    }

    //控制台显隐
    public void console_window_btn() { 
        console_window.SetActive(!console_window.activeSelf);
    }

    private byte[] getBytes(string message)
    {
        byte[] buffer = Encoding.Default.GetBytes(message);
        return buffer;
    }
}
