<?php

namespace Tests\Tenant;

use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleMake;
use Mtc\MercuryDataModels\VehicleModel;
use Mtc\MercuryDataModels\VehicleReview;
use Tests\TenantTestCase;

class VehicleContentControllerTest extends TenantTestCase
{

    public function testVideosEndpointReturnsExpectedStructure(): void
    {
        $make = VehicleMake::factory()->create(['name' => 'Toyota', 'slug' => 'toyota']);
        $model = VehicleModel::factory()->create([
            'name' => 'Corolla',
            'slug' => 'corolla',
            'make_id' => $make->id,
        ]);

        Vehicle::factory()->create([
            'is_published' => true,
            'main_video_url' => 'https://example.com/video.mp4',
            'make_id' => $make->id,
            'model_id' => $model->id,
        ]);

        $response = $this->getJson(route('vehicle-content.videos'));

        $response->assertStatus(200);
        $response->assertJsonStructure([
            'data' => [
                '*' => ['slug', 'title', 'thumbnail', 'video_url']
            ],
            'pagination' => [
                'current_page',
                'last_page',
                'per_page',
                'total',
                'first_page_url',
                'last_page_url',
                'next_page_url',
                'prev_page_url',
            ],
        ]);
        $this->assertStringStartsWith('/vehicles/', $response->json('data.0.slug'));
        $this->assertEquals(15, $response->json('pagination.per_page'));
    }

    public function testVideosEndpointFiltersByMakeAndModel(): void
    {
        $make1 = VehicleMake::factory()->create(['name' => 'Toyota', 'slug' => 'toyota']);
        $make2 = VehicleMake::factory()->create(['name' => 'Honda', 'slug' => 'honda']);
        $model1 = VehicleModel::factory()->create([
            'name' => 'Corolla',
            'slug' => 'corolla',
            'make_id' => $make1->id,
        ]);

        Vehicle::factory()->create([
            'is_published' => true,
            'main_video_url' => 'https://example.com/toyota.mp4',
            'make_id' => $make1->id,
            'model_id' => $model1->id,
        ]);

        Vehicle::factory()->create([
            'is_published' => true,
            'main_video_url' => 'https://example.com/honda.mp4',
            'make_id' => $make2->id,
        ]);

        $response = $this->getJson(route('vehicle-content.videos', [
            'make' => 'toyota',
            'model' => 'corolla',
        ]));

        $response->assertStatus(200);
        $this->assertCount(1, $response->json('data'));
    }

    public function testVideosEndpointExcludesVehiclesWithoutVideo(): void
    {
        $make = VehicleMake::factory()->create(['name' => 'Toyota', 'slug' => 'toyota']);

        Vehicle::factory()->create([
            'is_published' => true,
            'main_video_url' => 'https://example.com/video.mp4',
            'make_id' => $make->id,
        ]);

        Vehicle::factory()->create([
            'is_published' => true,
            'main_video_url' => null,
            'make_id' => $make->id,
        ]);

        Vehicle::factory()->create([
            'is_published' => true,
            'main_video_url' => '',
            'make_id' => $make->id,
        ]);

        $response = $this->getJson(route('vehicle-content.videos'));

        $response->assertStatus(200);
        $this->assertCount(1, $response->json('data'));
    }

    public function testVideosEndpointGroupsByMakeModel(): void
    {
        $make = VehicleMake::factory()->create(['name' => 'Toyota', 'slug' => 'toyota']);
        $model = VehicleModel::factory()->create([
            'name' => 'Corolla',
            'slug' => 'corolla',
            'make_id' => $make->id,
        ]);

        Vehicle::factory(3)->create([
            'is_published' => true,
            'main_video_url' => 'https://example.com/video.mp4',
            'make_id' => $make->id,
            'model_id' => $model->id,
        ]);

        $response = $this->getJson(route('vehicle-content.videos'));

        $response->assertStatus(200);
        $this->assertCount(1, $response->json('data'));
    }

    public function testVideosEndpointReturnsEmptyForNoResults(): void
    {
        $response = $this->getJson(route('vehicle-content.videos'));

        $response->assertStatus(200);
        $this->assertEmpty($response->json('data'));
    }

    public function testReviewsEndpointRequiresProvider(): void
    {
        $response = $this->getJson(route('vehicle-content.reviews'));

        $response->assertStatus(422);
        $response->assertJsonValidationErrors(['provider']);
    }

    public function testReviewsEndpointReturnsExpectedStructure(): void
    {
        $make = VehicleMake::factory()->create(['name' => 'Toyota', 'slug' => 'toyota']);
        $model = VehicleModel::factory()->create([
            'name' => 'Corolla',
            'slug' => 'corolla',
            'make_id' => $make->id,
        ]);

        $vehicle = Vehicle::factory()->create([
            'is_published' => true,
            'make_id' => $make->id,
            'model_id' => $model->id,
        ]);

        $review = VehicleReview::factory()->create([
            'provider' => 'car-and-driving',
            'review' => [
                ['type' => 'Ten Second Review', 'headline' => 'Test', 'text' => 'Review text'],
            ],
        ]);

        $vehicle->reviews()->attach($review->id);

        $response = $this->getJson(route('vehicle-content.reviews', ['provider' => 'car-and-driving']));

        $response->assertStatus(200);
        $response->assertJsonStructure([
            'data' => [
                '*' => ['slug', 'title', 'thumbnail', 'review']
            ],
            'pagination' => [
                'current_page',
                'last_page',
                'per_page',
                'total',
                'first_page_url',
                'last_page_url',
                'next_page_url',
                'prev_page_url',
            ],
        ]);
        $this->assertStringStartsWith('/vehicles/', $response->json('data.0.slug'));
    }

    public function testReviewsEndpointFiltersByProvider(): void
    {
        $make = VehicleMake::factory()->create(['name' => 'Toyota', 'slug' => 'toyota']);

        $vehicle = Vehicle::factory()->create([
            'is_published' => true,
            'make_id' => $make->id,
        ]);

        $cadReview = VehicleReview::factory()->create([
            'provider' => 'car-and-driving',
            'review' => [['type' => 'Summary', 'text' => 'CAD review']],
        ]);

        $otherReview = VehicleReview::factory()->create([
            'provider' => 'other-provider',
            'review' => [['type' => 'Summary', 'text' => 'Other review']],
        ]);

        $vehicle->reviews()->attach([$cadReview->id, $otherReview->id]);

        $response = $this->getJson(route('vehicle-content.reviews', ['provider' => 'car-and-driving']));

        $response->assertStatus(200);
        $this->assertCount(1, $response->json('data'));
    }

    public function testReviewsEndpointFiltersByMakeAndModel(): void
    {
        $make1 = VehicleMake::factory()->create(['name' => 'Toyota', 'slug' => 'toyota']);
        $make2 = VehicleMake::factory()->create(['name' => 'Honda', 'slug' => 'honda']);
        $model1 = VehicleModel::factory()->create([
            'name' => 'Corolla',
            'slug' => 'corolla',
            'make_id' => $make1->id,
        ]);

        $vehicle1 = Vehicle::factory()->create([
            'is_published' => true,
            'make_id' => $make1->id,
            'model_id' => $model1->id,
        ]);

        $vehicle2 = Vehicle::factory()->create([
            'is_published' => true,
            'make_id' => $make2->id,
        ]);

        $review1 = VehicleReview::factory()->create([
            'provider' => 'car-and-driving',
            'review' => [['type' => 'Summary', 'text' => 'Toyota review']],
        ]);

        $review2 = VehicleReview::factory()->create([
            'provider' => 'car-and-driving',
            'review' => [['type' => 'Summary', 'text' => 'Honda review']],
        ]);

        $vehicle1->reviews()->attach($review1->id);
        $vehicle2->reviews()->attach($review2->id);

        $response = $this->getJson(route('vehicle-content.reviews', [
            'provider' => 'car-and-driving',
            'make' => 'toyota',
            'model' => 'corolla',
        ]));

        $response->assertStatus(200);
        $this->assertCount(1, $response->json('data'));
    }

    public function testReviewsEndpointReturnsEmptyForNoResults(): void
    {
        $response = $this->getJson(route('vehicle-content.reviews', ['provider' => 'car-and-driving']));

        $response->assertStatus(200);
        $this->assertEmpty($response->json('data'));
    }

    public function testVideosEndpointPaginatesResults(): void
    {
        for ($i = 1; $i <= 5; $i++) {
            $make = VehicleMake::factory()->create(['name' => "Make{$i}", 'slug' => "make{$i}"]);
            $model = VehicleModel::factory()->create([
                'name' => "Model{$i}",
                'slug' => "model{$i}",
                'make_id' => $make->id,
            ]);
            Vehicle::factory()->create([
                'is_published' => true,
                'main_video_url' => "https://example.com/video{$i}.mp4",
                'make_id' => $make->id,
                'model_id' => $model->id,
            ]);
        }

        $response = $this->getJson(route('vehicle-content.videos', ['per_page' => 2, 'page' => 1]));

        $response->assertStatus(200);
        $this->assertCount(2, $response->json('data'));
        $this->assertEquals(1, $response->json('pagination.current_page'));
        $this->assertEquals(3, $response->json('pagination.last_page'));
        $this->assertEquals(2, $response->json('pagination.per_page'));
        $this->assertEquals(5, $response->json('pagination.total'));

        $response2 = $this->getJson(route('vehicle-content.videos', ['per_page' => 2, 'page' => 2]));

        $response2->assertStatus(200);
        $this->assertCount(2, $response2->json('data'));
        $this->assertEquals(2, $response2->json('pagination.current_page'));

        $response3 = $this->getJson(route('vehicle-content.videos', ['per_page' => 2, 'page' => 3]));

        $response3->assertStatus(200);
        $this->assertCount(1, $response3->json('data'));
        $this->assertEquals(3, $response3->json('pagination.current_page'));
    }

    public function testPaginationValidatesPerPageMax(): void
    {
        $response = $this->getJson(route('vehicle-content.videos', ['per_page' => 150]));

        $response->assertStatus(422);
        $response->assertJsonValidationErrors(['per_page']);
    }
}
