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