<?php

namespace Tests\Tenant\Controllers;

use App\Facades\Settings;
use Carbon\Carbon;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Storage;
use Mtc\MercuryDataModels\ApiNotification;
use Mtc\MercuryDataModels\Setting;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleStandardEquipment;
use Tests\TenantTestCase;

class AutoImagingNotificationControllerTest extends TenantTestCase
{
    use WithFaker;

    private function enableAutoImaging(): void
    {
        Setting::query()->updateOrCreate(
            ['config_key' => 'image-sync-auto-imaging-enabled'],
            [
                'tab' => 'Automotive',
                'section' => 'Image Synchronization',
                'group' => 'AutoImaging',
                'name' => 'Enabled',
                'type' => 'boolean',
                'value' => true,
            ]
        );
    }

    /**
     * A basic feature test example.
     *
     * @return void
     */
    public function testListVehicles()
    {
        $this->enableAutoImaging();
        Config::set('services.image-sync.auto-imaging.key', 'abc');
        $params = [
            'tenant' => tenant('id'),
            'key' => 'abc'
        ];
        $vehicles = Vehicle::factory(3)->create([
            'stock_arrival_date' => Carbon::now()->subDays(10),
            'is_reserved' => false,
        ]);

        $response = $this->getJson(route('tenant.notifications.auto-imaging.index', $params));
        $response->assertStatus(200);
        $this->assertCount(3, $response->json('data'));
        $this->assertArrayHasKey('vrm', $response->json('data.0'));
        $this->assertArrayHasKey('vin', $response->json('data.0'));
        $this->assertArrayHasKey('make', $response->json('data.0'));
        $this->assertArrayHasKey('model', $response->json('data.0'));
        $this->assertArrayHasKey('cap_id', $response->json('data.0'));
        $this->assertArrayHasKey('odometer', $response->json('data.0'));
        $this->assertArrayHasKey('url', $response->json('data.0'));
    }

    public function testUpdateVehicle()
    {
        $this->enableAutoImaging();
        Storage::fake('media');
        Config::set('services.image-sync.auto-imaging.key', 'abc');
        $vehicle = Vehicle::factory()->create();
        if (empty($this->faker->image)) {
            $this->markTestSkipped('Unable to generate test image');
        }
        $response = $this->postJson(route('tenant.notifications.auto-imaging.index', tenant('id')), [
            'key' => 'abc',
            'vehicleId' => $vehicle->registration_number,
            'vimeoUrl' => 'http://foo.baz/bar',
            'images' => [
                ['large' => $this->faker->image],
            ]
        ]);

        $response->assertStatus(200);
        $vehicle->refresh();
        $this->assertEquals('http://foo.baz/bar', $vehicle->exterior_video_url);
        $this->assertEquals(1, $vehicle->mediaUses()->count());
    }

    public function testListVehiclesIncludesEquipmentWhenSettingEnabled()
    {
        $this->enableAutoImaging();
        Config::set('services.image-sync.auto-imaging.key', 'abc');
        Settings::make([
            'tab' => 'Automotive',
            'section' => 'Image Synchronization',
            'group' => 'AutoImaging',
            'name' => 'Include Equipment List',
            'config_key' => 'image-sync-auto-imaging-include-equipment',
            'type' => 'boolean',
            'value' => true,
        ]);

        $vehicle = Vehicle::factory()->create([
            'stock_arrival_date' => Carbon::now()->subDays(10),
            'is_reserved' => false,
        ]);

        VehicleStandardEquipment::factory()->create([
            'vehicle_type' => $vehicle->getMorphClass(),
            'vehicle_id' => $vehicle->id,
            'description' => 'Air Conditioning',
        ]);
        VehicleStandardEquipment::factory()->create([
            'vehicle_type' => $vehicle->getMorphClass(),
            'vehicle_id' => $vehicle->id,
            'description' => 'Bluetooth',
        ]);

        $response = $this->getJson(route('tenant.notifications.auto-imaging.index', [
            'tenant' => tenant('id'),
            'key' => 'abc',
        ]));

        $response->assertStatus(200);
        $this->assertArrayHasKey('EquipmentList', $response->json('data.0'));
        $this->assertStringContainsString('Air Conditioning', $response->json('data.0.EquipmentList'));
        $this->assertStringContainsString('Bluetooth', $response->json('data.0.EquipmentList'));
    }

    public function testListVehiclesExcludesEquipmentWhenSettingDisabled()
    {
        $this->enableAutoImaging();
        Config::set('services.image-sync.auto-imaging.key', 'abc');
        Settings::make([
            'tab' => 'Automotive',
            'section' => 'Image Synchronization',
            'group' => 'AutoImaging',
            'name' => 'Include Equipment List',
            'config_key' => 'image-sync-auto-imaging-include-equipment',
            'type' => 'boolean',
            'value' => false,
        ]);

        $vehicle = Vehicle::factory()->create([
            'stock_arrival_date' => Carbon::now()->subDays(10),
            'is_reserved' => false,
        ]);

        VehicleStandardEquipment::factory()->create([
            'vehicle_type' => $vehicle->getMorphClass(),
            'vehicle_id' => $vehicle->id,
            'description' => 'Air Conditioning',
        ]);

        $response = $this->getJson(route('tenant.notifications.auto-imaging.index', [
            'tenant' => tenant('id'),
            'key' => 'abc',
        ]));

        $response->assertStatus(200);
        $this->assertArrayNotHasKey('EquipmentList', $response->json('data.0'));
    }

    public function testVehicleMissing()
    {
        $this->enableAutoImaging();
        Config::set('services.image-sync.auto-imaging.key', 'abc');
        $response = $this->postJson(route('tenant.notifications.auto-imaging.store', tenant('id')), [
            'key' => 'abc',
            'vehicleId' => 1
        ]);

        // 422 disabled to allow logging and deferred processing
        $response->assertStatus(200);
        //        $this->assertArrayHasKey('vehicleId', $response->json('errors'));
    }

    public function testStoreIsForbiddenWhenIntegrationDisabled()
    {
        Storage::fake('media');
        Config::set('services.image-sync.auto-imaging.key', 'abc');
        $vehicle = Vehicle::factory()->create();

        $response = $this->postJson(route('tenant.notifications.auto-imaging.store', tenant('id')), [
            'key' => 'abc',
            'vehicleId' => $vehicle->registration_number,
            'vimeoUrl' => 'http://foo.baz/bar',
            'images' => [
                ['large' => 'https://ai-backdrop.s3.eu-west-2.amazonaws.com/test/DG14VBC_1.jpg'],
            ],
        ]);

        $response->assertStatus(403);

        $vehicle->refresh();
        // Nothing imported and no notification recorded while the integration is disabled
        $this->assertSame(0, $vehicle->mediaUses()->count());
        $this->assertSame(0, ApiNotification::query()->where('provider', 'auto-imaging')->count());
    }

    public function testListVehiclesIsForbiddenWhenIntegrationDisabled()
    {
        Config::set('services.image-sync.auto-imaging.key', 'abc');
        Vehicle::factory(3)->create([
            'stock_arrival_date' => Carbon::now()->subDays(10),
            'is_reserved' => false,
        ]);

        $response = $this->getJson(route('tenant.notifications.auto-imaging.index', [
            'tenant' => tenant('id'),
            'key' => 'abc',
        ]));

        $response->assertStatus(403);
    }
}
