using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Windows.Forms;
using System.Xml;
using Fleck;
using Microsoft.VisualBasic.ApplicationServices;
using Newtonsoft.Json;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;


public class WebSocketServer
{
    //用户信息
    public static List<ClassUserInfo> IWebSocketUserinfo = new List<ClassUserInfo>();
    //socket信息
    public static List<IWebSocketConnection> _clients = new List<IWebSocketConnection>();
    //课程信息
    public static List<ClassInfo> _classInfos = new List<ClassInfo>();

    public Fleck.WebSocketServer _server;

    public async void Start(string location)
    {

        var certPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "fullchain.pfx");
        if (!File.Exists(certPath))
        {
            MessageBox.Show("证书文件未找到！");
            return;
        }
        var certificate = new X509Certificate2(certPath, "");


        var _server = new Fleck.WebSocketServer(location)
        {
           
            Certificate = certificate,
            EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls12,
            RestartAfterListenError = true
        };

        _server.Start(async socket =>
        {
            socket.OnOpen = () =>
            {

                try
                {
                    Result r = new Result();
                    ClassUserInfo u = new ClassUserInfo();
                    var query = HttpUtility.ParseQueryString(socket.ConnectionInfo.Path);
                    u.UserName = HttpUtility.UrlDecode(query["UserName"]);
                    u.Class = Convert.ToInt64(query["Class"]);
                    u.Schoolclass = Convert.ToInt32(query["SchoolClass"]);
                    u.UserID = Convert.ToInt64(query["UserID"]);
                    u.UserType = Convert.ToInt32(query["UserType"]);//0学生 1老师  2教室
                    u.GUID = socket.ConnectionInfo.Id;
                    string token = query["Token"];
                    u.Linsocket = socket;
                    if (token != "123456")
                    {
                        r.IsSuccess = false;
                        r.Data = "Faile TokenNo";
                        r.MessageType = 0;
                        socket.Send(JsonConvert.SerializeObject(r));
                        return;
                    }
                    else
                    {
                        IWebSocketUserinfo.Add(u);
                    }
                }

                catch { }
            };

            socket.OnClose = () =>
            {
                try
                {
                    IWebSocketUserinfo.RemoveAll(P => P.GUID == socket.ConnectionInfo.Id);
                    _clients.Remove(socket);
                }
                catch { }
               
            };

            socket.OnMessage =  message =>
            {
                try
                {
                    var user = IWebSocketUserinfo.First(p => p.GUID == socket.ConnectionInfo.Id);
                    OperaterSocketData(message, IWebSocketUserinfo, socket, user);
                }
                catch { 
                
                }
               
            };
        });
    }


    //消息处理
    public async void OperaterSocketData(string message, List<ClassUserInfo> ListUser, IWebSocketConnection socket, ClassUserInfo user)
    {
        try
        {
            ReciveSocketInfo recive = JsonConvert.DeserializeObject<ReciveSocketInfo>(message);
            // 群发
            if (recive.Type == 1)
            {
                SendDataOtherUser(recive, ListUser, user);
            }
            //单发
            if (recive.Type == 0)
            {
                SendDataUserToUser(recive, ListUser, user);
            }
        }
        catch { 
        
        }
    }
    //如果是发单人

    public async void SendDataOtherUser(ReciveSocketInfo recive, List<ClassUserInfo> ListUser, ClassUserInfo user)
    {
        string userIDList = recive.UserIDS;
        if (!string.IsNullOrEmpty(userIDList))
        {
            string[] userids = userIDList.Trim().Split(',');

            foreach (ClassUserInfo c in ListUser)
            {
                foreach (string userID in userids)
                {
                    if (c.UserID == Convert.ToInt64(userID)&&c.UserType == recive.UserType)
                    {
                        c.Linsocket.Send(recive.Data);
                    }
                }
            }
        }
        string rclass = recive.Class;
        if (!string.IsNullOrEmpty(rclass))
        {
            string[] rclasslist = rclass.Trim().Split(',');

            foreach (ClassUserInfo c in ListUser)
            {
                foreach (string r in rclasslist)
                {

                    if (c.Class == Convert.ToInt64(r) && c.UserType == recive.UserType)
                    {
                        c.Linsocket.Send(recive.Data);
                    }
                }
            }
        }

        string rschoolclass = recive.SchoolClass;
        if (!string.IsNullOrEmpty(rschoolclass))
        {
            string[] rschoolclasslist = rschoolclass.Trim().Split(',');

            foreach (ClassUserInfo c in ListUser)
            {
                foreach (string r in rschoolclasslist)
                {

                    if (c.Schoolclass == Convert.ToInt64(r) && c.UserType == recive.UserType)
                    {
                        c.Linsocket.Send(recive.Data);
                    }
                }
            }
        }
    }


    private async void SendDataUserToUser(ReciveSocketInfo recive, List<ClassUserInfo> ListUser, ClassUserInfo user)
    {
        foreach (ClassUserInfo c in ListUser)
        {
            if (c.UserID == recive.UserID && c.UserType == recive.UserType)
            {
                c.Linsocket.Send(recive.Data);
            }
        }
    }



    public void Stop()
    {
        foreach (var client in _clients.ToList())
        {
            client.Close();
        }
        _clients.Clear();
        // Console.WriteLine("WebSocket 服务器已停止");
    }
}
