<?php

namespace Tests\Tenant;

use Illuminate\Http\UploadedFile;
use Mtc\MercuryDataModels\SeoData;
use Mtc\MercuryDataModels\SeoRedirect;
use Tests\TenantTestCase;
use Tests\UserForTenant;

class SeoDataTest extends TenantTestCase
{
    use UserForTenant;

    public function testIndexPage()
    {
        SeoData::factory(4)->create();
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.seo_settings.data.index'));

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

    public function testStorePage()
    {
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.seo_settings.data.store'), [
            'path' => '/foo',
            'title' => 'baz bar',
            'description' => 'Lorem ipsum',
        ]);

        $response->assertStatus(201);
        $seo = SeoData::query()->where('path', '/foo')->first();
        $this->assertEquals('baz bar', $seo->title);
        $this->assertEquals('Lorem ipsum', $seo->description);
    }

    public function testUpdatePage()
    {
        $seo = SeoData::factory()->create();
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->putJson(route('tenant.seo_settings.data.update', $seo->id), [
            'path' => '/foo',
            'title' => 'baz bar',
            'description' => 'Lorem ipsum',
        ]);

        $response->assertStatus(200);
        $seo->refresh();
        $this->assertEquals('baz bar', $seo->title);
        $this->assertEquals('Lorem ipsum', $seo->description);
    }

    public function testDeletePage()
    {
        $seo = SeoData::factory()->create();
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->deleteJson(route('tenant.seo_settings.data.destroy', $seo->id));

        $response->assertStatus(200);
        $exists = SeoData::query()
            ->where('id', $seo->id)
            ->where(fn($query) => $query->whereNotNull('title')->orWhereNotNull('description'))
            ->exists();
        $this->assertFalse($exists);
    }

    public function testExport()
    {
        SeoData::factory(10)->create();
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.seo_settings.data.export'));

        $response->assertStatus(200);
        $response->assertDownload('seo_data.xlsx');
    }

    public function testImport()
    {
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.seo_settings.data.import'), [
                'truncate' => true,
                'file' => UploadedFile::fake()->createWithContent(
                    'seo_data_import.csv',
                    file_get_contents(dirname(__DIR__) . '/data/seo_data_import.csv')
                ),
            ]);

        $response->assertStatus(200);
        $this->assertEquals(2, SeoData::query()->count());
    }

    public function testRedirectImport()
    {
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.seo_settings.redirects.import'), [
                'truncate' => true,
                'file' => UploadedFile::fake()->createWithContent(
                    'seo_redirects.csv',
                    file_get_contents(dirname(__DIR__) . '/data/seo_redirect_import.csv')
                ),
            ]);

        $response->assertStatus(200);
        $this->assertEquals(3, SeoRedirect::query()->count());
    }

    public function testJsonSchemaInvalid()
    {
        $seo = SeoData::factory()->create([
            'json_schema' => '{"abc":"123"}',
        ]);
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->putJson(route('tenant.seo_settings.data.update', $seo->id), [
                'path' => '/foo',
                'title' => 'baz bar',
                'description' => 'Lorem ipsum',
                'jsonSchema' => 'xyz',
            ]);

        $response->assertStatus(422);
        $seo->refresh();
        $this->assertEquals('{"abc":"123"}', $seo->json_schema);
    }

    public function testJsonSchema()
    {
        $seo = SeoData::factory()->create([
            'json_schema' => '{"abc":"123"}',
        ]);
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->putJson(route('tenant.seo_settings.data.update', $seo->id), [
                'path' => '/foo',
                'title' => 'baz bar',
                'description' => 'Lorem ipsum',
                'jsonSchema' => '{"xyz":"456"}',
            ]);

        $response->assertStatus(200);
        $seo->refresh();
        $this->assertEquals('{"xyz":"456"}', $seo->json_schema);
    }

    public function testJsonSchemaNull()
    {
        $seo = SeoData::factory()->create();
        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->putJson(route('tenant.seo_settings.data.update', $seo->id), [
                'path' => '/foo',
                'title' => 'baz bar',
                'description' => 'Lorem ipsum',
                'jsonSchema' => null,
            ]);

        $response->assertStatus(200);
    }
}
