using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using PSO2SERVER.Database;
using PSO2SERVER.Protocol.Packets;
using PSO2SERVER.Models;
using System.Text;
using System.Collections.Generic;
using System;

namespace PSO2SERVER.Protocol.Handlers
{
    [PacketHandlerAttr(0x11, 0x00)]
    public class SegaIDLogin : PacketHandler
    {
        public uint Unk1 { get; set; }
        public uint Unk2 { get; set; }
        public uint Unk3 { get; set; }
        public byte[] VerId { get; set; } = new byte[0x20];
        public List<NetInterface> Interfaces { get; set; } = new List<NetInterface>();
        public byte[] Unk4 { get; set; } = new byte[0x90];
        public byte[] Unk5 { get; set; } = new byte[0x10];
        public Language TextLang { get; set; }
        public Language VoiceLang { get; set; }
        public Language TextLang2 { get; set; }
        public Language LangLang { get; set; }
        public string LanguageCode { get; set; } = new string('\0', 0x10);
        public uint Unk6 { get; set; }
        public uint Unk7 { get; set; }
        public uint Magic1 { get; set; }
        public byte[] Unk8 { get; set; } = new byte[0x20];
        public byte[] Unk9 { get; set; } = new byte[0x44];
        public string Username { get; set; } = new string('\0', 0x40);
        public string Password { get; set; } = new string('\0', 0x40);
        public uint Unk10 { get; set; }
        public string Unk11 { get; set; } = string.Empty;

        public List<NetInterface> ReadNetInterfaces(PacketReader reader, uint count)
        {
            var interfaces = new List<NetInterface>();
            for (uint i = 0; i < count; i++)
            {
                var netInterface = new NetInterface();
                netInterface.ReadFromStream(reader);
                interfaces.Add(netInterface);
            }
            return interfaces;
        }

        public void SaveNetInterfacesToDatabase(int AccountId, string Username, List<NetInterface> interfaces)
        {
            using (var db = new ServerEf())
            {
                // 使用 AddRange 来批量插入数据
                var newInterfaces = interfaces.Select(netInterface => new AccountNetInterFace
                {
                    AccountId = AccountId,
                    Username = Username,
                    State = (int)netInterface.State,  // 确保转换类型正确
                    Mac = netInterface.Mac
                }).ToList();

                db.AccountsNetInterFaces.AddRange(newInterfaces);
                db.SaveChanges();  // 批量保存更改
            }
        }

        // 假设你有一个读取到的实例
        public void PrintInterfaces(List<NetInterface> interfaces)
        {
            foreach (var netInterface in interfaces)
            {
                Logger.Write(netInterface.ToString());
            }
        }

        public void ReadFromStream(PacketReader reader)
        {
            Unk1 = reader.ReadUInt32();
            Unk2 = reader.ReadUInt32();
            Unk3 = reader.ReadUInt32();
            VerId = reader.ReadBytes(0x20);

            var macCount = reader.ReadMagic(0x5E6, 107);
            // Assuming Interfaces is populated somehow
            // e.g. Interfaces = ReadNetInterfaces(reader);
            Interfaces = ReadNetInterfaces(reader, macCount);
            // Read the fixed length fields
            reader.BaseStream.Seek(0x14, SeekOrigin.Current);
            Unk4 = reader.ReadBytes(0x90);
            reader.BaseStream.Seek(0x10, SeekOrigin.Current);
            Unk5 = reader.ReadBytes(0x10);
            reader.BaseStream.Seek(0x10, SeekOrigin.Current);
            TextLang = (Language)reader.ReadUInt32(); // Adjust based on actual type
            VoiceLang = (Language)reader.ReadUInt32(); // Adjust based on actual type
            TextLang2 = (Language)reader.ReadUInt32(); // Adjust based on actual type
            LangLang = (Language)reader.ReadUInt32(); // Adjust based on actual type
            reader.BaseStream.Seek(0x8, SeekOrigin.Current);
            LanguageCode = reader.ReadFixedLengthUtf16(0x10);
            Unk6 = reader.ReadUInt32();
            Unk7 = reader.ReadUInt32();
            Magic1 = reader.ReadUInt32();
            Unk8 = reader.ReadBytes(0x20);
            Unk9 = reader.ReadBytes(0x44);

            // Read Username and Password
            reader.BaseStream.Seek(0x104, SeekOrigin.Current);
            Username = reader.ReadFixedLengthAscii(0x40);
            reader.BaseStream.Seek(0x20, SeekOrigin.Current);
            Password = reader.ReadFixedLengthAscii(0x40);
            reader.BaseStream.Seek(0x04, SeekOrigin.Current);
            Unk10 = reader.ReadUInt32();
            Unk11 = reader.ReadFixedLengthAscii(0x08);
        }

        #region implemented abstract members of PacketHandler

        public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size)
        {
            var reader = new PacketReader(data, position, size);

            ReadFromStream(reader);

            //var info = string.Format("[<--] 接收到的数据 (hex): {0}字节", data.Length);
            //Logger.WriteHex(info, data);

            //Logger.Write("用户名 {0} 密码 {1} - {2}", Username, Password, BCrypt.Net.BCrypt.HashPassword(Password));

            // What am I doing here even
            using (var db = new ServerEf())
            {
                var users = from u in db.Accounts
                            where u.Username.ToLower().Equals(Username.ToLower())
                            select u;


                var error = "";
                Account user;

                if (!users.Any())
                {
                    // Check if there is an empty field
                    if (string.IsNullOrWhiteSpace(Username))
                    {
                        error = "賬戶名為空.";
                        user = null;
                    }

                    if (string.IsNullOrWhiteSpace(Password))
                    {
                        error = "密碼為空 #1.";
                        user = null;
                    }

                    // Check for special characters
                    else if (!Regex.IsMatch(Username, "^[a-zA-Z0-9 ]*$", RegexOptions.IgnoreCase))
                    {
                        error = "用戶名不能包含特殊字符\n請只使用字母和數字.";
                        user = null;
                    }
                    else // We're all good!
                    {
                        // 直接插入新账户至数据库
                        user = new Account
                        {
                            Username = Username.ToLower(),
                            Password = BCrypt.Net.BCrypt.HashPassword(Password),
                            Nickname = Username.ToLower(),
                            // Since we can't display the Nickname prompt yet, just default it to the username
                            SettingsIni = File.ReadAllText(ServerApp.ServerSettingsKey),
                            TextLang = (int)TextLang,
                            VoiceLang = (int)VoiceLang,
                            TextLang2 = (int)TextLang2,
                            LangLang = (int)LangLang,
                            LanguageCode = LanguageCode,

                        };

                        db.Accounts.Add(user);
                        db.SaveChanges();

                        context.SendPacket(new NicknameRequestPacket()); // Request Nickname
                    }
                }
                else
                {
                    user = users.First();

                    var existingUser = db.Accounts.FirstOrDefault(u => u.AccountId == user.AccountId);

                    if (existingUser != null)
                    {
                        // 更新值
                        existingUser.TextLang = (int)TextLang;
                        existingUser.VoiceLang = (int)VoiceLang;
                        existingUser.TextLang2 = (int)TextLang2;
                        existingUser.LangLang = (int)LangLang;
                        existingUser.LanguageCode = LanguageCode;

                        // 提交更改到数据库
                        db.SaveChanges();

                        SaveNetInterfacesToDatabase(user.AccountId, Username, Interfaces);
                    }

                    //TODO 方便GM测试
                    //if (Password != user.Password)
                    //{
                    //    if (Password == "")
                    //    {
                    //        error = "密碼為空 #2.";
                    //        user = null;
                    //    }
                    //    else
                    //    if (!BCrypt.Net.BCrypt.Verify(Password, user.Password))
                    //    {
                    //        error = "密碼錯誤.";
                    //        user = null;
                    //    }
                    //}
                }

                context.SendPacket(new LoginDataPacket("夢幻之星2", error, (user == null) ? (uint)0 : (uint)user.AccountId));

                //Mystery packet
                //var mystery = new PacketWriter();
                //mystery.Write((uint)100);
                //context.SendPacket(0x11, 0x49, 0, mystery.ToArray());

                // SegaIDLogin response packet

                if (user == null)
                {
                    return;
                }

                context._account = user;

            }

            if (ServerApp.Config.motd != "")
            {
                context.SendPacket(new SystemMessagePacket(ServerApp.Config.motd, SystemMessagePacket.MessageType.AdminMessageInstant));
            }

        }

        #endregion
    }
}