<?php

declare(strict_types=1);

/**
 * Examples for cURL OOP API usage
 *
 * Based on PHP RFC: Object-oriented curl API v2
 * @link https://wiki.php.net/rfc/curl_oop_v2
 */

require_once __DIR__ . '/../vendor/autoload.php';

use App\Framework\HttpClient\Curl\Handle;
use App\Framework\HttpClient\Curl\HandleOption;
use App\Framework\HttpClient\Curl\Info;
use App\Framework\HttpClient\Curl\MultiHandle;
use App\Framework\HttpClient\Curl\Exception\HandleException;

// ============================================================================
// Example 1: Simple GET Request
// ============================================================================
echo "=== Example 1: Simple GET Request ===\n";

try {
    $handle = new Handle('https://api.github.com/users/anthropics');

    // Set options using fluent API
    $handle->setOption(HandleOption::UserAgent, 'CustomPHP-Framework/1.0')
           ->setOption(HandleOption::Timeout, 10);

    // Execute and get response
    $response = $handle->fetch();

    echo "Response received: " . strlen($response) . " bytes\n";
    echo "HTTP Code: " . $handle->getInfo(Info::ResponseCode) . "\n";
    echo "Total Time: " . $handle->getInfo(Info::TotalTime) . " seconds\n\n";
} catch (HandleException $e) {
    echo "Error: " . $e->getMessage() . "\n";
    echo "Error Number: " . $handle->errorNumber . "\n";
    echo "Error Message: " . $handle->errorMessage . "\n\n";
}

// ============================================================================
// Example 2: POST Request with JSON Body
// ============================================================================
echo "=== Example 2: POST Request with JSON ===\n";

try {
    $handle = new Handle('https://httpbin.org/post');

    $data = ['name' => 'Test User', 'email' => 'test@example.com'];

    $handle->setOptions([
        HandleOption::Post => true,
        HandleOption::PostFields => json_encode($data),
        HandleOption::HttpHeader => [
            'Content-Type: application/json',
            'Accept: application/json',
        ],
        HandleOption::Timeout => 10,
    ]);

    $response = $handle->fetch();
    echo "POST successful\n";
    echo "Response Code: " . $handle->getInfo(Info::ResponseCode) . "\n\n";
} catch (HandleException $e) {
    echo "POST failed: " . $e->getMessage() . "\n\n";
}

// ============================================================================
// Example 3: Multiple Options with Method Chaining
// ============================================================================
echo "=== Example 3: Fluent API with Method Chaining ===\n";

try {
    $handle = new Handle();

    $response = $handle
        ->setOption(HandleOption::Url, 'https://api.github.com/zen')
        ->setOption(HandleOption::UserAgent, 'PHP-Curl-OOP/1.0')
        ->setOption(HandleOption::Timeout, 10)
        ->setOption(HandleOption::FollowLocation, true)
        ->setOption(HandleOption::MaxRedirs, 5)
        ->fetch();

    echo "GitHub Zen: " . trim($response) . "\n\n";
} catch (HandleException $e) {
    echo "Error: " . $e->getMessage() . "\n\n";
}

// ============================================================================
// Example 4: Parallel Requests with MultiHandle
// ============================================================================
echo "=== Example 4: Parallel Requests ===\n";

try {
    $multi = new MultiHandle();

    // Create multiple handles
    $urls = [
        'https://api.github.com/users/github',
        'https://api.github.com/users/microsoft',
        'https://api.github.com/users/google',
    ];

    $handles = [];
    foreach ($urls as $url) {
        $handle = new Handle($url);
        $handle->setOption(HandleOption::Timeout, 10);
        $handles[] = $handle;
        $multi->addHandle($handle);
    }

    echo "Executing " . $multi->count() . " parallel requests...\n";

    // Execute all requests in parallel
    $completed = $multi->executeAll();

    echo "Completed " . count($completed) . " requests\n";

    // Get results from each handle
    foreach ($handles as $i => $handle) {
        $responseCode = $handle->getInfo(Info::ResponseCode);
        $totalTime = $handle->getInfo(Info::TotalTime);
        echo "Request {$i}: HTTP {$responseCode} in {$totalTime}s\n";
    }

    echo "\n";
} catch (\Exception $e) {
    echo "Multi-request error: " . $e->getMessage() . "\n\n";
}

// ============================================================================
// Example 5: Error Handling with Asymmetric Visibility
// ============================================================================
echo "=== Example 5: Error Handling ===\n";

try {
    $handle = new Handle('https://invalid-domain-that-does-not-exist-12345.com');
    $handle->setOption(HandleOption::Timeout, 5);

    $response = $handle->fetch();
} catch (HandleException $e) {
    echo "Expected error occurred:\n";
    echo "Message: " . $e->getMessage() . "\n";

    // Access error properties (public private(set))
    echo "Error Number: " . $handle->errorNumber . "\n";
    echo "Error Message: " . $handle->errorMessage . "\n";

    // Cannot write (compile error if uncommented):
    // $handle->errorNumber = 123; // ❌ Error: Cannot write to readonly property
    echo "\n";
}

// ============================================================================
// Example 6: Advanced SSL Configuration
// ============================================================================
echo "=== Example 6: SSL Configuration ===\n";

try {
    $handle = new Handle('https://www.google.com');

    $handle->setOptions([
        HandleOption::SslVerifyPeer => true,
        HandleOption::SslVerifyHost => 2,
        HandleOption::SslVersion => CURL_SSLVERSION_TLSv1_2,
        HandleOption::Timeout => 10,
    ]);

    $response = $handle->fetch();

    echo "SSL Connection successful\n";
    echo "Response Code: " . $handle->getInfo(Info::ResponseCode) . "\n";
    echo "SSL Verify Result: " . $handle->getInfo(Info::SslVerifyResult) . "\n\n";
} catch (HandleException $e) {
    echo "SSL Error: " . $e->getMessage() . "\n\n";
}

// ============================================================================
// Example 7: Upload File with Progress Callback
// ============================================================================
echo "=== Example 7: File Upload (Simulated) ===\n";

try {
    $handle = new Handle('https://httpbin.org/post');

    $tempFile = tempnam(sys_get_temp_dir(), 'upload_');
    file_put_contents($tempFile, str_repeat('A', 1024 * 100)); // 100KB

    $fp = fopen($tempFile, 'r');

    $handle->setOptions([
        HandleOption::Upload => true,
        HandleOption::InFile => $fp,
        HandleOption::InFileSize => filesize($tempFile),
        HandleOption::Timeout => 30,
    ]);

    echo "Uploading 100KB file...\n";
    $response = $handle->fetch();

    fclose($fp);
    unlink($tempFile);

    echo "Upload successful\n";
    echo "Response Code: " . $handle->getInfo(Info::ResponseCode) . "\n\n";
} catch (HandleException $e) {
    echo "Upload error: " . $e->getMessage() . "\n\n";
}

// ============================================================================
// Example 8: Comprehensive Info Retrieval
// ============================================================================
echo "=== Example 8: Comprehensive Info Retrieval ===\n";

try {
    $handle = new Handle('https://www.example.com');
    $handle->setOption(HandleOption::Timeout, 10);
    $response = $handle->fetch();

    echo "=== Request Information ===\n";
    echo "Effective URL: " . $handle->getInfo(Info::EffectiveUrl) . "\n";
    echo "HTTP Code: " . $handle->getInfo(Info::HttpCode) . "\n";
    echo "Total Time: " . $handle->getInfo(Info::TotalTime) . " seconds\n";
    echo "Name Lookup Time: " . $handle->getInfo(Info::NameLookupTime) . " seconds\n";
    echo "Connect Time: " . $handle->getInfo(Info::ConnectTime) . " seconds\n";
    echo "Pre-Transfer Time: " . $handle->getInfo(Info::PreTransferTime) . " seconds\n";
    echo "Start Transfer Time: " . $handle->getInfo(Info::StartTransferTime) . " seconds\n";
    echo "Size Download: " . $handle->getInfo(Info::SizeDownload) . " bytes\n";
    echo "Speed Download: " . $handle->getInfo(Info::SpeedDownload) . " bytes/sec\n";
    echo "Header Size: " . $handle->getInfo(Info::HeaderSize) . " bytes\n";
    echo "Request Size: " . $handle->getInfo(Info::RequestSize) . " bytes\n";
    echo "Content Type: " . ($handle->getInfo(Info::ContentType) ?? 'N/A') . "\n";

    // Get all info at once
    $allInfo = $handle->getInfo();
    echo "\nTotal info keys: " . count($allInfo) . "\n\n";
} catch (HandleException $e) {
    echo "Error: " . $e->getMessage() . "\n\n";
}

echo "=== All Examples Completed ===\n";
