<?php

namespace Tests\Unit;

use App\Models\Category;
use App\Models\Product;
use App\Services\ProductComparisonService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class ProductComparisonServiceTest extends TestCase
{
    use RefreshDatabase;

    protected ProductComparisonService $service;

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

        $this->service = new ProductComparisonService;
    }

    public function test_compare_returns_empty_array_for_no_products(): void
    {
        $result = $this->service->compare(collect());

        $this->assertIsArray($result);
        $this->assertEmpty($result);
    }

    public function test_compare_returns_analysis(): void
    {
        $category = Category::factory()->create();
        $products = Product::factory()->count(3)->create([
            'category_id' => $category->id,
            'price' => [100, 200, 300],
            'positive_feedback' => [80, 90, 85],
            'discount' => [10, 20, 15],
        ]);

        $result = $this->service->compare($products);

        $this->assertArrayHasKey('products', $result);
        $this->assertArrayHasKey('analysis', $result);
        $this->assertArrayHasKey('price_range', $result);
        $this->assertArrayHasKey('comparison_matrix', $result);
        $this->assertCount(3, $result['products']);
    }

    public function test_compare_identifies_best_value(): void
    {
        $category = Category::factory()->create();
        $products = Product::factory()->count(3)->create([
            'category_id' => $category->id,
            'price' => 100,
            'positive_feedback' => 90,
            'discount' => 20,
        ]);

        $result = $this->service->compare($products);

        $this->assertArrayHasKey('best_value', $result['analysis']);
        $this->assertNotNull($result['analysis']['best_value']);
    }

    public function test_compare_identifies_highest_quality(): void
    {
        $category = Category::factory()->create();
        Product::factory()->create([
            'category_id' => $category->id,
            'positive_feedback' => 95,
            'sales_180day' => 200,
        ]);
        Product::factory()->create([
            'category_id' => $category->id,
            'positive_feedback' => 85,
            'sales_180day' => 100,
        ]);

        $products = Product::all();
        $ranked = $this->service->rankByQuality($products);

        $this->assertEquals(95, $ranked->first()->positive_feedback);
    }

    public function test_compare_calculates_price_range(): void
    {
        $category = Category::factory()->create();
        Product::factory()->create([
            'category_id' => $category->id,
            'price' => 50,
        ]);
        Product::factory()->create([
            'category_id' => $category->id,
            'price' => 150,
        ]);
        Product::factory()->create([
            'category_id' => $category->id,
            'price' => 100,
        ]);

        $products = Product::all();
        $result = $this->service->compare($products);

        $this->assertEquals(50, $result['price_range']['min']);
        $this->assertEquals(150, $result['price_range']['max']);
        $this->assertEquals(100, $result['price_range']['avg']);
    }

    public function test_determine_best_choice_weights_preferences(): void
    {
        $category = Category::factory()->create();

        $lowPriceHighQuality = Product::factory()->create([
            'category_id' => $category->id,
            'price' => 100,
            'positive_feedback' => 95,
            'discount' => 5,
            'sales_180day' => 100,
        ]);

        $highPriceLowQuality = Product::factory()->create([
            'category_id' => $category->id,
            'price' => 500,
            'positive_feedback' => 70,
            'discount' => 30,
            'sales_180day' => 50,
        ]);

        $products = collect([$lowPriceHighQuality, $highPriceLowQuality]);

        $bestForPrice = $this->service->determineBestChoice($products, [
            'price_importance' => 0.7,
            'quality_importance' => 0.2,
            'discount_importance' => 0.1,
        ]);

        $this->assertEquals($lowPriceHighQuality->id, $bestForPrice->id);
    }

    public function test_comparison_matrix_includes_all_metrics(): void
    {
        $category = Category::factory()->create();
        $products = Product::factory()->count(2)->create([
            'category_id' => $category->id,
        ]);

        $result = $this->service->compare($products);

        $this->assertArrayHasKey('prices', $result['comparison_matrix']);
        $this->assertArrayHasKey('discounts', $result['comparison_matrix']);
        $this->assertArrayHasKey('ratings', $result['comparison_matrix']);
        $this->assertArrayHasKey('sales', $result['comparison_matrix']);
    }
}
