<?php

namespace Tests\Feature\Security\Authorization;

use App\Models\Admin;
use App\Models\Bank;
use App\Models\Organization;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
use Tests\TestCase;

/**
 * Posts Management Authorization Tests
 *
 * Tests that only admins and central banks can access post management,
 * and prevents IDOR/cross-guard attacks.
 *
 * @group security
 * @group authorization
 * @group admin
 * @group critical
 */
class PostsManageAuthorizationTest extends TestCase
{
    use RefreshDatabase;

    /**
     * Test admin can access posts management
     *
     * @test
     */
    public function admin_can_access_posts_management()
    {
        $admin = Admin::factory()->create();

        $this->actingAs($admin, 'admin');
        session(['activeProfileType' => Admin::class, 'activeProfileId' => $admin->id]);

        $response = Livewire::test(\App\Http\Livewire\Posts\Manage::class);

        $response->assertStatus(200);
    }

    /**
     * Test central bank (level 0) can access posts management
     *
     * @test
     */
    public function central_bank_can_access_posts_management()
    {
        $bank = Bank::factory()->create(['level' => 0]);

        $this->actingAs($bank, 'bank');
        session(['activeProfileType' => Bank::class, 'activeProfileId' => $bank->id]);

        $response = Livewire::test(\App\Http\Livewire\Posts\Manage::class);

        $response->assertStatus(200);
    }

    /**
     * Test regular bank (level 1) CANNOT access posts management
     *
     * @test
     */
    public function regular_bank_cannot_access_posts_management()
    {
        $bank = Bank::factory()->create(['level' => 1]);

        $this->actingAs($bank, 'bank');
        session(['activeProfileType' => Bank::class, 'activeProfileId' => $bank->id]);

        $response = Livewire::test(\App\Http\Livewire\Posts\Manage::class);

        $response->assertStatus(403);
    }

    /**
     * Test user CANNOT access posts management
     *
     * @test
     */
    public function user_cannot_access_posts_management()
    {
        $user = User::factory()->create();

        $this->actingAs($user, 'web');
        session(['activeProfileType' => User::class, 'activeProfileId' => $user->id]);

        $response = Livewire::test(\App\Http\Livewire\Posts\Manage::class);

        $response->assertStatus(403);
    }

    /**
     * Test organization CANNOT access posts management
     *
     * @test
     */
    public function organization_cannot_access_posts_management()
    {
        $user = User::factory()->create();
        $organization = Organization::factory()->create();
        $organization->users()->attach($user->id);

        $this->actingAs($user, 'web');
        $this->actingAs($organization, 'organization');
        session(['activeProfileType' => Organization::class, 'activeProfileId' => $organization->id]);

        $response = Livewire::test(\App\Http\Livewire\Posts\Manage::class);

        $response->assertStatus(403);
    }

    /**
     * Test web user CANNOT access posts via cross-guard attack (targeting admin profile)
     *
     * @test
     */
    public function web_user_cannot_access_posts_via_cross_guard_admin_attack()
    {
        $user = User::factory()->create();
        $admin = Admin::factory()->create();
        $admin->users()->attach($user->id); // User is linked to admin

        // User authenticated on 'web' guard
        $this->actingAs($user, 'web');

        // Malicious: manipulate session to target admin profile
        session(['activeProfileType' => Admin::class, 'activeProfileId' => $admin->id]);

        $response = Livewire::test(\App\Http\Livewire\Posts\Manage::class);

        // Should be blocked by ProfileAuthorizationHelper (cross-guard validation)
        $response->assertStatus(403);
    }

    /**
     * Test web user CANNOT access posts via cross-guard attack (targeting bank profile)
     *
     * @test
     */
    public function web_user_cannot_access_posts_via_cross_guard_bank_attack()
    {
        $user = User::factory()->create();
        $bank = Bank::factory()->create(['level' => 0]);
        $bank->managers()->attach($user->id); // User is manager of bank

        // User authenticated on 'web' guard
        $this->actingAs($user, 'web');

        // Malicious: manipulate session to target bank profile
        session(['activeProfileType' => Bank::class, 'activeProfileId' => $bank->id]);

        $response = Livewire::test(\App\Http\Livewire\Posts\Manage::class);

        // Should be blocked by ProfileAuthorizationHelper (cross-guard validation)
        $response->assertStatus(403);
    }

    /**
     * Test unauthenticated user CANNOT access posts management
     *
     * @test
     */
    public function unauthenticated_user_cannot_access_posts_management()
    {
        $admin = Admin::factory()->create();

        // Not authenticated
        session(['activeProfileType' => Admin::class, 'activeProfileId' => $admin->id]);

        $response = Livewire::test(\App\Http\Livewire\Posts\Manage::class);

        // Should return 401 (not authenticated)
        $response->assertStatus(401);
    }

    /**
     * Test admin CANNOT access posts when session has no active profile
     *
     * @test
     */
    public function admin_cannot_access_posts_without_active_profile()
    {
        $admin = Admin::factory()->create();

        $this->actingAs($admin, 'admin');
        // NO session activeProfileType/activeProfileId set

        $response = Livewire::test(\App\Http\Livewire\Posts\Manage::class);

        $response->assertStatus(403);
    }

    /**
     * Test admin CANNOT access posts when session has invalid profile ID
     *
     * @test
     */
    public function admin_cannot_access_posts_with_invalid_profile_id()
    {
        $admin = Admin::factory()->create();

        $this->actingAs($admin, 'admin');
        session(['activeProfileType' => Admin::class, 'activeProfileId' => 99999]); // Non-existent ID

        $response = Livewire::test(\App\Http\Livewire\Posts\Manage::class);

        $response->assertStatus(403);
    }

    /**
     * Test admin CANNOT access posts management for different admin profile (IDOR)
     *
     * @test
     */
    public function admin_cannot_access_posts_as_different_admin()
    {
        $admin1 = Admin::factory()->create();
        $admin2 = Admin::factory()->create();

        // Authenticated as admin1
        $this->actingAs($admin1, 'admin');

        // Malicious: manipulate session to target admin2 profile
        session(['activeProfileType' => Admin::class, 'activeProfileId' => $admin2->id]);

        $response = Livewire::test(\App\Http\Livewire\Posts\Manage::class);

        // Should be blocked by ProfileAuthorizationHelper (different admin)
        $response->assertStatus(403);
    }
}
