<?php

namespace Itgalaxy\Elementor\Form\Infusionsoft\Integration\Includes;

class RequestHelper
{
    /**
     * @var array
     */
    private static $authInfo = [];

    /**
     * @return array|mixed
     */
    public static function getAuthInfo()
    {
        if (!empty(self::$authInfo)) {
            return self::$authInfo;
        }

        $settings = \get_option(Bootstrap::OPTIONS_KEY, []);
        $tokenData = \get_option(Bootstrap::TOKEN_KEY, []);

        if (empty($tokenData)) {
            $response = \wp_remote_post(
                'https://api.infusionsoft.com/token',
                [
                    'body' => [
                        'grant_type' => 'authorization_code',
                        'client_id' => $settings['api-key'],
                        'client_secret' => $settings['api-secret'],
                        'redirect_uri' => admin_url()
                            . 'admin.php?page=' . Bootstrap::OPTIONS_KEY,
                        'code' => $settings['code'],
                    ],
                    'headers' => [
                        'Content-Type' => 'application/x-www-form-urlencoded',
                        'Accept-Encoding' => 'gzip',
                    ],
                    'timeout' => 20,
                ]
            );

            if (\is_wp_error($response)) {
                return $response;
            }

            $decodedResponse = json_decode(wp_remote_retrieve_body($response), true);

            if (!empty($decodedResponse) && !isset($decodedResponse['error'])) {
                \update_option(Bootstrap::TOKEN_KEY, $decodedResponse);

                if (isset($decodedResponse['refresh_token'])) {
                    \update_option(Bootstrap::REFRESH_TOKEN_KEY, $decodedResponse['refresh_token']);
                }
            } else {
                Helper::log('error token data', $response);
            }

            return $decodedResponse;
        }

        $response = \wp_remote_post(
            'https://api.infusionsoft.com/token',
            [
                'body' => [
                    'grant_type' => 'refresh_token',
                    'client_id' => $settings['api-key'],
                    'client_secret' => $settings['api-secret'],
                    'refresh_token' => \get_option(Bootstrap::REFRESH_TOKEN_KEY, ''),
                ],
                'headers' => [
                    'Content-Type' => 'application/x-www-form-urlencoded',
                    'Accept-Encoding' => 'gzip',
                    'Authorization' => 'Basic ' . base64_encode($settings['api-key'] . ':' . $settings['api-secret']),
                ],
                'timeout' => 20,
            ]
        );

        if (\is_wp_error($response)) {
            return $response;
        }

        $decodedResponse = json_decode(wp_remote_retrieve_body($response), true);

        if (empty($decodedResponse) || isset($decodedResponse['error'])) {
            Helper::log('error token data', $response);

            return $decodedResponse;
        }

        \update_option(Bootstrap::REFRESH_TOKEN_KEY, $decodedResponse['refresh_token']);

        $tokenData['access_token'] = $decodedResponse['access_token'];

        self::$authInfo = $tokenData;

        return self::$authInfo;
    }

    /**
     * @param array $authInfo
     *
     * @return string[]
     */
    public static function generateHeaders($authInfo)
    {
        return [
            'Authorization' => 'Bearer ' . $authInfo['access_token'],
        ];
    }

    /**
     * @return bool
     */
    public static function checkConnection()
    {
        try {
            if (!function_exists('curl_init')) {
                throw new \Exception('Please install/enable `php-curl` extension for PHP');
            }

            $result = self::getAuthInfo();

            if (\is_wp_error($result)) {
                throw new \Exception($result->get_error_message());
            }

            if (!empty($result['error'])) {
                throw new \Exception($result['error']);
            }
        } catch (\Exception $e) {
            Helper::log('check connection error', $e, 'error');
            self::checkConnectionError($e);

            return false;
        }

        return true;
    }

    /**
     * @param \Exception $e
     * @param bool       $cleanSettings
     *
     * @return false
     */
    public static function checkConnectionError($e, $cleanSettings = true)
    {
        if (!$cleanSettings) {
            return false;
        }

        $settings = get_option(Bootstrap::OPTIONS_KEY, []);

        // Clean failed information
        \update_option(
            Bootstrap::OPTIONS_KEY,
            [
                'enabled_logging' => isset($settings['enabled_logging']) ? $settings['enabled_logging'] : '',
                'send_type' => isset($settings['send_type']) ? $settings['send_type'] : '',
            ]
        );

        echo sprintf(
            '<div class="error notice notice-error"><p><strong>%1$s</strong></p></div>',
            sprintf(
                esc_html__(
                    'Check connection error code (%d): %s. Check the settings.',
                    'el-pro-form-infusionsoft-integration'
                ),
                (int) $e->getCode(),
                esc_html($e->getMessage())
            )
        );

        return false;
    }
}
