using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using PSO2SERVER.Database;
using PSO2SERVER.Models;
using PSO2SERVER.Protocol.Packets;

namespace PSO2SERVER.Protocol.Handlers
{
    [PacketHandlerAttr(0x11, 0x2D)]
    public class SystemInformation : PacketHandler
    {
        public struct SystemInformationPacket
        {
            public string CpuInfo { get; set; }
            public string VideoInfo { get; set; }
            public ulong Vram { get; set; }
            public ulong TotalRam { get; set; }
            public uint Unk1 { get; set; }
            public uint Unk2 { get; set; }
            public string WindowsVersion { get; set; }
            public string WindowSize { get; set; }
            public string AudioDevices { get; set; }
            public string Unk4 { get; set; }
            public string VideoDriver { get; set; }
            public ulong TotalDiskSpace { get; set; }
            public ulong FreeDiskSpace { get; set; }
        }

        SystemInformationPacket pkt = new SystemInformationPacket();

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

            pkt.CpuInfo = reader.ReadAscii(0x883D, 0x9F);
            pkt.VideoInfo = reader.ReadAscii(0x883D, 0x9F);
            pkt.Vram = reader.ReadUInt64();
            pkt.TotalRam = reader.ReadUInt64();
            pkt.Unk1 = reader.ReadUInt32();
            pkt.Unk2 = reader.ReadUInt32();
            pkt.WindowsVersion = reader.ReadUtf16(0x883D, 0x9F);
            pkt.WindowSize = reader.ReadAscii(0x883D, 0x9F);
            pkt.AudioDevices = reader.ReadUtf16(0x883D, 0x9F);
            pkt.Unk4 = reader.ReadUtf16(0x883D, 0x9F);
            pkt.VideoDriver = reader.ReadUtf16(0x883D, 0x9F);
            pkt.TotalDiskSpace = reader.ReadUInt64();
            pkt.FreeDiskSpace = reader.ReadUInt64();

            // 打印日志
            //Logger.Write(
            //    "System Info: Vram={0}GB, TotalRam={1}GB, WindowsVersion={2}, CpuInfo={3}, VideoInfo={4}, AudioDevices={5}, WindowSize={6}, VideoDriver={7}, Unk1={8}, Unk2={9}, Unk4={10}, TotalDiskSpace={11}GB, FreeDiskSpace={12}GB",
            //    (pkt.Vram / (1024 * 1024 * 1024)),
            //    (pkt.TotalRam / (1024 * 1024 * 1024)),
            //    pkt.WindowsVersion,
            //    pkt.CpuInfo,
            //    pkt.VideoInfo,
            //    pkt.AudioDevices,
            //    pkt.WindowSize,
            //    pkt.VideoDriver,
            //    pkt.Unk1,
            //    pkt.Unk2,
            //    pkt.Unk4,
            //    (pkt.TotalDiskSpace / (1024 * 1024 * 1024)),
            //    (pkt.FreeDiskSpace / (1024 * 1024 * 1024))
            //);

            // 尝试将数据保存到数据库
            SaveSystemInfoToDatabase(context);
        }

        private void SaveSystemInfoToDatabase(Client context)
        {
            try
            {
                using (var db = new ServerEf())
                {
                    // 创建新的 AccountSystemInfo 对象
                    var acsinfo = new AccountSystemInfo
                    {
                        AccountId = context._account.AccountId,
                        Username = context._account.Username,
                        CpuInfo = pkt.CpuInfo,
                        VideoInfo = pkt.VideoInfo,
                        Vram = (long)pkt.Vram,
                        TotalRam = (long)pkt.TotalRam,
                        Unk1 = (int)pkt.Unk1,
                        Unk2 = (int)pkt.Unk2,
                        WindowsVersion = pkt.WindowsVersion,
                        WindowSize = pkt.WindowSize,
                        AudioDevices = pkt.AudioDevices,
                        Unk4 = pkt.Unk4,
                        VideoDriver = pkt.VideoDriver,
                        TotalDiskSpace = (long)pkt.TotalDiskSpace,
                        FreeDiskSpace = (long)pkt.FreeDiskSpace
                    };

                    // 使用事务来确保原子性
                    using (var dbContextTransaction = db.Database.BeginTransaction())
                    {
                        try
                        {
                            // 将记录保存到数据库
                            db.AccountsSystemInfoes.Add(acsinfo);
                            db.SaveChanges();
                            dbContextTransaction.Commit();  // 提交事务
                            //Logger.Write("系统信息已成功保存到数据库: AccountId={0}, Username={1}", context._account.AccountId, context._account.Username);
                        }
                        catch (DbUpdateException dbEx)
                        {
                            dbContextTransaction.Rollback();  // 回滚事务
                            Logger.WriteError("数据库更新时发生异常: {0}", dbEx.Message);
                            Logger.WriteError("详细信息: {0}", dbEx.InnerException?.Message);
                        }
                        catch (Exception ex)
                        {
                            dbContextTransaction.Rollback();  // 回滚事务
                            Logger.WriteError("系统信息保存时发生异常: {0}", ex.Message);
                            Logger.WriteError("详细信息: {0}", ex.InnerException?.Message);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.WriteError("保存系统信息到数据库时发生未知错误: {0}", ex.Message);
                Logger.WriteError("详细信息: {0}", ex.InnerException?.Message);
            }
        }
    }
}
