<?php

namespace Tests\Tenant;

use App\Crm\SendLeadExportNotification;
use App\Models\LeadExport;
use Illuminate\Support\Facades\Http;
use Mtc\Crm\Models\Enquiry;
use Mtc\Crm\Models\EnquiryAction;
use Mtc\Crm\Models\FormQuestion;
use Mtc\MercuryDataModels\ApiNotification;
use Tests\TenantTestCase;

class SendLeadExportNotificationTest extends TenantTestCase
{
    public function testMappedPayloadIsNestedCoercedAndDelivered(): void
    {
        Http::fake(['*' => Http::response(['ok' => true], 200)]);

        $leadExport = LeadExport::query()->create([
            'name' => 'Partner CRM',
            'type' => 'lead',
            'active' => true,
            'mode' => LeadExport::MODE_MAPPED,
            'url' => 'https://crm.example.com/leads',
            'password' => 'secret-token',
            'field_map' => [
                ['destination' => 'contact.first_name', 'type' => 'string'],
                ['destination' => 'vehicle.year', 'type' => 'integer'],
            ],
        ]);

        $firstNameQuestion = FormQuestion::factory()->create([
            'name' => 'First name',
            'data' => [$leadExport->providerKey() => 'contact.first_name'],
        ]);
        $yearQuestion = FormQuestion::factory()->create([
            'name' => 'Year of interest',
            'data' => [$leadExport->providerKey() => 'vehicle.year'],
        ]);

        $enquiry = Enquiry::factory()->create();
        $enquiry->details = [
            ['id' => $firstNameQuestion->id, 'question' => 'First name', 'answer' => 'Jane'],
            ['id' => $yearQuestion->id, 'question' => 'Year of interest', 'answer' => '2020'],
        ];
        $enquiry->save();

        $action = EnquiryAction::factory()->create([
            'enquiry_id' => $enquiry->id,
            'action_name' => $leadExport->providerKey(),
            'data' => [],
            'processed_at' => null,
            'failed_at' => null,
        ]);

        $result = (new SendLeadExportNotification())->handle($action, $enquiry);

        $this->assertTrue($result);

        Http::assertSent(function ($request) use ($leadExport) {
            return $request->url() === $leadExport->url
                && $request->hasHeader('Authorization', 'Bearer secret-token')
                && data_get($request->data(), 'contact.first_name') === 'Jane'
                && data_get($request->data(), 'vehicle.year') === 2020;
        });

        $this->assertSame(
            1,
            ApiNotification::query()->where('provider', $leadExport->providerKey())->count()
        );
    }

    public function testPassthroughPayloadIsKeyedByFieldName(): void
    {
        Http::fake(['*' => Http::response([], 200)]);

        $leadExport = LeadExport::query()->create([
            'name' => 'Free Form CRM',
            'type' => 'lead',
            'active' => true,
            'mode' => LeadExport::MODE_PASSTHROUGH,
            'url' => 'https://crm.example.com/free',
        ]);

        $enquiry = Enquiry::factory()->create();
        $enquiry->details = [
            ['id' => 1, 'question' => 'Full name', 'answer' => 'Jane Doe'],
            ['id' => 2, 'question' => 'Email', 'answer' => 'jane@example.com'],
        ];
        $enquiry->save();

        $action = EnquiryAction::factory()->create([
            'enquiry_id' => $enquiry->id,
            'action_name' => $leadExport->providerKey(),
            'data' => [],
            'processed_at' => null,
            'failed_at' => null,
        ]);

        $result = (new SendLeadExportNotification())->handle($action, $enquiry);

        $this->assertTrue($result);

        Http::assertSent(function ($request) {
            return data_get($request->data(), 'Full name') === 'Jane Doe'
                && data_get($request->data(), 'Email') === 'jane@example.com';
        });
    }

    public function testMappedPayloadIncludesMarketingAttributionFromEnquiryMeta(): void
    {
        Http::fake(['*' => Http::response(['ok' => true], 200)]);

        $leadExport = LeadExport::query()->create([
            'name' => 'Attribution CRM',
            'type' => 'lead',
            'active' => true,
            'mode' => LeadExport::MODE_MAPPED,
            'url' => 'https://crm.example.com/leads',
            'field_map' => [
                ['destination' => 'marketing.utm_source', 'type' => 'string'],
            ],
        ]);

        $enquiry = Enquiry::factory()->create();
        $enquiry->source = 'https://site.test/landing?utm_source=google';
        $enquiry->data = ['meta' => [
            'utm_source' => 'google',
            'utm_medium' => 'cpc',
            'utm_campaign' => 'summer',
            'gclid' => 'abc123',
        ]];
        $enquiry->save();

        $action = EnquiryAction::factory()->create([
            'enquiry_id' => $enquiry->id,
            'action_name' => $leadExport->providerKey(),
            'data' => [],
            'processed_at' => null,
            'failed_at' => null,
        ]);

        $this->assertTrue((new SendLeadExportNotification())->handle($action, $enquiry));

        Http::assertSent(function ($request) {
            return data_get($request->data(), 'marketing.utm_source') === 'google'
                && data_get($request->data(), 'marketing.utm_medium') === 'cpc'
                && data_get($request->data(), 'marketing.utm_campaign') === 'summer'
                && data_get($request->data(), 'marketing.gclid') === 'abc123'
                && data_get($request->data(), 'marketing.landing_page')
                    === 'https://site.test/landing?utm_source=google';
        });
    }

    public function testPassthroughAppendsMarketingBlockAlongsideAnswers(): void
    {
        Http::fake(['*' => Http::response([], 200)]);

        $leadExport = LeadExport::query()->create([
            'name' => 'Free Form CRM',
            'type' => 'lead',
            'active' => true,
            'mode' => LeadExport::MODE_PASSTHROUGH,
            'url' => 'https://crm.example.com/free',
        ]);

        $enquiry = Enquiry::factory()->create();
        $enquiry->source = 'https://site.test/landing';
        $enquiry->details = [
            ['id' => 1, 'question' => 'Full name', 'answer' => 'Jane Doe'],
        ];
        $enquiry->data = ['meta' => ['utm_source' => 'autotrader', 'gclid' => 'xyz']];
        $enquiry->save();

        $action = EnquiryAction::factory()->create([
            'enquiry_id' => $enquiry->id,
            'action_name' => $leadExport->providerKey(),
            'data' => [],
            'processed_at' => null,
            'failed_at' => null,
        ]);

        $this->assertTrue((new SendLeadExportNotification())->handle($action, $enquiry));

        Http::assertSent(function ($request) {
            // Form answers stay keyed by their field name; attribution sits in its own block.
            return data_get($request->data(), 'Full name') === 'Jane Doe'
                && data_get($request->data(), 'marketing.utm_source') === 'autotrader'
                && data_get($request->data(), 'marketing.gclid') === 'xyz'
                && data_get($request->data(), 'marketing.landing_page') === 'https://site.test/landing';
        });
    }

    public function testActionLabelResolvesExportName(): void
    {
        $leadExport = LeadExport::create([
            'name' => 'Partner CRM',
            'type' => 'lead',
            'mode' => LeadExport::MODE_PASSTHROUGH,
        ]);

        // Lead-export actions show the export's own name; other actions title-case the key.
        $this->assertSame('Partner CRM', LeadExport::actionLabel($leadExport->providerKey()));
        $this->assertSame('Send To Salesforce', LeadExport::actionLabel('send-to-salesforce'));
    }

    public function testInactiveExportFailsWithoutSending(): void
    {
        Http::fake();

        $leadExport = LeadExport::query()->create([
            'name' => 'Off CRM',
            'type' => 'lead',
            'active' => false,
            'mode' => LeadExport::MODE_PASSTHROUGH,
            'url' => 'https://crm.example.com/off',
        ]);

        $enquiry = Enquiry::factory()->create();
        $action = EnquiryAction::factory()->create([
            'enquiry_id' => $enquiry->id,
            'action_name' => $leadExport->providerKey(),
            'data' => [],
            'processed_at' => null,
            'failed_at' => null,
        ]);

        $result = (new SendLeadExportNotification())->handle($action, $enquiry);

        $this->assertFalse($result);
        Http::assertNothingSent();
    }
}
