<?php

namespace Tests\Feature;

use App\Services\LinkedIn\LinkedInRestApi;
use App\Services\Meta\MetaException;
use App\Services\Platforms\Support\CallLogger;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\Http;
use Tests\TestCase;

class LinkedInRestApiTest extends TestCase
{
    use RefreshDatabase;

    private LinkedInRestApi $api;

    protected function setUp(): void
    {
        parent::setUp();

        config([
            'platforms.guardrails.allowed_ad_accounts' => ['509999999', 'urn:li:sponsoredAccount:509999999'],
            'platforms.guardrails.retry_backoff_ms' => 0,
        ]);

        $this->api = new LinkedInRestApi(
            'mock-linkedin-token',
            '202401',
            app(CallLogger::class),
        );
    }

    public function test_lists_ad_accounts(): void
    {
        Http::fake([
            'https://api.linkedin.com/rest/adAccounts*' => Http::response([
                'elements' => [
                    ['id' => 509999999, 'name' => 'AdMedia Corporate Account', 'currency' => 'USD'],
                ],
            ], 200),
        ]);

        $accounts = $this->api->adAccounts();

        $this->assertCount(1, $accounts);
        $this->assertSame(509999999, $accounts[0]['id']);

        Http::assertSent(function (Request $request): bool {
            return $request->hasHeader('Authorization', 'Bearer mock-linkedin-token')
                && $request->hasHeader('LinkedIn-Version', '202401')
                && $request->hasHeader('X-Restli-Protocol-Version', '2.0.0');
        });
    }

    public function test_creates_campaign_group(): void
    {
        Http::fake([
            'https://api.linkedin.com/rest/adAccounts/*/adCampaignGroups' => Http::response([], 201, [
                'x-restli-id' => 'urn:li:sponsoredCampaignGroup:12345',
            ]),
        ]);

        $response = $this->api->createCampaignGroup('509999999', [
            'name' => 'Q4 Enterprise Promo',
            'status' => 'PAUSED',
        ]);

        $this->assertSame('urn:li:sponsoredCampaignGroup:12345', $response['id']);

        Http::assertSent(function (Request $request): bool {
            $data = $request->data();

            return ($data['name'] ?? null) === 'Q4 Enterprise Promo'
                && ($data['account'] ?? null) === 'urn:li:sponsoredAccount:509999999';
        });
    }

    public function test_creates_campaign(): void
    {
        Http::fake([
            'https://api.linkedin.com/rest/adAccounts/*/adCampaigns' => Http::response([], 201, [
                'x-restli-id' => 'urn:li:sponsoredCampaign:67890',
            ]),
        ]);

        $response = $this->api->createCampaign('509999999', [
            'name' => 'Sponsored InFeed Campaign',
            'campaignGroup' => 'urn:li:sponsoredCampaignGroup:12345',
            'objectiveType' => 'WEBSITE_VISITS',
        ]);

        $this->assertSame('urn:li:sponsoredCampaign:67890', $response['id']);
    }

    public function test_disallowed_ad_account_is_blocked_by_guardrails(): void
    {
        $this->expectException(MetaException::class);
        $this->expectExceptionMessage('not on the allowed list');

        $this->api->createCampaignGroup('999999999', [
            'name' => 'Unauthorized Group',
        ]);
    }
}
