<?php

declare(strict_types=1);

namespace Tests\Unit;

use App\Services\Dashboard\DashboardTrendService;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

class JointPolarityTest extends TestCase
{
    #[Test]
    public function cartera_creciendo_con_caja_cayendo_es_watch(): void
    {
        $trends = DashboardTrendService::applyJointPolarity([
            'por_cobrar' => ['trend_pct' => 3.3, 'good' => true],
            'cash_base' => ['trend_pct' => -57.5, 'good' => false],
            'delinquency_rate' => ['trend_pct' => 9.0, 'good' => false],
        ]);

        $this->assertSame('watch', $trends['por_cobrar']['state']);
        $this->assertNull($trends['por_cobrar']['good']);
    }

    #[Test]
    public function cartera_creciendo_con_mora_subiendo_tambien_es_watch(): void
    {
        $trends = DashboardTrendService::applyJointPolarity([
            'por_cobrar' => ['trend_pct' => 3.3, 'good' => true],
            'cash_base' => ['trend_pct' => 4.0, 'good' => true],
            'delinquency_rate' => ['trend_pct' => 9.0, 'good' => false],
        ]);

        $this->assertSame('watch', $trends['por_cobrar']['state']);
    }

    #[Test]
    public function cartera_creciendo_con_caja_sana_sigue_siendo_buena(): void
    {
        $trends = DashboardTrendService::applyJointPolarity([
            'por_cobrar' => ['trend_pct' => 3.3, 'good' => true],
            'cash_base' => ['trend_pct' => 5.0, 'good' => true],
            'delinquency_rate' => ['trend_pct' => -2.0, 'good' => true],
        ]);

        $this->assertSame('good', $trends['por_cobrar']['state']);
        $this->assertTrue($trends['por_cobrar']['good']);
    }

    #[Test]
    public function cartera_cayendo_no_se_marca_watch_aunque_la_caja_baje(): void
    {
        // La regla solo aplica cuando la cartera CRECE: si decrece, el riesgo
        // que describe (colocar mas rapido de lo que entra) no existe.
        $trends = DashboardTrendService::applyJointPolarity([
            'por_cobrar' => ['trend_pct' => -4.0, 'good' => false],
            'cash_base' => ['trend_pct' => -10.0, 'good' => false],
            'delinquency_rate' => ['trend_pct' => 1.0, 'good' => false],
        ]);

        $this->assertNotSame('watch', $trends['por_cobrar']['state']);
    }

    #[Test]
    public function sin_tendencia_el_estado_es_no_data_no_bad(): void
    {
        // Durante los primeros 7 dias no hay snapshot base: `good` es null, o sea
        // DESCONOCIDO. Marcarlo 'bad' seria inventar una mala noticia.
        $trends = DashboardTrendService::applyJointPolarity([
            'por_cobrar' => ['trend_pct' => null, 'good' => null],
            'cash_base' => ['trend_pct' => null, 'good' => null],
            'delinquency_rate' => ['trend_pct' => null, 'good' => null],
        ]);

        $this->assertSame('no_data', $trends['por_cobrar']['state']);
        $this->assertSame('no_data', $trends['cash_base']['state']);
        $this->assertSame('no_data', $trends['delinquency_rate']['state']);
    }

    #[Test]
    public function una_tendencia_mala_si_se_marca_bad(): void
    {
        $trends = DashboardTrendService::applyJointPolarity([
            'cash_base' => ['trend_pct' => -12.0, 'good' => false],
        ]);

        $this->assertSame('bad', $trends['cash_base']['state']);
    }
}
