<?php

namespace Formatrica\Submission\Integrations;

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

use Formatrica\Submission\Security\Endpoint_Validator;

/**
 * HTTP client for integration requests
 */
final class Http_Client
{
    private Endpoint_Validator $endpoint_validator;

    public function __construct(?Endpoint_Validator $endpoint_validator = null)
    {
        $this->endpoint_validator = $endpoint_validator ?? new Endpoint_Validator();
    }

    /**
     * Send JSON payload to an endpoint
     *
     * @param string $endpoint
     * @param array<string, mixed> $body
     * @param string $integration
     * @param array<string, mixed> $form
     * @param array<string, mixed> $payload
     * @param array<string, mixed> $context
     * @param string $method
     * @param array<string, string> $extra_headers
     */
    public function send_json(
        string $endpoint,
        array $body,
        string $integration,
        array $form,
        array $payload,
        array $context,
        string $method = 'POST',
        array $extra_headers = []
    ): void {
        $target = $this->endpoint_validator->validate($endpoint);
        if ($target === null) {
            return;
        }

        $json = wp_json_encode($body);
        if ($json === false) {
            return;
        }

        $headers = array_merge([
            'Content-Type' => 'application/json',
        ], $extra_headers);

        $args = [
            'method' => strtoupper($method),
            'body' => $json,
            'headers' => $headers,
            'timeout' => 10,
            'redirection' => 0, // no redirects: target is SSRF-validated pre-flight (avoid TOCTOU)
            'reject_unsafe_urls' => true,
            'blocking' => true,
            'limit_response_size' => 512 * 1024,
        ];

        $response = wp_remote_request($target, $args);

        if (is_wp_error($response)) {
            $this->log_error($integration, $target, $response->get_error_message(), $form, $payload, $context);
            return;
        }

        $code = (int) wp_remote_retrieve_response_code($response);
        if ($code < 200 || $code >= 300) {
            $response_body = wp_remote_retrieve_body($response);
            $extra = ['status' => $code];

            // Include response body for debugging (truncate if too long)
            if ($response_body) {
                $extra['response'] = strlen($response_body) > 500
                    ? substr($response_body, 0, 500) . '...[truncated]'
                    : $response_body;
            }

            $this->log_error(
                $integration,
                $target,
                sprintf('HTTP %d', $code),
                $form,
                $payload,
                $context,
                $extra
            );
        }
    }

    /**
     * Send form-encoded payload to an endpoint
     *
     * @param string $endpoint
     * @param array<string, mixed> $body
     * @param string $integration
     * @param array<string, mixed> $form
     * @param array<string, mixed> $payload
     * @param array<string, mixed> $context
     */
    public function send_form(
        string $endpoint,
        array $body,
        string $integration,
        array $form,
        array $payload,
        array $context
    ): void {
        $target = $this->endpoint_validator->validate($endpoint);
        if ($target === null) {
            return;
        }

        $args = [
            'body' => $body,
            'timeout' => 10,
            'redirection' => 0, // no redirects: target is SSRF-validated pre-flight (avoid TOCTOU)
            'reject_unsafe_urls' => true,
            'blocking' => true,
            'limit_response_size' => 512 * 1024,
        ];

        $response = wp_remote_post($target, $args);

        if (is_wp_error($response)) {
            $this->log_error($integration, $target, $response->get_error_message(), $form, $payload, $context);
            return;
        }

        $code = (int) wp_remote_retrieve_response_code($response);
        if ($code < 200 || $code >= 400) {
            $this->log_error(
                $integration,
                $target,
                sprintf('HTTP %d', $code),
                $form,
                $payload,
                $context,
                ['status' => $code]
            );
        }
    }

    /**
     * Log integration error
     *
     * @param string $integration
     * @param string $endpoint
     * @param string $message
     * @param array<string, mixed> $form
     * @param array<string, mixed> $payload
     * @param array<string, mixed> $context
     * @param array<string, mixed> $extra
     */
    private function log_error(
        string $integration,
        string $endpoint,
        string $message,
        array $form,
        array $payload,
        array $context = [],
        array $extra = []
    ): void {
        $error_payload = array_merge([
            'endpoint' => $endpoint,
            'integration' => $integration,
            'context' => $context,
        ], $extra);

        if (!isset($error_payload['error'])) {
            $error_payload['error'] = $message;
        }

        do_action('formatrica_webhook_failed', $error_payload, $form, $payload);

        // Enhanced logging with response body for debugging
        $log_message = sprintf('[Formatrica] Integration (%s) request failed for %s - %s', $integration, $endpoint, $message);
        if (!empty($extra['response'])) {
            $log_message .= sprintf(' | Response: %s', $extra['response']);
        }
        do_action('formatrica_debug_log', $log_message);
    }
}
