<?php

declare(strict_types=1);

namespace Tests\Feature;

use App\Models\Company;
use App\Models\Partner;
use App\Models\User;
use App\Services\PartnerInvestmentService;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;

/**
 * Regresión #129 (Ronda 3, item 4): PartnerInvestmentService::distributeProfits()
 * sumaba Expense por `affects_profit=true` sin el scope canónico `effective()`
 * (approved OR !requires_approval), así que un egreso PENDIENTE de aprobación
 * ya reducía la utilidad distribuible antes de que el admin lo aprobara —
 * contradice la regla de caja de CLAUDE.md (getCashBase/getCashPosition usan
 * `effective()`). El método está dormido hoy (ninguna acción Filament lo cablea),
 * pero se corrige antes de exponer una UI de distribución.
 */
class DistributeProfitsEffectiveExpensesTest extends TestCase
{
    use DatabaseTransactions;

    private Company $company;

    private PartnerInvestmentService $service;

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

        $this->company = Company::factory()->create();
        $admin = User::factory()->create(['company_id' => $this->company->id]);
        $this->actingAs($admin); // distributeProfits() usa auth()->id() para user_id (NOT NULL)

        Partner::create([
            'company_id' => $this->company->id,
            'name' => 'Socio Único',
            'status' => 'active',
            'user_id' => $admin->id,
            'joined_at' => now()->subYear(),
            'ownership_model' => 'fixed',
            'fixed_ownership_percentage' => '100.0000',
        ]);

        DB::table('incomes')->insert([
            'company_id' => $this->company->id,
            'user_id' => $admin->id,
            'amount' => '1000000.00',
            'category' => 'service_fee',
            'operation_date' => now()->toDateString(),
            'affects_capital' => false,
            'affects_profit' => true,
            'is_locked' => false,
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        // Egreso APROBADO: sí debe descontar utilidad.
        $this->insertExpense($admin->id, '200000.00', requiresApproval: false, approvalStatus: 'approved');

        // Egreso PENDIENTE: NO debe descontar utilidad hasta que se apruebe (el bug).
        $this->insertExpense($admin->id, '300000.00', requiresApproval: true, approvalStatus: 'pending');

        $this->service = app(PartnerInvestmentService::class);
    }

    private function insertExpense(int $userId, string $amount, bool $requiresApproval, string $approvalStatus): void
    {
        DB::table('expenses')->insert([
            'company_id' => $this->company->id,
            'user_id' => $userId,
            'amount' => $amount,
            'category' => 'transportation',
            'expense_type' => 'operational',
            'affects_cash' => true,
            'affects_profit' => true,
            'reduces_capital' => false,
            'is_locked' => false,
            'requires_approval' => $requiresApproval,
            'approval_status' => $approvalStatus,
            'operation_date' => now()->toDateString(),
            'created_at' => now(),
            'updated_at' => now(),
        ]);
    }

    #[Test]
    public function pending_expense_does_not_reduce_distributable_profit(): void
    {
        $distribution = $this->service->distributeProfits(
            $this->company->id,
            now()->subMonth(),
            now(),
        );

        // Ingresos 1.000.000 - solo el egreso APROBADO (200.000) = 800.000.
        // Si el pendiente (300.000) contara, quedaría en 500.000.
        $this->assertSame('800000.00', $distribution->net_profit);
    }
}
