<?php

namespace Tests\Tenant;

use App\Facades\Settings;
use App\Jobs\CarAndDrivingImportJob;
use App\Jobs\ImportImagesFromUrlList;
use App\Services\CarAndDrivingService;
use App\VehicleType;
use Database\Seeders\Tenant\CarAndDrivingReviewSeeder;
use Database\Seeders\Tenant\CarAndDrivingSeeder;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\Http;
use Mtc\MercuryDataModels\Vehicle;
use Tests\TenantTestCase;

class CarAndDrivingImportTest extends TenantTestCase
{
    #[\Override]
    protected function setUp(): void
    {
        parent::setUp();

        new CarAndDrivingSeeder()->run();
        new CarAndDrivingReviewSeeder()->run();

        Settings::shouldReceive('get')->andReturn(null)->byDefault();

        Http::preventStrayRequests();
    }

    public function testCreateReviewsAndVideo()
    {
        Bus::fake();
        Settings::shouldReceive('get')
            ->with('app-content-car-and-driving-enabled')
            ->andReturn(true);

        Settings::shouldReceive('get')
            ->with('app-content-car-and-driving-user-id')
            ->andReturn('test-tenant');

        Settings::shouldReceive('get')
            ->with('app-content-car-and-driving-image-sync-vehicle-types', 'none')
            ->andReturn("new");

        Settings::shouldReceive('get')
            ->with('app-content-car-and-driving-image-import-behaviour')
            ->andReturn("add");

        Settings::shouldReceive('get')
            ->with('app-content-car-and-driving-should-sync-videos')
            ->andReturn(true);

        Settings::shouldReceive('get')
            ->with('app-content-car-and-driving-sync-type')
            ->andReturn('new');
        Settings::shouldReceive('get')
            ->with('app-content-car-and-driving-should-delete-existing-images', false)
            ->andReturn(false);

        $this->mockApiResponse();

        $vehicle = Vehicle::factory()
            ->create([
                'cap_id' => '102373',
                'is_new' => 1,
                'type' => VehicleType::CAR->value
            ]);


        new CarAndDrivingImportJob()->handle();
        Bus::assertDispatched(ImportImagesFromUrlList::class);

        $this->assertDatabaseHas('vehicle_reviews', [
            'external_review_id' => '12767',
            'make'               => 'Abarth',
            'model'              => '500e',
        ]);

        $review = \Mtc\MercuryDataModels\VehicleReview::where('external_review_id', '12767')->first();
        $this->assertNotNull($review->main_video_url, 'main_video_url should be stored on the review row');

        $this->assertDatabaseHas('vehicles', [
            'cap_id' => '102373',
        ]);

        $vehicle = Vehicle::where('cap_id', '102373')->first();
        $this->assertEquals('https://ssl.caranddriving.com/f6/videos/shorts700/short_Abarth500e_2023.mp4', $vehicle->main_video_url);

        $this->assertDatabaseHas('api_notifications', [
            'provider' => 'car-and-driving',
            'processed' => true,
            'data_model' => \Mtc\MercuryDataModels\VehicleReview::class,
        ]);


        $notification = \Mtc\MercuryDataModels\ApiNotification::first();
        $summary = $notification->data['summary'];

        $this->assertGreaterThan(0, $summary['total_reviews_received']);
        $this->assertGreaterThanOrEqual(1, $summary['total_reviews_processed']);
        $this->assertGreaterThanOrEqual(1, $summary['total_cap_codes_received']);
        $this->assertGreaterThanOrEqual(1, $summary['total_cap_ids_that_exists_on_site']);
        $this->assertContains('102373', $summary['cap_ids_that_exists_on_site']);

        $this->assertGreaterThanOrEqual(1, $summary['total_images_processed']);
        $this->assertGreaterThanOrEqual(1, $summary['total_videos_processed']);
    }

    public function testImportSkipsWhenIntegrationIsNotEnabled()
    {
        $this->mockApiResponse();

        Settings::shouldReceive('get')
            ->with('app-content-car-and-driving-enabled')
            ->once()
            ->andReturn(false);

        Artisan::call('car-and-driving:bulk-import');

        $this->assertDatabaseCount('vehicle_reviews', 0);
    }

    public function testDeletesCarAndDrivingImagesWhenSettingIsActivated()
    {
        $vehicle = Vehicle::factory()->create(['cap_id' => '102373', 'is_new' => 1, 'type' => VehicleType::CAR->value]);
        $carAndDrivingMedia = \Mtc\ContentManager\Models\Media::factory()->create(['image_provider' => 'car-and-driving']);
        $otherProviderMedia = \Mtc\ContentManager\Models\Media::factory()->create(['image_provider' => 'other-provider']);

        $vehicle->mediaUses()->create(['media_id' => $carAndDrivingMedia->id]);
        $vehicle->mediaUses()->create(['media_id' => $otherProviderMedia->id]);

        Settings::shouldReceive('get')
            ->with('app-content-car-and-driving-enabled')->andReturn(true);
        Settings::shouldReceive('get')
            ->with('app-content-car-and-driving-user-id')->andReturn('test-tenant');
        Settings::shouldReceive('get')
            ->with('app-content-car-and-driving-image-sync-vehicle-types', 'none')->andReturn("new");
        Settings::shouldReceive('get')
            ->with('app-content-car-and-driving-image-import-behaviour')->andReturn("add");
        Settings::shouldReceive('get')
            ->with('app-content-car-and-driving-should-sync-videos')->andReturn(true);
        Settings::shouldReceive('get')
            ->with('app-content-car-and-driving-sync-type')->andReturn('new');
        Settings::shouldReceive('get')
            ->with('app-content-car-and-driving-should-delete-existing-images', false)->andReturn(true);
        Settings::shouldReceive('get')
            ->with('app-content-car-and-driving-image-overwrite-threshold', 0)->andReturn(1);

        $this->mockApiResponse();

        new CarAndDrivingImportJob()->handle();

        $this->assertDatabaseMissing('media_uses', [
            'media_id' => $carAndDrivingMedia->id,
            'owner_id' => $vehicle->id,
        ]);
        $this->assertDatabaseHas('media_uses', [
            'media_id' => $otherProviderMedia->id,
            'owner_id' => $vehicle->id,
        ]);
    }

    private function mockApiResponse()
    {
        $service = new CarAndDrivingService();
        Http::fake([
            $service->getEndpoint() . '*' => Http::response(
                file_get_contents(base_path('tests/data/car-and-driving.xml'), true),
                200
            ),
        ]);
    }
}
