<?php

namespace Tests\Feature;

use App\Models\Customer;
use App\Models\CustomerDocument;
use App\Models\Permission;
use App\Models\User;
use App\Models\UserPermissionOverride;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;

class TenantRBACAndMultiTenancyTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();
        $this->seed();
    }

    public function test_platform_super_admin_can_access_platform_dashboard(): void
    {
        $admin = User::where('email', 'admin@platform.com')->first();
        $response = $this->actingAs($admin)->get('/platform/dashboard');
        $response->assertStatus(200);
    }

    public function test_tenant_owner_redirects_to_app_dashboard(): void
    {
        $owner = User::where('email', 'owner@almadina.ae')->first();
        $this->assertEquals(route('app.dashboard'), $owner->getDashboardUrl());

        $response = $this->actingAs($owner)->get('/app/dashboard');
        $response->assertStatus(200);
    }

    public function test_receptionist_lands_on_front_desk(): void
    {
        $receptionist = User::where('email', 'reception@almadina.ae')->first();
        $this->assertEquals(route('app.front_desk'), $receptionist->getDashboardUrl());

        $response = $this->actingAs($receptionist)->get('/app/front-desk');
        $response->assertStatus(200);
    }

    public function test_typist_lands_on_work_queue(): void
    {
        $typist = User::where('email', 'typist@almadina.ae')->first();
        $this->assertEquals(route('app.work_queue'), $typist->getDashboardUrl());
        $this->assertTrue($typist->hasPermission('renewals.view'));
        $this->assertTrue($typist->hasPermission('renewals.manage'));

        $response = $this->actingAs($typist)->get('/app/work-queue');
        $response->assertStatus(200)
            ->assertSee('Typing Command Center')
            ->assertSee('Smart Queue')
            ->assertSee('Daily Output')
            ->assertSee('Workload by Stage')
            ->assertSee('My Workflow Tasks');

        $this->actingAs($typist)->get('/app/work-queue?view=returned&sort=sla')
            ->assertOk()
            ->assertViewHas('view', 'returned');

        $this->actingAs($typist)->get('/app/applications/work-queue')
            ->assertRedirect(route('app.work_queue'));

        foreach ([
            route('app.work_queue', ['view' => 'mine']),
            route('app.work_queue', ['view' => 'returned']),
            route('app.applications.create'),
            route('app.applications.index'),
            route('app.customers.documents.index'),
            route('app.renewals.index'),
            route('app.renewals.index', ['reminder_due' => 1]),
            route('app.tasks.index', ['scope' => 'mine']),
        ] as $workspaceUrl) {
            $this->actingAs($typist)->get($workspaceUrl)->assertOk();
        }

        $this->actingAs($typist)->get(route('app.tasks.index', ['scope' => 'mine']))
            ->assertSeeText('My Tasks')
            ->assertDontSeeText('Approval Inbox');
    }

    public function test_typist_can_securely_download_a_tenant_document(): void
    {
        Storage::fake('local');
        $typist = User::where('email', 'typist@almadina.ae')->firstOrFail();
        $customer = Customer::create([
            'tenant_id' => $typist->tenant_id,
            'customer_code' => 'CUS-DOWNLOAD-001',
            'first_name' => 'Document',
            'full_name_en' => 'Document Vault Customer',
            'customer_type' => 'individual',
            'status' => 'active',
        ]);
        Storage::disk('local')->put('tests/document-vault-test.pdf', 'secure customer document');
        $document = CustomerDocument::create([
            'tenant_id' => $typist->tenant_id,
            'customer_id' => $customer->id,
            'document_name' => 'Document Vault Test',
            'attachment_path' => 'tests/document-vault-test.pdf',
            'status' => 'valid',
            'version' => 1,
            'is_current' => true,
        ]);

        $this->actingAs($typist)
            ->get(route('app.customers.documents.download', $document->id))
            ->assertOk()
            ->assertDownload('document-vault-test.pdf');
    }

    public function test_user_explicit_deny_override_takes_precedence_over_role_allow(): void
    {
        $receptionist = User::where('email', 'reception@almadina.ae')->first();
        $permission = Permission::where('slug', 'customers.create')->first();

        // Normally receptionist has customers.create
        $this->assertTrue($receptionist->hasPermission('customers.create'));

        // Add explicit user DENY override
        UserPermissionOverride::create([
            'user_id' => $receptionist->id,
            'permission_id' => $permission->id,
            'is_allowed' => false,
        ]);

        // Now hasPermission should evaluate to false
        $this->assertFalse($receptionist->fresh()->hasPermission('customers.create'));
    }

    public function test_user_explicit_allow_override_grants_permission(): void
    {
        $receptionist = User::where('email', 'reception@almadina.ae')->first();
        $permission = Permission::where('slug', 'roles.delete')->first();

        // Receptionist normally cannot delete roles
        $this->assertFalse($receptionist->hasPermission('roles.delete'));

        // Add explicit user ALLOW override
        UserPermissionOverride::create([
            'user_id' => $receptionist->id,
            'permission_id' => $permission->id,
            'is_allowed' => true,
        ]);

        // Now hasPermission should evaluate to true
        $this->assertTrue($receptionist->fresh()->hasPermission('roles.delete'));
    }
}
