Refactor and optimize this C# code:
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;
                }

            }
        }