<?php

declare(strict_types=1);

namespace Tests\Feature;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Maestro\Core\Database\Seeders\UserSeeder;
use Maestro\Core\Models\MaestroAppSetting;
use Maestro\Core\Support\PermissionGuardName;
use Spatie\Permission\Models\Role;
use Spatie\Permission\PermissionRegistrar;
use Tests\Fixtures\AuthTestUser;
use Tests\TestCase;

final class PublicPageSuperadminApiTest extends TestCase
{
    use RefreshDatabase;

    public function test_public_page_health_is_forbidden_without_superadmin_permission(): void
    {
        $this->seed([UserSeeder::class]);

        $user = AuthTestUser::query()->where('email', 'demo@example.com')->first();
        self::assertNotNull($user);

        $guardName = PermissionGuardName::forApp();
        $role = Role::findByName('admin', $guardName);
        self::assertNotNull($role);
        $role->revokePermissionTo('platform.superadmin');
        app()[PermissionRegistrar::class]->forgetCachedPermissions();

        $response = $this->actingAs($user, 'web')->getJson('/api/superadmin/public-page-health');

        $response->assertForbidden();
    }

    public function test_superadmin_can_store_public_page_settings(): void
    {
        $this->withoutMiddleware(VerifyCsrfToken::class);
        $this->seed([UserSeeder::class]);

        $user = AuthTestUser::query()->where('email', 'demo@example.com')->first();
        self::assertNotNull($user);

        $response = $this->actingAs($user, 'web')->patchJson('/api/superadmin/app-settings', [
            'publicPage' => [
                'enabled' => true,
                'mode' => 'customer_override',
                'rootMode' => 'public',
            ],
        ]);

        $response->assertOk();
        $response->assertJsonPath('publicPage.enabled', true);
        $response->assertJsonPath('publicPage.mode', 'customer_override');
        $response->assertJsonPath('publicPage.rootMode', 'public');

        $row = MaestroAppSetting::instance()->fresh();
        self::assertNotNull($row);
        self::assertIsArray($row->public_page);
        self::assertTrue((bool) ($row->public_page['enabled'] ?? false));
        self::assertSame('customer_override', (string) ($row->public_page['mode'] ?? ''));
        self::assertSame('public', (string) ($row->public_page['root_mode'] ?? ''));
    }

    public function test_public_page_toggle_off_forces_root_mode_login(): void
    {
        $this->withoutMiddleware(VerifyCsrfToken::class);
        $this->seed([UserSeeder::class]);

        $user = AuthTestUser::query()->where('email', 'demo@example.com')->first();
        self::assertNotNull($user);

        $response = $this->actingAs($user, 'web')->patchJson('/api/superadmin/app-settings', [
            'publicPage' => [
                'enabled' => false,
                'mode' => 'core_default',
                'rootMode' => 'dashboard',
            ],
        ]);

        $response->assertOk();
        $response->assertJsonPath('publicPage.enabled', false);
        $response->assertJsonPath('publicPage.rootMode', 'login');

        $row = MaestroAppSetting::instance()->fresh();
        self::assertNotNull($row);
        self::assertIsArray($row->public_page);
        self::assertFalse((bool) ($row->public_page['enabled'] ?? true));
        self::assertSame('login', (string) ($row->public_page['root_mode'] ?? ''));
    }

    public function test_public_page_health_returns_structured_checks(): void
    {
        $this->seed([UserSeeder::class]);

        $user = AuthTestUser::query()->where('email', 'demo@example.com')->first();
        self::assertNotNull($user);

        $response = $this->actingAs($user, 'web')->getJson('/api/superadmin/public-page-health');

        $response->assertOk();
        $response->assertJsonStructure([
            'data' => [
                'route',
                'status',
                'status_detail',
                'checks' => [
                    '*' => ['id', 'label', 'status', 'detail', 'commands'],
                ],
            ],
        ]);

        $status = $response->json('data.status');
        self::assertContains($status, ['ok', 'warn', 'fail']);
    }
}
