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();
                        }
                    }