<?php

namespace Tests\Tenant;

use App\Http\Resources\FormViewResource;
use App\Traits\MapElementBasedContent;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Mtc\Crm\Models\Form;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\Vehicle;
use ReflectionProperty;
use Tests\TenantTestCase;

class MapElementBasedContentTest extends TenantTestCase
{
    /**
     * A content-embedded form block should pre-fill the Dealership field with the
     * associated vehicle's dealership, so the enquiry carries the branch and the
     * recipient map fires (AUTO-1702).
     */
    public function testFormBlockPrefillsDealershipFromAssociatedVehicle(): void
    {
        $dealership = Dealership::factory()->create();
        $vehicle = Vehicle::factory()->create(['dealership_id' => $dealership->id]);
        $form = Form::factory()->create();

        $values = $this->assignedValuesForFormBlock(
            $form->id,
            new Request(['vehicle_id' => $vehicle->id])
        );

        $this->assertSame($vehicle->id, $values['vehicle_id']);
        $this->assertSame($dealership->id, $values['dealership_id']);
    }

    /**
     * Without an associated vehicle the Dealership stays null - identical to the
     * previous behaviour, so plain content forms are unaffected.
     */
    public function testFormBlockLeavesDealershipNullWithoutVehicle(): void
    {
        $form = Form::factory()->create();

        $values = $this->assignedValuesForFormBlock($form->id, new Request());

        $this->assertNull($values['vehicle_id']);
        $this->assertNull($values['dealership_id']);
    }

    /**
     * Run mapContent() for a form block and return the values assigned to the resulting
     * FormViewResource. mapContent() is a private trait method, so it is exercised through
     * an anonymous class that uses the trait.
     */
    private function assignedValuesForFormBlock(int $formId, Request $request): array
    {
        $harness = new class () {
            use MapElementBasedContent;

            public function build(Model $resource, array $entry, Request $request): array
            {
                return $this->mapContent($resource, $entry, $request, 'content');
            }
        };

        $result = $harness->build(
            new Vehicle(),
            ['field_type' => 'form', 'content' => $formId],
            $request
        );

        $this->assertInstanceOf(FormViewResource::class, $result['content']);

        $property = new ReflectionProperty(FormViewResource::class, 'assignedValues');
        $property->setAccessible(true);

        return $property->getValue($result['content']);
    }
}
