<?php

namespace Tests\Unit;

use App\Crm\SendCopyViaMail;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Mail;
use Mtc\Crm\Facades\Enquiries;
use Mtc\Crm\Models\Enquiry;
use Mtc\Crm\Models\EnquiryAction;
use Mtc\Crm\Models\Form;
use Mtc\Crm\Models\FormQuestion;
use Mtc\Crm\Models\FormSection;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\VehicleAttribute;
use Mtc\MercuryDataModels\VehicleAttributeValue;
use Tests\TestCase;

class SendCopyViaMailTest extends TestCase
{
    use RefreshDatabase;

    protected $tenancy = true;

    protected function setUp(): void
    {
        parent::setUp();
        Mail::fake();
    }

    public function testFormAdditionalDataFieldsContainsSendToFieldLocation()
    {
        $fields = Enquiries::makeAction('send-copy-via-mail')->formAdditionalDataFields();

        $this->assertIsArray($fields);
        $this->assertArrayHasKey('send_to_field_location', $fields);
        $this->assertEquals('select', $fields['send_to_field_location']['type']);
        $this->assertEquals('form-questions', $fields['send_to_field_location']['source']);
    }

    public function testHandleSendsEmailToDirectEmailAnswer()
    {
        $form = Form::factory()->create();
        $section = FormSection::factory()->create(['form_id' => $form->id]);
        $question = FormQuestion::factory()->create([
            'form_id' => $form->id,
            'form_section_id' => $section->id,
            'name' => 'Email Address',
            'data' => [],
        ]);

        $enquiry = Enquiry::factory()->create([
            'form_id' => $form->id,
            'details' => [
                [
                    'id' => $question->id,
                    'question' => 'Email Address',
                    'answer' => 'test@example.com',
                ],
            ],
        ]);

        $action = EnquiryAction::factory()->create([
            'enquiry_id' => $enquiry->id,
            'action_name' => 'send-copy-via-mail',
            'data' => [
                'send_to_field_location' => 'Email Address',
                'enquiry_subject' => 'Test Subject',
            ],
            'processed_at' => null,
            'failed_at' => null,
        ]);

        $sendCopyViaMail = Enquiries::makeAction('send-copy-via-mail');
        $result = $sendCopyViaMail->handle($action, $enquiry);

        $this->assertTrue($result);
        Mail::assertSent(config('crm.new_enquiry_email'), function ($mail) {
            return $mail->hasTo('test@example.com');
        });
    }

    public function testHandleSendsEmailToDealershipMainEmail()
    {
        $dealership = Dealership::factory()->create([
            'email' => 'dealership@example.com',
        ]);

        $form = Form::factory()->create();
        $section = FormSection::factory()->create(['form_id' => $form->id]);
        $question = FormQuestion::factory()->create([
            'form_id' => $form->id,
            'form_section_id' => $section->id,
            'name' => 'Select Dealership',
            'data' => [
                'meta' => [
                    'options' => [
                        'source' => 'dealerships',
                        'emailField' => 'email',
                    ],
                ],
            ],
        ]);

        $enquiry = Enquiry::factory()->create([
            'form_id' => $form->id,
            'details' => [
                [
                    'id' => $question->id,
                    'question' => 'Select Dealership',
                    'answer' => $dealership->id,
                ],
            ],
        ]);
        $enquiry->load('form.questions');

        $action = EnquiryAction::factory()->create([
            'enquiry_id' => $enquiry->id,
            'action_name' => 'send-copy-via-mail',
            'data' => [
                'send_to_field_location' => 'Select Dealership',
                'enquiry_subject' => 'Test Subject',
            ],
            'processed_at' => null,
            'failed_at' => null,
        ]);

        $sendCopyViaMail = Enquiries::makeAction('send-copy-via-mail');
        $result = $sendCopyViaMail->handle($action, $enquiry);

        $this->assertTrue($result);
        Mail::assertSent(config('crm.new_enquiry_email'), function ($mail) {
            return $mail->hasTo('dealership@example.com');
        });
    }

    public function testHandleSendsEmailToDealershipEmailAttribute()
    {
        $dealership = Dealership::factory()->create([
            'email' => 'main@example.com',
        ]);

        $attribute = VehicleAttribute::factory()->create([
            'name' => 'Sales Email',
            'slug' => 'sales_email',
            'type' => 'email',
            'model' => 'dealership',
        ]);

        VehicleAttributeValue::factory()->create([
            'owner_type' => 'dealership',
            'owner_id' => $dealership->id,
            'attribute_id' => $attribute->id,
            'slug' => 'sales_email',
            'type' => 'email',
            'value_text' => 'sales@example.com',
        ]);

        $form = Form::factory()->create();
        $section = FormSection::factory()->create(['form_id' => $form->id]);
        $question = FormQuestion::factory()->create([
            'form_id' => $form->id,
            'form_section_id' => $section->id,
            'name' => 'Select Dealership',
            'data' => [
                'meta' => [
                    'options' => [
                        'source' => 'dealerships',
                        'emailField' => 'attribute:sales_email',
                    ],
                ],
            ],
        ]);

        $enquiry = Enquiry::factory()->create([
            'form_id' => $form->id,
            'details' => [
                [
                    'id' => $question->id,
                    'question' => 'Select Dealership',
                    'answer' => $dealership->id,
                ],
            ],
        ]);
        $enquiry->load('form.questions');

        $action = EnquiryAction::factory()->create([
            'enquiry_id' => $enquiry->id,
            'action_name' => 'send-copy-via-mail',
            'data' => [
                'send_to_field_location' => 'Select Dealership',
                'enquiry_subject' => 'Test Subject',
            ],
            'processed_at' => null,
            'failed_at' => null,
        ]);

        $sendCopyViaMail = Enquiries::makeAction('send-copy-via-mail');
        $result = $sendCopyViaMail->handle($action, $enquiry);

        $this->assertTrue($result);
        Mail::assertSent(config('crm.new_enquiry_email'), function ($mail) {
            return $mail->hasTo('sales@example.com');
        });
    }

    public function testHandleFallsBackToMainRecipientWhenNoEmailFieldConfigured()
    {
        $dealership = Dealership::factory()->create([
            'email' => 'dealership@example.com',
        ]);

        $form = Form::factory()->create();
        $section = FormSection::factory()->create(['form_id' => $form->id]);
        $question = FormQuestion::factory()->create([
            'form_id' => $form->id,
            'form_section_id' => $section->id,
            'name' => 'Select Dealership',
            'data' => [
                'meta' => [
                    'options' => [
                        'source' => 'dealerships',
                        // No emailField configured
                    ],
                ],
            ],
        ]);

        $enquiry = Enquiry::factory()->create([
            'form_id' => $form->id,
            'details' => [
                [
                    'id' => $question->id,
                    'question' => 'Select Dealership',
                    'answer' => $dealership->id,
                ],
            ],
        ]);
        $enquiry->load('form.questions');

        $action = EnquiryAction::factory()->create([
            'enquiry_id' => $enquiry->id,
            'action_name' => 'send-copy-via-mail',
            'data' => [
                'send_to_field_location' => 'Select Dealership',
                'recipient' => 'fallback@example.com',
                'enquiry_subject' => 'Test Subject',
            ],
            'processed_at' => null,
            'failed_at' => null,
        ]);

        $sendCopyViaMail = Enquiries::makeAction('send-copy-via-mail');
        $result = $sendCopyViaMail->handle($action, $enquiry);

        $this->assertTrue($result);
        Mail::assertSent(config('crm.new_enquiry_email'), function ($mail) {
            return $mail->hasTo('fallback@example.com');
        });
    }

    public function testHandleSendsToBothWhenSendToBothEnabled()
    {
        $dealership = Dealership::factory()->create([
            'email' => 'dealership@example.com',
        ]);

        $form = Form::factory()->create();
        $section = FormSection::factory()->create(['form_id' => $form->id]);
        $question = FormQuestion::factory()->create([
            'form_id' => $form->id,
            'form_section_id' => $section->id,
            'name' => 'Select Dealership',
            'data' => [
                'meta' => [
                    'options' => [
                        'source' => 'dealerships',
                        'emailField' => 'email',
                    ],
                ],
            ],
        ]);

        $enquiry = Enquiry::factory()->create([
            'form_id' => $form->id,
            'details' => [
                [
                    'id' => $question->id,
                    'question' => 'Select Dealership',
                    'answer' => $dealership->id,
                ],
            ],
        ]);
        $enquiry->load('form.questions');

        $action = EnquiryAction::factory()->create([
            'enquiry_id' => $enquiry->id,
            'action_name' => 'send-copy-via-mail',
            'data' => [
                'send_to_field_location' => 'Select Dealership',
                'send_to_both' => true,
                'recipient' => 'additional@example.com',
                'enquiry_subject' => 'Test Subject',
            ],
            'processed_at' => null,
            'failed_at' => null,
        ]);

        $sendCopyViaMail = Enquiries::makeAction('send-copy-via-mail');
        $result = $sendCopyViaMail->handle($action, $enquiry);

        $this->assertTrue($result);
        Mail::assertSent(config('crm.new_enquiry_email'), function ($mail) {
            return $mail->hasTo('dealership@example.com');
        });
        Mail::assertSent(config('crm.new_enquiry_email'), function ($mail) {
            return $mail->hasTo('additional@example.com');
        });
    }

    public function testHandleReturnsNullWhenDealershipNotFound()
    {
        $form = Form::factory()->create();
        $section = FormSection::factory()->create(['form_id' => $form->id]);
        $question = FormQuestion::factory()->create([
            'form_id' => $form->id,
            'form_section_id' => $section->id,
            'name' => 'Select Dealership',
            'data' => [
                'meta' => [
                    'options' => [
                        'source' => 'dealerships',
                        'emailField' => 'email',
                    ],
                ],
            ],
        ]);

        $enquiry = Enquiry::factory()->create([
            'form_id' => $form->id,
            'details' => [
                [
                    'id' => $question->id,
                    'question' => 'Select Dealership',
                    'answer' => 99999, // Non-existent dealership
                ],
            ],
        ]);
        $enquiry->load('form.questions');

        $action = EnquiryAction::factory()->create([
            'enquiry_id' => $enquiry->id,
            'action_name' => 'send-copy-via-mail',
            'data' => [
                'send_to_field_location' => 'Select Dealership',
                'enquiry_subject' => 'Test Subject',
            ],
            'processed_at' => null,
            'failed_at' => null,
        ]);

        $sendCopyViaMail = Enquiries::makeAction('send-copy-via-mail');
        $result = $sendCopyViaMail->handle($action, $enquiry);

        $this->assertFalse($result);
        $this->assertEquals('no recipient specified', $sendCopyViaMail->failureReason());
    }

    public function testGetDealershipEmailReturnsNullForMissingAttribute()
    {
        $dealership = Dealership::factory()->create([
            'email' => 'main@example.com',
        ]);

        $form = Form::factory()->create();
        $section = FormSection::factory()->create(['form_id' => $form->id]);
        $question = FormQuestion::factory()->create([
            'form_id' => $form->id,
            'form_section_id' => $section->id,
            'name' => 'Select Dealership',
            'data' => [
                'meta' => [
                    'options' => [
                        'source' => 'dealerships',
                        'emailField' => 'attribute:nonexistent_email',
                    ],
                ],
            ],
        ]);

        $enquiry = Enquiry::factory()->create([
            'form_id' => $form->id,
            'details' => [
                [
                    'id' => $question->id,
                    'question' => 'Select Dealership',
                    'answer' => $dealership->id,
                ],
            ],
        ]);
        $enquiry->load('form.questions');

        $action = EnquiryAction::factory()->create([
            'enquiry_id' => $enquiry->id,
            'action_name' => 'send-copy-via-mail',
            'data' => [
                'send_to_field_location' => 'Select Dealership',
                'recipient' => 'fallback@example.com',
                'enquiry_subject' => 'Test Subject',
            ],
            'processed_at' => null,
            'failed_at' => null,
        ]);

        $sendCopyViaMail = Enquiries::makeAction('send-copy-via-mail');
        $result = $sendCopyViaMail->handle($action, $enquiry);

        // Should fall back to recipient since attribute doesn't exist
        $this->assertTrue($result);
        Mail::assertSent(config('crm.new_enquiry_email'), function ($mail) {
            return $mail->hasTo('fallback@example.com');
        });
    }
}
