<?php

declare(strict_types=1);

namespace Tests\Feature;

use App\Livewire\Admin\ReviewedWebsites\CommunityReviewsManage;
use App\Models\ReviewedWebsite;
use App\Models\ReviewedWebsiteReview;
use App\Models\User;
use App\Services\TrustDirectory\RandomReviewedWebsiteReviewGenerator;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
use Spatie\Permission\Models\Role;
use Tests\TestCase;

final class AdminTrustCheckCommunityReviewsTest extends TestCase
{
    use RefreshDatabase;

    public function test_guest_cannot_open_trust_check_reviews_management(): void
    {
        $this->get(route('admin.reviewed-websites.community-reviews'))
            ->assertRedirect();
    }

    public function test_generator_legit_tone_creates_legit_verdicts(): void
    {
        $website = ReviewedWebsite::factory()->published()->create(['name' => 'Demo Shop']);

        $generator = new RandomReviewedWebsiteReviewGenerator;
        $generator->generate($website, 8, RandomReviewedWebsiteReviewGenerator::TONE_LEGIT);

        $reviews = ReviewedWebsiteReview::query()->where('reviewed_website_id', $website->id)->get();
        $this->assertCount(8, $reviews);

        foreach ($reviews as $r) {
            $this->assertSame(ReviewedWebsiteReview::STATUS_APPROVED, $r->status);
            $this->assertSame(ReviewedWebsiteReview::VERDICT_LEGIT, $r->user_verdict);
            $this->assertGreaterThanOrEqual(4, $r->rating);
        }
    }

    public function test_generator_fintech_industry_uses_sector_phrasing(): void
    {
        $website = ReviewedWebsite::factory()->published()->create([
            'name' => 'PayFlow',
            'industry' => ReviewedWebsite::INDUSTRY_FINTECH,
        ]);

        $generator = new RandomReviewedWebsiteReviewGenerator;
        $generator->generate($website, 12, RandomReviewedWebsiteReviewGenerator::TONE_LEGIT);

        $blob = ReviewedWebsiteReview::query()
            ->where('reviewed_website_id', $website->id)
            ->pluck('body')
            ->implode(' ');

        $this->assertMatchesRegularExpression(
            '/\b(payment|payout|transfer|invoice|ACH|billing|KYC|settlement|ledger|vendor|fee)\b/i',
            $blob
        );
    }

    public function test_generator_scam_tone_creates_scam_verdicts(): void
    {
        $website = ReviewedWebsite::factory()->published()->create(['name' => 'Risky Co']);

        $generator = new RandomReviewedWebsiteReviewGenerator;
        $generator->generate($website, 6, RandomReviewedWebsiteReviewGenerator::TONE_SCAM);

        $reviews = ReviewedWebsiteReview::query()->where('reviewed_website_id', $website->id)->get();
        $this->assertCount(6, $reviews);

        foreach ($reviews as $r) {
            $this->assertSame(ReviewedWebsiteReview::VERDICT_SCAM, $r->user_verdict);
            $this->assertLessThanOrEqual(3, $r->rating);
        }
    }

    public function test_admin_can_bulk_generate_from_manage_screen(): void
    {
        Role::findOrCreate('admin');
        $admin = User::factory()->create();
        $admin->assignRole('admin');

        $website = ReviewedWebsite::factory()->published()->create(['name' => 'Bulk Target']);

        Livewire::actingAs($admin)
            ->test(CommunityReviewsManage::class)
            ->set('bulkWebsiteId', $website->id)
            ->set('bulkCount', 3)
            ->set('bulkTone', RandomReviewedWebsiteReviewGenerator::TONE_MIXED)
            ->call('generateBulk')
            ->assertHasNoErrors();

        $this->assertSame(3, ReviewedWebsiteReview::query()->where('reviewed_website_id', $website->id)->count());
    }
}
