<?php

namespace Tests\Feature;

use App\Models\Feedback;
use App\Models\Item;
use App\Models\Transaction;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class FeedbackTest extends TestCase
{
    use RefreshDatabase;

    private User $seller;
    private User $buyer;
    private Transaction $transaction;

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

        $this->seller = User::factory()->create()->refresh();
        $this->buyer = User::factory()->create()->refresh();

        $item = Item::create([
            'user_id' => $this->seller->id,
            'title' => 'Test Synth',
            'description' => 'A synth',
            'price' => 100,
            'condition' => 'Good',
            'quantity' => 1,
            'listing_type' => 'sale',
            'status' => 'sold',
            'location_country' => 'US',
        ]);

        $this->transaction = Transaction::create([
            'item_id' => $item->id,
            'seller_id' => $this->seller->id,
            'buyer_id' => $this->buyer->id,
            'price' => 100,
            'status' => 'completed',
            'type' => 'sale',
            'completed_at' => now(),
        ]);
    }

    public function test_buyer_can_rate_seller_and_aggregates_update(): void
    {
        $response = $this->actingAs($this->buyer)
            ->post(route('transactions.feedback', $this->transaction), [
                'rating' => 4,
                'comment' => 'Fast shipping, well packed.',
            ]);

        $response->assertRedirect();
        $this->assertDatabaseHas('feedback', [
            'transaction_id' => $this->transaction->id,
            'reviewer_id' => $this->buyer->id,
            'reviewee_id' => $this->seller->id,
            'rating' => 4,
            'type' => 'buyer',
        ]);

        $this->seller->refresh();
        $this->assertSame('4.00', (string) $this->seller->rating);
        $this->assertSame(1, $this->seller->total_reviews);
    }

    public function test_seller_can_rate_buyer(): void
    {
        $this->actingAs($this->seller)
            ->post(route('transactions.feedback', $this->transaction), ['rating' => 5]);

        $this->assertDatabaseHas('feedback', [
            'reviewer_id' => $this->seller->id,
            'reviewee_id' => $this->buyer->id,
            'type' => 'seller',
        ]);
        $this->assertSame(1, $this->buyer->fresh()->total_reviews);
    }

    public function test_feedback_requires_completed_transaction(): void
    {
        $this->transaction->update(['status' => 'pending']);

        $this->actingAs($this->buyer)
            ->from(route('transactions.show', $this->transaction))
            ->post(route('transactions.feedback', $this->transaction), ['rating' => 5])
            ->assertRedirect(route('transactions.show', $this->transaction));

        $this->assertDatabaseCount('feedback', 0);
    }

    public function test_feedback_can_only_be_left_once(): void
    {
        Feedback::create([
            'transaction_id' => $this->transaction->id,
            'reviewer_id' => $this->buyer->id,
            'reviewee_id' => $this->seller->id,
            'rating' => 5,
            'type' => 'buyer',
            'is_public' => true,
        ]);

        $this->actingAs($this->buyer)
            ->post(route('transactions.feedback', $this->transaction), ['rating' => 1]);

        $this->assertDatabaseCount('feedback', 1);
        $this->assertDatabaseMissing('feedback', ['rating' => 1]);
    }

    public function test_strangers_cannot_leave_feedback(): void
    {
        $stranger = User::factory()->create()->refresh();

        $this->actingAs($stranger)
            ->post(route('transactions.feedback', $this->transaction), ['rating' => 5])
            ->assertForbidden();
    }

    public function test_average_rating_across_multiple_reviews(): void
    {
        $this->actingAs($this->buyer)
            ->post(route('transactions.feedback', $this->transaction), ['rating' => 5]);

        // Second completed transaction from another buyer
        $buyer2 = User::factory()->create()->refresh();
        $item2 = Item::create([
            'user_id' => $this->seller->id,
            'title' => 'Second Synth',
            'description' => 'Another synth',
            'price' => 50,
            'condition' => 'Good',
            'quantity' => 1,
            'listing_type' => 'sale',
            'status' => 'sold',
            'location_country' => 'US',
        ]);
        $transaction2 = Transaction::create([
            'item_id' => $item2->id,
            'seller_id' => $this->seller->id,
            'buyer_id' => $buyer2->id,
            'price' => 50,
            'status' => 'completed',
            'type' => 'sale',
            'completed_at' => now(),
        ]);

        $this->actingAs($buyer2)
            ->post(route('transactions.feedback', $transaction2), ['rating' => 2]);

        $this->seller->refresh();
        $this->assertSame('3.50', (string) $this->seller->rating);
        $this->assertSame(2, $this->seller->total_reviews);
    }
}
