protected function getCurlOptions(): array
    {
        $options = [];

        $options[CURLOPT_RETURNTRANSFER] = true;
        $options[CURLOPT_HEADER] = true;

        foreach ($this->getOptions() as $option => $value) {
            $options[$option] = $value;
        }

        switch ($this->getMethod()) {
            case self::POST:
                if (!$this->hasOption(CURLOPT_CUSTOMREQUEST)) {
                    $options[CURLOPT_CUSTOMREQUEST] = $this->getMethod();
                }

                if (!$this->hasOption(CURLOPT_POSTFIELDS)) {
                    $options[CURLOPT_POSTFIELDS] = count($this->getParams()) > 0 ? http_build_query($this->getParams()) : '';
                }

                if ($this->hasHeader('Content-Type') && $this->getHeader('Content-Type') == 'application/json') {
                    $options[CURLOPT_POSTFIELDS] = Json::encode($this->getParams());
                }
                break;

            case self::PUT:
            case self::DELETE:
                if (!$this->hasOption(CURLOPT_CUSTOMREQUEST)) {
                    $options[CURLOPT_CUSTOMREQUEST] = $this->getMethod();
                }

                if (!$this->hasOption(CURLOPT_POSTFIELDS)) {
                    $options[CURLOPT_POSTFIELDS] = count($this->params) > 0 ? http_build_query($this->params) : '';
                }
                break;
        }

        if (count($this->headers) > 0) {
            $options[CURLOPT_HTTPHEADER] = $this->getPreparedHeaders();
        }

        return $options;
    }