<?php

declare(strict_types=1);

namespace Tests\Feature\Pwa;

use App\Models\Company;
use App\Models\Plan;
use App\Models\Subscription;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Laravel\Sanctum\Sanctum;
use PHPUnit\Framework\Attributes\Test;
use Spatie\Permission\Models\Role;
use Tests\TestCase;

/**
 * Principio rector del rediseño (#43 Fase B): cada rol ve SOLO lo suyo.
 * El P&L del dueño (caja/patrimonio/utilidad/gastos) no debe filtrarse al
 * supervisor ni al cobrador; los datos de equipo no deben llegar al cobrador.
 */
class DashboardDataScopeTest extends TestCase
{
    use DatabaseTransactions;

    private Company $company;

    protected function setUp(): void
    {
        parent::setUp();

        foreach (['admin', 'supervisor', 'collector'] as $role) {
            Role::firstOrCreate(['name' => $role, 'guard_name' => 'web']);
        }

        $plan = Plan::factory()->create(['has_pwa_access' => true]);
        $this->company = Company::factory()->create(['interest_method' => 'flat_rate']);
        Subscription::factory()->active()->create([
            'company_id' => $this->company->id,
            'plan_id' => $plan->id,
            'ends_at' => now()->addYear(),
        ]);
    }

    private function actingAsRole(string $role): void
    {
        $user = User::factory()->create(['company_id' => $this->company->id]);
        $user->assignRole($role);
        Sanctum::actingAs($user->fresh());
    }

    #[Test]
    public function the_supervisor_dashboard_never_exposes_owner_pnl(): void
    {
        $this->actingAsRole('supervisor');

        $stats = $this->getJson('/api/pwa/dashboard')
            ->assertStatus(200)
            ->json('stats');

        foreach (['cash_base', 'business_total', 'interest_earned', 'operational_expenses_today', 'disbursements_today'] as $ownerOnly) {
            $this->assertArrayNotHasKey($ownerOnly, $stats, "supervisor no debe ver {$ownerOnly}");
        }
        // Sí ve su alcance de equipo:
        $this->assertArrayHasKey('active_portfolio', $stats);
        $this->assertArrayHasKey('active_collectors', $stats);
    }

    #[Test]
    public function the_collector_dashboard_is_strictly_personal(): void
    {
        $this->actingAsRole('collector');

        $stats = $this->getJson('/api/pwa/dashboard')
            ->assertStatus(200)
            ->json('stats');

        foreach (['cash_base', 'business_total', 'interest_earned', 'active_portfolio', 'active_collectors'] as $notPersonal) {
            $this->assertArrayNotHasKey($notPersonal, $stats, "cobrador no debe ver {$notPersonal}");
        }
        // Sí ve lo suyo:
        $this->assertArrayHasKey('due_today', $stats);
        $this->assertArrayHasKey('collected_today', $stats);
    }

    #[Test]
    public function the_admin_dashboard_exposes_the_owner_pnl(): void
    {
        $this->actingAsRole('admin');

        $stats = $this->getJson('/api/pwa/dashboard')
            ->assertStatus(200)
            ->json('stats');

        foreach (['cash_base', 'business_total', 'interest_earned', 'por_cobrar', 'collected_today'] as $ownerKey) {
            $this->assertArrayHasKey($ownerKey, $stats, "admin debe ver {$ownerKey}");
        }
    }
}
