<?php

declare(strict_types=1);

namespace Tests\Unit;

use App\Models\ReviewedWebsite;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\TestCase;

final class ReviewedWebsiteLegitimacyMeterTest extends TestCase
{
    public static function tierProvider(): array
    {
        return [
            'scam low' => [0, 'scam'],
            'scam high' => [29, 'scam'],
            'good low' => [30, 'good'],
            'good mid' => [45, 'good'],
            'good high' => [59, 'good'],
            'legit low' => [60, 'legit'],
            'legit high' => [100, 'legit'],
        ];
    }

    #[DataProvider('tierProvider')]
    public function test_legitimacy_meter_tier_from_manual_score(int $score, string $expectedTier): void
    {
        $site = new ReviewedWebsite([
            'manual_trust_score' => $score,
            'trust_score' => null,
        ]);

        $this->assertSame($expectedTier, $site->legitimacyMeterTier());
        $this->assertSame((float) $score, $site->legitimacyMeterPercent());
    }

    public function test_legitimacy_meter_percent_clamps(): void
    {
        $site = new ReviewedWebsite(['manual_trust_score' => 150, 'trust_score' => null]);
        $this->assertSame(100.0, $site->legitimacyMeterPercent());

        $site = new ReviewedWebsite(['manual_trust_score' => -5, 'trust_score' => null]);
        $this->assertSame(0.0, $site->legitimacyMeterPercent());
    }

    public function test_legitimacy_meter_is_null_without_scores_or_verdict(): void
    {
        $site = new ReviewedWebsite([
            'manual_trust_score' => null,
            'trust_score' => null,
            'editorial_verdict' => null,
        ]);

        $this->assertNull($site->publicAuthenticityScore());
        $this->assertNull($site->legitimacyMeterPercent());
        $this->assertNull($site->legitimacyMeterTier());
    }

    public function test_public_authenticity_score_uses_editorial_when_no_numeric_scores(): void
    {
        $site = new ReviewedWebsite([
            'manual_trust_score' => null,
            'trust_score' => null,
            'editorial_verdict' => ReviewedWebsite::VERDICT_LEGIT,
        ]);

        $this->assertSame(78, $site->publicAuthenticityScore());
        $this->assertTrue($site->authenticityRatingIsEditorialEstimate());
        $this->assertSame('editorial', $site->authenticityRatingSource());
        $this->assertSame(78.0, $site->legitimacyMeterPercent());
    }

    public function test_public_authenticity_score_manual_overrides_community(): void
    {
        $site = new ReviewedWebsite([
            'manual_trust_score' => 90,
            'trust_score' => 40,
            'editorial_verdict' => ReviewedWebsite::VERDICT_SCAM,
        ]);

        $this->assertSame(90, $site->publicAuthenticityScore());
        $this->assertFalse($site->authenticityRatingIsEditorialEstimate());
        $this->assertSame('manual', $site->authenticityRatingSource());
    }

    public function test_band_constants_sum_to_one_hundred(): void
    {
        $this->assertSame(
            100,
            ReviewedWebsite::LEGITIMACY_METER_SCAM_PERCENT
                + ReviewedWebsite::LEGITIMACY_METER_GOOD_PERCENT
                + ReviewedWebsite::LEGITIMACY_METER_LEGIT_PERCENT
        );
    }
}
