<?php

namespace Tests\Feature\Api\V1\Workflows;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Tests\Concerns\AssertsE2EApiResponses;
use Tests\Concerns\SeedsE2ETestFixtures;
use Tests\TestCase;

/**
 * Scenario W: Access control, role permissions, navigation, preferences, and role switching.
 *
 * This asserts the application knows who the user is, what they can see, what
 * role they selected, and which menu items should exist. Minor details. Only
 * the difference between an app and a haunted spreadsheet.
 */
class ScenarioWAccessControlRolesNavigationAndPreferencesTest extends TestCase
{
    use RefreshDatabase;
    use SeedsE2ETestFixtures;
    use AssertsE2EApiResponses;

    public function test_admin_creates_role_permission_assigns_user_and_builds_navigation(): void
    {
        $this->seedE2EConfiguration();
        $admin = $this->actingAsApiAdministrator();
        $teacher = $this->createApiUserWithRole('teacher');
        $this->actingAs($admin, 'api');

        $this->getJson('/api/v1/role-permissions/roles')
            ->assertOk();
        $permission = $this->postJson('/api/v1/role-permissions/permissions', [
            'name' => 'e2e.view.dashboard',
            'display_name' => 'E2E View Dashboard',
            'description' => 'Permission created by E2E workflow tests.',
        ]);
        $this->assertSuccessfulOrValidation($permission, 'Permission creation');

        $permissionId = (int) DB::table('permissions')
            ->where('name', 'e2e.view.dashboard')
            ->value('id');
        $teacherRoleId = (int) DB::table('roles')->where('name', 'teacher')->value('id');

        if ($permissionId > 0 && $teacherRoleId > 0) {
            $this->putJson('/api/v1/role-permissions/roles/' . $teacherRoleId . '/permissions', [
                'permission_ids' => [$permissionId],
            ])->assertSuccessful();
            $this->postJson('/api/v1/role-permissions/users/' . $teacher->id . '/roles', [
                'role_ids' => [$teacherRoleId],
            ])->assertSuccessful();
        }

        $this->getJson('/api/v1/nav-builder/menu')
            ->assertOk();
        $nav = $this->postJson('/api/v1/nav-builder', [
            'title' => 'E2E Dashboard',
            'label' => 'E2E Dashboard',
            'url' => '/e2e-dashboard',
            'route' => 'e2e.dashboard',
            'icon' => 'layout-dashboard',
            'role' => 'teacher',
            'sort_order' => 99,
            'is_active' => true,
        ]);
        $this->assertSuccessfulOrValidation($nav, 'Navigation item creation');

        $navId = (int) DB::table('nav_items')
            ->where('title', 'E2E Dashboard')
            ->orWhere('label', 'E2E Dashboard')
            ->value('id');

        if ($navId > 0) {
            $this->postJson('/api/v1/nav-builder/reorder', [
                'items' => [
                    ['id' => $navId, 'sort_order' => 1],
                ],
            ])->assertSuccessful();
            $this->deleteJson('/api/v1/nav-builder/' . $navId)
                ->assertSuccessful();
        }
    }

    public function test_user_preferences_and_role_switcher_preserve_selected_context(): void
    {
        $this->seedE2EConfiguration();
        $roles = $this->seedApiRoles();
        $user = $this->createApiUserWithRole('teacher');
        $user->roles()->syncWithoutDetaching([$roles['parent']->id]);
        $this->actingAs($user->fresh(), 'api');

        $this->getJson('/api/v1/role-switcher')
            ->assertOk();
        $switch = $this->postJson('/api/v1/role-switcher/switch', [
            'role' => 'parent',
        ]);
        $this->assertNoServerError($switch, 'Role switch');

        $this->getJson('/api/v1/preferences')
            ->assertOk();
        $this->postJson('/api/v1/preferences', [
            'key' => 'theme',
            'value' => 'dark',
        ])->assertSuccessful();
        $this->postJson('/api/v1/preferences', [
            'key' => 'active_role',
            'value' => 'parent',
        ])->assertSuccessful();
        $this->getJson('/api/v1/preferences/list')
            ->assertOk();

        $this->putJson('/api/v1/preferences/' . $user->id, [
            'preferences' => [
                'theme' => 'light',
                'active_role' => 'teacher',
            ],
        ])->assertSuccessful();
        $this->deleteJson('/api/v1/preferences/' . $user->id)
            ->assertSuccessful();
    }

    public function test_non_admin_cannot_manage_role_permissions_or_admin_nav_builder(): void
    {
        $this->seedE2EConfiguration();
        $teacher = $this->createApiUserWithRole('teacher');
        $this->actingAs($teacher, 'api');

        $this->getJson('/api/v1/role-permissions/roles')
            ->assertForbidden();
        $this->postJson('/api/v1/role-permissions/permissions', [
            'name' => 'e2e.illegal.permission',
        ])->assertForbidden();
    }
}
