<?php

namespace Tests\Unit;

use App\Models\Product;
use App\Models\ProductReview;
use App\Models\User;
use App\Models\Category;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class ProductReviewTest extends TestCase
{
    use RefreshDatabase;

    public function test_product_review_belongs_to_product()
    {
        $category = Category::factory()->create();
        $product = Product::factory()->create(['category_id' => $category->id]);
        $user = User::factory()->create();
        
        $review = ProductReview::factory()->create([
            'product_id' => $product->id,
            'user_id' => $user->id,
            'rating' => 5,
        ]);

        $this->assertInstanceOf(Product::class, $review->product);
        $this->assertEquals($product->id, $review->product->id);
    }

    public function test_product_review_belongs_to_user()
    {
        $category = Category::factory()->create();
        $product = Product::factory()->create(['category_id' => $category->id]);
        $user = User::factory()->create();
        
        $review = ProductReview::factory()->create([
            'product_id' => $product->id,
            'user_id' => $user->id,
            'rating' => 4,
        ]);

        $this->assertInstanceOf(User::class, $review->user);
        $this->assertEquals($user->id, $review->user->id);
    }

    public function test_product_review_can_have_null_user()
    {
        $category = Category::factory()->create();
        $product = Product::factory()->create(['category_id' => $category->id]);
        
        $review = ProductReview::factory()->create([
            'product_id' => $product->id,
            'user_id' => null,
            'rating' => 3,
        ]);

        $this->assertNull($review->user);
    }

    public function test_approved_scope_filters_approved_reviews()
    {
        $category = Category::factory()->create();
        $product = Product::factory()->create(['category_id' => $category->id]);
        $user = User::factory()->create();
        
        ProductReview::factory()->create([
            'product_id' => $product->id,
            'user_id' => $user->id,
            'is_approved' => true,
        ]);
        
        ProductReview::factory()->create([
            'product_id' => $product->id,
            'user_id' => $user->id,
            'is_approved' => false,
        ]);

        $approvedReviews = ProductReview::approved()->get();
        
        $this->assertEquals(1, $approvedReviews->count());
        $this->assertTrue($approvedReviews->first()->is_approved);
    }

    public function test_pending_scope_filters_pending_reviews()
    {
        $category = Category::factory()->create();
        $product = Product::factory()->create(['category_id' => $category->id]);
        $user = User::factory()->create();
        
        ProductReview::factory()->create([
            'product_id' => $product->id,
            'user_id' => $user->id,
            'is_approved' => true,
        ]);
        
        ProductReview::factory()->create([
            'product_id' => $product->id,
            'user_id' => $user->id,
            'is_approved' => false,
        ]);

        $pendingReviews = ProductReview::pending()->get();
        
        $this->assertEquals(1, $pendingReviews->count());
        $this->assertFalse($pendingReviews->first()->is_approved);
    }

    public function test_for_product_scope_filters_by_product()
    {
        $category = Category::factory()->create();
        $product1 = Product::factory()->create(['category_id' => $category->id]);
        $product2 = Product::factory()->create(['category_id' => $category->id]);
        $user = User::factory()->create();
        
        ProductReview::factory()->create([
            'product_id' => $product1->id,
            'user_id' => $user->id,
        ]);
        
        ProductReview::factory()->create([
            'product_id' => $product2->id,
            'user_id' => $user->id,
        ]);

        $reviews = ProductReview::forProduct($product1->id)->get();
        
        $this->assertEquals(1, $reviews->count());
        $this->assertEquals($product1->id, $reviews->first()->product_id);
    }

    public function test_mark_as_helpful_increments_helpful_count()
    {
        $category = Category::factory()->create();
        $product = Product::factory()->create(['category_id' => $category->id]);
        $user = User::factory()->create();
        
        $review = ProductReview::factory()->create([
            'product_id' => $product->id,
            'user_id' => $user->id,
            'helpful_count' => 5,
        ]);

        $review->markAsHelpful();
        $review->refresh();

        $this->assertEquals(6, $review->helpful_count);
    }

    public function test_is_author_returns_true_for_review_author()
    {
        $category = Category::factory()->create();
        $product = Product::factory()->create(['category_id' => $category->id]);
        $user = User::factory()->create();
        $otherUser = User::factory()->create();
        
        $review = ProductReview::factory()->create([
            'product_id' => $product->id,
            'user_id' => $user->id,
        ]);

        $this->assertTrue($review->isAuthor($user));
        $this->assertFalse($review->isAuthor($otherUser));
        $this->assertFalse($review->isAuthor(null));
    }

    public function test_product_recalculate_rating_calculates_average()
    {
        $category = Category::factory()->create();
        $product = Product::factory()->create(['category_id' => $category->id]);
        $user = User::factory()->create();
        
        ProductReview::factory()->create([
            'product_id' => $product->id,
            'user_id' => $user->id,
            'rating' => 5,
            'is_approved' => true,
        ]);
        
        ProductReview::factory()->create([
            'product_id' => $product->id,
            'user_id' => $user->id,
            'rating' => 3,
            'is_approved' => true,
        ]);
        
        ProductReview::factory()->create([
            'product_id' => $product->id,
            'user_id' => $user->id,
            'rating' => 4,
            'is_approved' => false, // Not approved, should not count
        ]);

        $result = $product->recalculateRating();
        $product->refresh();

        $this->assertEquals(4.0, $product->avg_rating);
        $this->assertEquals(2, $product->rating_count);
        $this->assertEquals(4.0, $result['avg_rating']);
        $this->assertEquals(2, $result['rating_count']);
    }

    public function test_product_recalculate_rating_handles_no_reviews()
    {
        $category = Category::factory()->create();
        $product = Product::factory()->create(['category_id' => $category->id]);

        $result = $product->recalculateRating();
        $product->refresh();

        $this->assertEquals(0.00, $product->avg_rating);
        $this->assertEquals(0, $product->rating_count);
    }
}

