<?php

namespace Tests\Unit;

use App\Crm\Config\BrevoConfig;
use App\Facades\Settings;
use App\Services\BrevoApi;
use Database\Seeders\Tenant\BrevoSettingSeeder;
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use GuzzleHttp\Psr7\Response;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Mtc\Crm\Facades\Enquiries;
use Mtc\Crm\Models\Enquiry;
use Mtc\Crm\Models\EnquiryAction;
use Tests\TenantTestCase;
use Tests\TestCase;
use Tests\UserForTenant;
use Mockery;

class SendToBrevoTest extends TenantTestCase
{

    public function testSendToBrevo()
    {
        $history = [];
        $historyMiddleware = Middleware::history($history);

        // Mock responses for Guzzle
        $mock = new MockHandler([
            new Response(200),
            new Response(400, [], json_encode([
                'code' => 'duplicate_parameter',
                'message' => 'email is already associated with another Contact'
            ])),
        ]);

        $handlerStack = HandlerStack::create($mock);
        $handlerStack->push($historyMiddleware);
        $mockHttpClient = new Client(['handler' => $handlerStack]);
        $mockConfig = Mockery::mock(BrevoConfig::class);
        $mockConfig->shouldReceive('apiKey')
            ->andReturn('test-api-key');

        $this->app->bind(BrevoApi::class, function () use ($mockConfig, $mockHttpClient) {
            return new BrevoApi($mockConfig, $mockHttpClient);
        });

        $enquiry = Enquiry::factory()->create([
                'email'=>'test@example.com',
                'details' => []
            ]
        );

        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-brevo',
            'data' => [
                'brevo_list_id' => 12345,
                'brevo_update_enabled' => true,
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        $brevo = Enquiries::makeAction('send-to-brevo');

        //Successful request
        $response = $brevo->handle($action, $enquiry);
        $this->assertCount(1, $history);
        $request = $history[0]['request'];
        $this->assertEquals('POST', $request->getMethod());
        $this->assertEquals('https://api.brevo.com/v3/contacts', (string)$request->getUri());
        $this->assertTrue($response);
        $this->assertEquals(
            'Contact with email test@example.com has been successfully created and added to the following list(s): 12345.',
            $brevo->successDetails()
        );

        //Failed request
        $response = $brevo->handle($action, $enquiry);
        $this->assertCount(2, $history);
        $request = $history[1]['request'];
        $this->assertEquals('POST', $request->getMethod());
        $this->assertEquals('https://api.brevo.com/v3/contacts', (string)$request->getUri());
        $this->assertFalse($response);
        $this->assertEquals(
            'email is already associated with another Contact',
            $brevo->failureReason()
        );
    }

    public function testGetFormAdditionalDataFields()
    {
        $fields = Enquiries::makeAction('send-to-brevo')->formAdditionalDataFields();
        $this->assertIsArray($fields);
        $this->assertArrayHasKey('brevo_list_id', $fields);
        $this->assertArrayHasKey('brevo_update_enabled', $fields);
    }

    public function testApiKeyReturnsCorrectValue()
    {
        $this->seed(BrevoSettingSeeder::class);
        Settings::update('brevo-api-key', 'foo-baz');
        $config = new BrevoConfig();
        $this->assertEquals('foo-baz', $config->apiKey());
    }
}
