<?php
/**
 * Dolibarr HTTP client for Doli Training Management.
 *
 * @package DoliTrainingManagement
 */

if (!defined('ABSPATH')) {
    exit;
}

/**
 * Centralized outbound requests to Dolibarr API.
 */
class Doli_Training_Management_Dolibarr_Client {

    /**
     * Request timeout in seconds.
     *
     * @var int
     */
    private $timeout = 20;

    /**
     * Get decoded JSON response from Dolibarr.
     *
     * @param string $method HTTP method.
     * @param string $path API path after /api/index.php.
     * @param array  $query Query args.
     * @param array  $body Body payload for POST.
     * @return mixed|\WP_Error
     */
    public function request_json($method, $path, $query = array(), $body = array()) {
        $response = $this->request($method, $path, $query, $body);
        if (is_wp_error($response)) {
            return $response;
        }

        $status_code = (int) wp_remote_retrieve_response_code($response);
        $raw_body    = wp_remote_retrieve_body($response);
        $decoded     = json_decode($raw_body, true);

        if ($status_code < 200 || $status_code >= 300) {
            return new WP_Error(
                'dolibarr_http_error',
                __('Dolibarr request failed.', 'doli-training-management'),
                array(
                    'status'  => $status_code,
                    'body'    => is_array($decoded) ? $decoded : array('message' => $raw_body),
                    'rawBody' => $raw_body,
                )
            );
        }

        return $decoded;
    }

    /**
     * Get raw response (used for binary/image streams).
     *
     * @param string $method HTTP method.
     * @param string $path API path after /api/index.php.
     * @param array  $query Query args.
     * @param array  $body Body payload.
     * @return array|\WP_Error
     */
    public function request_raw($method, $path, $query = array(), $body = array()) {
        $response = $this->request($method, $path, $query, $body);
        if (is_wp_error($response)) {
            return $response;
        }

        $status_code = (int) wp_remote_retrieve_response_code($response);
        $raw_body    = wp_remote_retrieve_body($response);
        $headers     = wp_remote_retrieve_headers($response);

        if ($status_code < 200 || $status_code >= 300) {
            return new WP_Error(
                'dolibarr_http_error',
                __('Dolibarr request failed.', 'doli-training-management'),
                array(
                    'status' => $status_code,
                    'body'   => $raw_body,
                )
            );
        }

        return array(
            'status'  => $status_code,
            'headers' => $headers,
            'body'    => $raw_body,
        );
    }

    /**
     * Build and execute HTTP request.
     *
     * @param string $method HTTP method.
     * @param string $path API path after /api/index.php.
     * @param array  $query Query args.
     * @param array  $body Body payload.
     * @return array|\WP_Error
     */
    private function request($method, $path, $query = array(), $body = array()) {
        $base_url = $this->get_dolibarr_base_url();
        $api_key  = $this->get_dolibarr_api_key();

        if (empty($base_url) || empty($api_key)) {
            return new WP_Error(
                'dolibarr_missing_config',
                __('Dolibarr URL or API key is missing.', 'doli-training-management'),
                array('status' => 500)
            );
        }

        $api_url = trailingslashit($base_url) . 'api/index.php/' . ltrim($path, '/');
        if (!empty($query)) {
            $api_url = add_query_arg($query, $api_url);
        }

        // Dolibarr reads $_SERVER['HTTP_DOLAPIKEY'] from the DOLAPIKEY header.
        $args = array(
            'method'  => strtoupper($method),
            'timeout' => $this->timeout,
            'headers' => array(
                'DOLAPIKEY'    => $api_key,
                'Content-Type' => 'application/json',
            ),
        );

        if ('POST' === strtoupper($method)) {
            $args['body'] = wp_json_encode($body);
        }

        return wp_remote_request($api_url, $args);
    }

    /**
     * Read and normalize Dolibarr base URL from options.
     *
     * @return string
     */
    private function get_dolibarr_base_url() {
        return untrailingslashit((string) get_option('doli_training_management_dolibarr_url', ''));
    }

    /**
     * Read Dolibarr API key from options.
     *
     * @return string
     */
    private function get_dolibarr_api_key() {
        return trim((string) get_option('doli_training_management_dolibarr_api_key', ''));
    }
}
