<?php

namespace Tests\Unit\Services;

use App\Services\CloudflareService;
use Illuminate\Support\Facades\Http;
use Mtc\MercuryDataModels\Tenant;
use Tests\TestCase;

class CloudflareServiceTest extends TestCase
{
    public function testClearCacheSendsCorrectRequest()
    {
        // Mock the Tenant model
        $tenant = new Tenant();
        $tenant->cloudflare_data = [
            'zone_id' => 'example-zone-id',
        ];

        // Mock the HTTP response
        Http::fake([
            'https://api.cloudflare.com/client/v4/zones/example-zone-id/purge_cache' => Http::response(['success' => true], 200),
        ]);

        // Instantiate the service
        $service = new CloudflareService();

        // Call the clear method
        $response = $service->clear($tenant);

        // Assert the response is successful
        $this->assertTrue($response->successful());

        // Assert the correct HTTP request was sent
        Http::assertSent(function ($request) {
            return $request->url() === 'https://api.cloudflare.com/client/v4/zones/example-zone-id/purge_cache' &&
                $request->method() === 'POST' &&
                $request->hasHeader('Content-Type', 'application/json') &&
                $request->hasHeader('X-Auth-Email', config('services.cloudflare.email')) &&
                $request->hasHeader('X-Auth-Key', config('services.cloudflare.api_key')) &&
                $request['purge_everything'] === true;
        });
    }

    public function testCacheEndpointReturnsCorrectUrl()
    {
        $service = new CloudflareService();

        $zoneId = 'example-zone-id';
        $expectedUrl = "https://api.cloudflare.com/client/v4/zones/$zoneId/purge_cache";

        $this->assertEquals($expectedUrl, $this->invokeMethod($service, 'cacheEndpoint', [$zoneId]));
    }

    /**
     * Helper to invoke private or protected methods.
     *
     * @param object $object
     * @param string $methodName
     * @param array $parameters
     * @return mixed
     */
    protected function invokeMethod(object $object, string $methodName, array $parameters = [])
    {
        $reflection = new \ReflectionClass($object);
        $method = $reflection->getMethod($methodName);
        $method->setAccessible(true);

        return $method->invokeArgs($object, $parameters);
    }
}
