<?php

namespace Tests\Feature\Controllers;

use App\Models\ContentSync;
use Mtc\MercuryDataModels\Dealership;
use Tests\DatabaseTestCase;
use Tests\UserForTenant;

class SiteExportControllerTest extends DatabaseTestCase
{
    use UserForTenant;

    public function testTablesRequiresValidToken()
    {
        $response = $this->postJson(
            route('tenant.site-export.tables', ['tenant' => tenant('id')], false)
        );

        $response->assertStatus(403);
    }

    public function testTablesListsOnlySelectedModules()
    {
        $response = $this->postJson(
            route('tenant.site-export.tables', ['tenant' => tenant('id')], false),
            ['modules' => ['dealerships']],
            $this->authHeaders()
        );

        $response->assertStatus(200);

        $names = collect($response->json('tables'))->pluck('name');
        $this->assertTrue($names->contains('dealerships'));
        $this->assertTrue($names->contains('franchises'));
        $this->assertFalse($names->contains('pages'));
        $this->assertFalse($names->contains('vehicles'));
    }

    public function testMediaIsItsOwnModule()
    {
        $response = $this->postJson(
            route('tenant.site-export.tables', ['tenant' => tenant('id')], false),
            ['modules' => ['content']],
            $this->authHeaders()
        );

        $response->assertStatus(200);
        $this->assertFalse(collect($response->json('tables'))->pluck('name')->contains('media'));

        $response = $this->postJson(
            route('tenant.site-export.tables', ['tenant' => tenant('id')], false),
            ['modules' => ['media']],
            $this->authHeaders()
        );

        $response->assertStatus(200);

        $names = collect($response->json('tables'))->pluck('name');
        $this->assertTrue($names->contains('media'));
        $this->assertTrue($names->contains('media_uses'));
        $this->assertFalse($names->contains('pages'));
    }

    public function testTablesRejectsUnknownModule()
    {
        $response = $this->postJson(
            route('tenant.site-export.tables', ['tenant' => tenant('id')], false),
            ['modules' => ['not-a-module']],
            $this->authHeaders()
        );

        $response->assertStatus(422);
    }

    public function testPiiTablesAreSkippedWhenRedactedViewIsMissing()
    {
        // The test schema has no *_redacted views (they are MariaDB-only), so
        // PII tables must fail closed and drop out of the export list.
        $response = $this->postJson(
            route('tenant.site-export.tables', ['tenant' => tenant('id')], false),
            ['modules' => ['customers']],
            $this->authHeaders()
        );

        $response->assertStatus(200);

        $names = collect($response->json('tables'))->pluck('name');
        $this->assertTrue($names->contains('enquiry_statuses'));
        $this->assertFalse($names->contains('customers'));
        $this->assertFalse($names->contains('enquiries'));
        $this->assertFalse($names->contains('invoices'));
    }

    public function testDataRejectsTableOutsideAllowlist()
    {
        $response = $this->postJson(
            route('tenant.site-export.data', ['tenant' => tenant('id'), 'table' => 'users'], false),
            [],
            $this->authHeaders()
        );

        $response->assertStatus(403);
    }

    public function testDataRejectsPiiTableWithoutRedactedView()
    {
        $response = $this->postJson(
            route('tenant.site-export.data', ['tenant' => tenant('id'), 'table' => 'customers'], false),
            [],
            $this->authHeaders()
        );

        $response->assertStatus(403);
    }

    public function testDataReturnsRowsForAllowedTable()
    {
        Dealership::factory(3)->create();

        $response = $this->postJson(
            route('tenant.site-export.data', ['tenant' => tenant('id'), 'table' => 'dealerships'], false),
            [],
            $this->authHeaders()
        );

        $response->assertStatus(200);
        $this->assertEquals('dealerships', $response->json('table'));
        $this->assertCount(3, $response->json('data'));
        $this->assertEquals(3, $response->json('pagination.total'));
    }

    private function authHeaders(): array
    {
        $sync = ContentSync::factory()->create([
            'user_id' => $this->getUser()->id,
        ]);

        return [
            'x-token' => $sync->token,
            'x-user' => $this->getUser()->email,
        ];
    }
}
