Refactor and optimize this C# code:

using MimeKit;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;

using EmailSoftWare.Models.ProxyClients;
using EmailSoftWare.Models.Connections;
using EmailSoftWare.Models.UserData;
using static EmailSoftWare.Models.Connections.ServerResponseParser;
using EmailSoftWare.Models.Extensions.Enums;
using EmailSoftWare.Models.Extensions.Enums;
using EmailSoftWare.Models.EmailClients;

namespace EmailSoftWare.Models.EmailClients
{

    public class ImapClient
    {
        private TcpClient _client;
        private StreamReader _reader;
        private StreamWriter _writer;
        private SslStream _sslStream;
        private Account _account;
        private ProxyType _proxyType;
        private string _response = "";
        IPAddress ipAddress;
        private int _currentTagNumber = 0;
        private string _currentRequest = "";

        public ImapClient(Account account, ProxyType proxyType)
        {
            _account = account;
            _proxyType = proxyType;
        }

        private string GenerateTag()
        {
            _currentTagNumber++;
            return $"A{_currentTagNumber:000}";
        }

        public void Connect()
        {
            while (true)
            {
                try
                {
                    byte[] buffer;
                    ipAddress = IPAddress.Parse(GetIpAddress(_account.Server));
                    _currentTagNumber = 0;

                    switch (_proxyType)
                    {
                        case ProxyType.Socks4:
                            _client = new Socks4Client().GetClient();
                            _client.ReceiveTimeout = Connections.ViewManager.TimeOut;
                            _client.SendTimeout = Connections.ViewManager.TimeOut;
                            _reader = new StreamReader(_client.GetStream(), Encoding.ASCII);
                            _writer = new StreamWriter(_client.GetStream(), Encoding.ASCII);
                            buffer = new byte[4096];
                            buffer[0] = 4;
                            buffer[1] = 1;
                            buffer[2] = (byte)(_account.Port >> 8);
                            buffer[3] = (byte)(_account.Port & 0xFF);
                            Array.Copy(ipAddress.GetAddressBytes(), 0, buffer, 4, 4);
                            _writer.BaseStream.Write(buffer, 0, 8 + 4);
                            _reader.BaseStream.Read(buffer, 0, 8);
                            if (buffer[1] != 90)
                            {
                                _client?.Dispose();
                                continue;
                            }

                            break;
                        case ProxyType.Socks5:
                            _client = new Socks5Client().GetClient();
                            NetworkStream stream = _client.GetStream();
                            buffer = new byte[4096];
                            buffer[0] = 5;
                            buffer[1] = 1;
                            buffer[2] = 0;
                            buffer[3] = 1;
                            Array.Copy(ipAddress.GetAddressBytes(), 0, buffer, 4, 4);
                            buffer[8] = (byte)(_account.Port / 256);
                            buffer[9] = (byte)(_account.Port % 256);
                            stream.Write(buffer, 0, 10);
                            stream.Read(buffer, 0, 10);
                            if (buffer[1] != 0)
                            {
                                _client?.Dispose();
                                continue;
                            }

                            break;
                        case ProxyType.Https:
                            _client = new HTTPsClient().GetClient();
                            _client.ReceiveTimeout = Connections.ViewManager.TimeOut;
                            _client.SendTimeout = Connections.ViewManager.TimeOut;
                            _reader = new StreamReader(_client.GetStream(), Encoding.ASCII);
                            _writer = new StreamWriter(_client.GetStream(), Encoding.ASCII);

                            SendCommand($"CONNECT {ipAddress}:{_account.Port} HTTP/1.1\r\nHost: {ipAddress}:{_account.Port}\r\n\r\n");
                            string connectResponse = ReadResponse();
                            if (!connectResponse.Contains("200"))
                            {
                                _client?.Dispose();
                                continue;
                            }

                            break;
                        case ProxyType.None:
                            _client = new TcpClient();
                            _client.ReceiveTimeout = Connections.ViewManager.TimeOut;
                            _client.SendTimeout = Connections.ViewManager.TimeOut;
                            _client.Connect(ipAddress, _account.Port);
                            _reader = new StreamReader(_client.GetStream(), Encoding.ASCII);
                            _writer = new StreamWriter(_client.GetStream(), Encoding.ASCII);
                            break;
                    }

                    if (_account.Port == 993)
                    {
                        _sslStream = new SslStream(_client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
                        _sslStream.AuthenticateAsClient(ipAddress.ToString());
                        _reader = new StreamReader(_sslStream, Encoding.ASCII);
                        _writer = new StreamWriter(_sslStream, Encoding.ASCII);
                    }

                    if (_account.Port != 143 && _proxyType != ProxyType.Https)
                    {
                        _response = ReadResponse();

                        if (_response == null || !_response.Contains("OK", StringComparison.OrdinalIgnoreCase))
                        {
                            throw new Exception();
                        }
                    }

                    SendCommand($"{GenerateTag()} LOGIN \"{_account.Email}\" \"{_account.Password}\"\r\n");
                    _response = ReadResponse();
                    _account.Result = ServerResponseParser.AnswerHandler(_response.ToLower());
                    if (_account.Result == Result.ToCheck)
                    {
                        _account.Result = Result.Bad;
                        //File.WriteAllText("ResponseCheck\\" + _account.Email + ".txt", _response.ToLower());
                        _client?.Dispose();
                        return;
                    }
                    else if (_account.Result == Result.Error)
                    {
                        _client?.Dispose();
                        throw new Exception();
                    }

                    if (_account.Result == Result.Good)
                    {
                        if (Connections.ViewManager.SearchForEmails == true)
                        {
                            foreach (var request in Connections.ViewManager.ReqList)
                            {
                                var emails = SearchEmailsBySenderInAllMailboxes(request);
                                if (emails.Any(x => x.From.Contains(request, StringComparison.OrdinalIgnoreCase)))
                                {
                                    lock (Connections.ViewManager.LockerWriteLetters)
                                    {
                                        File.AppendAllText(Connections.ViewManager.MainWindow.PathToSaveResults + "\\" + request + ".txt", $"{_account.FullData}\n");
                                    }
                                }

                                if (Connections.ViewManager.DownloadLetters == true)
                                {
                                    foreach (var item in emails)
                                    {
                                        if (item.From.Contains(request, StringComparison.OrdinalIgnoreCase))
                                        {
                                            if (!Directory.Exists(Connections.ViewManager.MainWindow.PathToSaveResults + "\\" + request))
                                            {
                                                Directory.CreateDirectory(Connections.ViewManager.MainWindow.PathToSaveResults + "\\" + request);
                                            }
                                            File.AppendAllText(Connections.ViewManager.MainWindow.PathToSaveResults + "\\" + request + "\\" + _account.Email + ".html", $"<center>===================================================<br>\r\nAccount: {_account.FullData}<br>\r\nSubject: {item.Subject}<br>\r\nFrom: {item.From.Replace("<", "").Replace(">", "")}<br>\r\nDate: {item.Date}<br><br>\r\n\r\n</center>{item.Body}<center><br>\r\n===================================================<br>\r\n</center>");
                                        }
                                    }
                                }
                            }
                        }
                        _client?.Dispose();
                        return;
                    }

                    _client?.Dispose();
                    return;
                }
                catch (Exception e)
                {
                    _client?.Dispose();

                    if (e is SocketException)
                    {
                        _account.Result = Result.WrongServer;
                        return;
                    }

                    if (_account.Errors > 30)
                    {
                        //File.WriteAllText("ErrorCheck\\" + _account.Email + ".txt", _response.ToLower() + Environment.NewLine + e.Message);
                        _account.Result = Result.Error;
                        return;
                    }

                    _account.Errors++;
                    continue;
                }

            }
        }

        public List<string> GetAllMailboxes()
        {
            List<string> mailboxes = new List<string>();

            // Получение списка всех почтовых ящиков
            SendCommand($"{GenerateTag()} LIST \"\" \"*\"\r\n");
            _response = ReadResponse();
            _response = _response.Remove(_response.LastIndexOf($"A{_currentTagNumber:000}"));

            // Разбор ответа и извлечение имен почтовых ящиков
            var matches = Regex.Matches(_response, @"(?<=\s""|\s)\w*(?:[\.\s/\-\*\&+'$\\#,]\w*)*(?=""\r|\r)", RegexOptions.Multiline);
            foreach (Match match in matches)
            {
                string mailbox = match.Value;
                mailboxes.Add(mailbox);
            }

            return mailboxes;
        }

        public List<EmailDetails> SearchEmailsBySenderInAllMailboxes(string sender)
        {
            List<EmailDetails> emails = new List<EmailDetails>();

            // Получение списка всех почтовых ящиков
            var mailboxes = GetAllMailboxes();

            // Поиск писем от отправителя в каждом почтовом ящике
            foreach (var mailbox in mailboxes)
            {
                var mailboxEmails = SearchEmailsBySenderInMailbox(sender, mailbox);
                emails.AddRange(mailboxEmails);
            }

            return emails;
        }

        public List<EmailDetails> SearchEmailsBySenderInMailbox(string sender, string mailbox)
        {
            List<EmailDetails> emails = new List<EmailDetails>();

            // Выбор почтового ящика
            SendCommand($"{GenerateTag()} SELECT \"{mailbox}\"\r\n");
            _response = ReadResponse();

            // Поиск писем от отправителя
            SendCommand($"{GenerateTag()} SEARCH HEADER \"FROM\" \"{sender}\"\r\n");
            _response = ReadResponse();

            // Получение списка идентификаторов писем
            List<int> emailIds = ParseEmailIds(_response);

            // Получение информации о письмах
            foreach (int emailId in emailIds)
            {
                EmailDetails email = FetchEmail(emailId);
                if (email != null)
                {
                    emails.Add(email);
                }
            }

            return emails;
        }

        private List<int> ParseEmailIds(string response)
        {
            List<int> emailIds = new List<int>();

            string idsLine = Regex.Match(response, "\\* SEARCH (.+)$", RegexOptions.Multiline).Groups[1].Value;
            string[] ids = idsLine.Split(' ');

            foreach (var id in ids)
            {
                if (int.TryParse(id, out int emailId))
                {
                    emailIds.Add(emailId);
                }
            }

            return emailIds;
        }

        public EmailDetails FetchEmail(int emailId)
        {
            try
            {
                SendCommand($"{GenerateTag()} FETCH {emailId} BODY[]\r\n");
                _response = ReadResponse();

                string bodyPattern = $"BODY\\[\\] \\{{.*?\\}}.(.*)\\).*A{_currentTagNumber:000}";
                Match bodyMatch = Regex.Match(_response, bodyPattern, RegexOptions.Singleline);
                if (!bodyMatch.Success)
                {
                    return null;
                }

                string body = bodyMatch.Groups[1].Value;
                body = body.Substring(1, body.Length - 2);
                string from = Regex.Match(body, @"^From:(?:\s|)(.*?)$", RegexOptions.Multiline | RegexOptions.IgnoreCase).Groups[1].Value;

                byte[] responseBytes = Encoding.ASCII.GetBytes(body);
                using MemoryStream responseStream = new MemoryStream(responseBytes);

                var parser = new MimeParser(responseStream);
                var message = parser.ParseMessage();

                EmailDetails email = new EmailDetails
                {
                    From = from,
                    Date = message.Date.LocalDateTime,
                    Body = message.HtmlBody,
                    Subject = message.Subject
                };

                return email;

            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public void SendCommand(string command)
        {
            _writer.AutoFlush = true;
            _writer.Write(command);
        }

        public string ReadResponse()
        {
            StringBuilder responseBuilder = new StringBuilder();

            Thread.Sleep(150);

            string line = _reader.ReadLine();
            responseBuilder.AppendLine(line);
            if (_currentTagNumber > 0)
            {
                while (!Regex.Match(line, $@"^A{_currentTagNumber:000}", RegexOptions.Multiline | RegexOptions.IgnoreCase).Success)
                {
                    try
                    {
                        line = _reader.ReadLine();
                        if (line != null)
                        {
                            responseBuilder.AppendLine(line);
                        }
                    }
                    catch (IOException)
                    {
                        break;
                    }
                }
            }

            return responseBuilder.ToString();
        }

        private static string GetIpAddress(string domainName)
        {
            lock (Connections.ViewManager.DnsLock)
            {
                Connections.ViewManager.DnsList.TryGetValue(domainName, out string ip);
                if (ip == null)
                {
                    ip = Dns.GetHostEntry(domainName).AddressList[0].ToString();
                    Connections.ViewManager.DnsList.Add(domainName, ip);
                }

                return ip;
            }
        }

        private static bool ValidateServerCertificate(object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslpolicyerrors)
        {
            return true;
        }
    }
}