<?php

namespace Tests\Feature\Controllers;

use App\Jobs\SyncContentToTemplate;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\Queue;
use Mtc\MercuryDataModels\Page;
use Mtc\MercuryDataModels\Template;
use Mtc\MercuryDataModels\VehicleOffer;
use Tests\DatabaseTestCase;
use Tests\UserForTenant;

class TemplateControllerTest extends DatabaseTestCase
{
    use UserForTenant;


    public function testIndex()
    {
        Template::query()->delete();
        Template::factory(5)->create();
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->withoutExceptionHandling()
            ->getJson(route('content.templates.index'));

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

    public function testShow()
    {
        $template = Template::factory()->create();
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('content.templates.show', $template));

        $response->assertStatus(200);
        $this->assertArrayHasKey('template', $response->json());
        $this->assertArrayHasKey('global_content', $response->json());
        $this->assertArrayHasKey('elements', $response->json());
        $this->assertArrayHasKey('comments', $response->json());
    }

    public function testUsage()
    {
        $template = Template::factory()->create();
        $pages = Page::factory(3)->create(['template_id' => $template->id]);
        Page::factory(3)->create(['template_id' => null]);
        $offers = VehicleOffer::factory(4)->create(['template_id' => $template->id]);

        $response = $this->actingAs($this->getUser(false))
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.templates.usage', $template));

        $response->assertStatus(200);
        $this->assertCount(7, $response->json());
        $pages->each(fn ($page) => $this->assertTrue(collect($response->json())->where('type', 'page')->where('id', $page->id)->isNotEmpty()));
        $offers->each(fn ($offer) => $this->assertTrue(collect($response->json())->where('type', 'offer')->where('id', $offer->id)->isNotEmpty()));
    }

    public function testSync()
    {
        Queue::fake();
        $template = Template::factory()->create();
        $page = Page::factory()->create(['template_id' => $template->id]);
        Page::factory(3)->create(['template_id' => null]);
        $offer = VehicleOffer::factory()->create(['template_id' => $template->id]);

        $response = $this->actingAs($this->getUser(false))
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.templates.sync-usage', $template));
        $response->assertStatus(200);
        Queue::assertPushed(SyncContentToTemplate::class);

    }

    public function testSyncProcess()
    {
        $template = Template::factory()->create();
        $page = Page::factory()->create(['template_id' => $template->id]);
        Page::factory(3)->create(['template_id' => null]);
        $offer = VehicleOffer::factory()->create(['template_id' => $template->id]);

        Bus::fake();
        $response = $this->actingAs($this->getUser(false))
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.templates.sync-usage', $template));
        $response->assertStatus(200);
        Bus::assertDispatched(SyncContentToTemplate::class);
        Bus::assertDispatchedTimes(SyncContentToTemplate::class, 2);
    }

}
