<?php

namespace Tests\Unit\Services\Scraping;

use App\Services\ProductPageScraper;
use App\Services\Scraping\CatalogListingProductValidator;
use Illuminate\Support\Facades\Http;
use Tests\TestCase;

class CatalogListingProductValidatorTest extends TestCase
{
    public function test_it_keeps_candidates_with_matching_listing_image_and_price(): void
    {
        $validator = new CatalogListingProductValidator(new ProductPageScraper);

        $validated = $validator->validateAndEnrich([
            [
                'name' => 'Realspace® Metal Folding Chair, Black',
                'url' => 'https://www.officedepot.com/a/products/254901/Realspace-Metal-Folding-Chair-Black/',
                'price' => '$49.99',
                'list_price' => '$79.99',
                'image_url' => 'https://media.officedepot.com/images/t_large,f_auto/products/254901/1.jpg',
            ],
        ]);

        $this->assertCount(1, $validated);
        $this->assertSame('$49.99', $validated[0]['price']);
        $this->assertSame('$79.99', $validated[0]['list_price']);
        $this->assertStringContainsString('/products/254901/', $validated[0]['image_url']);
    }

    public function test_it_drops_candidates_with_promo_images_that_do_not_match_the_product(): void
    {
        Http::preventStrayRequests();
        Http::fake([
            'https://www.officedepot.com/*' => Http::response(''),
        ]);

        $validator = new CatalogListingProductValidator(new ProductPageScraper);

        $validated = $validator->validateAndEnrich([
            [
                'name' => 'RS Gaming™ Chair',
                'url' => 'https://www.officedepot.com/a/products/9288997/Bestier-Ergonomic-Faux-Leather/',
                'price' => '$319.99',
                'image_url' => 'https://media.officedepot.com/image/upload/v1753716258/CREATIVE/CREATIVE_2025/SITE/GLOBAL/promo.jpg',
            ],
        ]);

        $this->assertSame([], $validated);
    }

    public function test_it_drops_duplicate_product_images(): void
    {
        Http::preventStrayRequests();
        Http::fake([
            'https://www.officedepot.com/*' => Http::response(''),
        ]);

        $validator = new CatalogListingProductValidator(new ProductPageScraper);

        $validated = $validator->validateAndEnrich([
            [
                'name' => 'Chair A',
                'url' => 'https://www.officedepot.com/a/products/110079/Realspace-Upholstered-Padded-Folding-Chair-Gray/',
                'price' => '$49.99',
                'image_url' => 'https://media.officedepot.com/images/t_large,f_auto/products/110079/1.jpg',
            ],
            [
                'name' => 'Chair B',
                'url' => 'https://www.officedepot.com/a/products/110043/Realspace-Upholstered-Padded-Folding-Chair-Tan/',
                'price' => '$49.99',
                'image_url' => 'https://media.officedepot.com/images/t_large,f_auto/products/110079/1.jpg',
            ],
        ]);

        $this->assertCount(1, $validated);
    }

    public function test_it_enriches_null_listing_images_from_the_product_page(): void
    {
        $productUrl = 'https://www.officedepot.com/a/products/2146434/Whalen-Marilla-48W-Pedestal-Desk-Driftwood/';
        $gallery = 'https://media.officedepot.com/images/f_auto,q_auto,e_sharpen,h_450/products/2146434/2146434_o01_whalen_marilla_48w_pedestal_desk_071723/2146434_o01_whalen_marilla_48w_pedestal_desk_071723.jpg';
        $jsonLd = json_encode([
            '@type' => 'Product',
            'name' => 'Whalen Marilla Desk',
            'image' => [
                '@type' => 'ImageObject',
                'contentUrl' => $gallery,
            ],
            'offers' => [
                'price' => '99.99',
                'highPrice' => '339.99',
                'priceCurrency' => 'USD',
            ],
        ]);
        $lexmarkLogo = 'https://media.officedepot.com/image/upload/v1614112807/assets/lexmark_logo.jpg';
        $html = '<html><head><title>Whalen Desk</title></head><body>'
            .'<h1>Whalen Marilla Desk</h1>'
            .str_repeat('<p>Desk feature copy.</p>', 50)
            .'<script type="application/ld+json">'.$jsonLd.'</script>'
            .'</body></html>';

        Http::fake([
            $productUrl => Http::response($html),
        ]);

        $validated = (new CatalogListingProductValidator(new ProductPageScraper))->validateAndEnrich([
            [
                'name' => 'Whalen® Marilla 48"W Wood Pedestal Computer Desk, Driftwood Gray',
                'url' => $productUrl,
                'price' => '$99.99',
                'list_price' => '$339.99',
                'image_url' => null,
            ],
        ]);

        $this->assertCount(1, $validated);
        $this->assertSame($gallery, $validated[0]['image_url']);
    }

    public function test_it_keeps_kohls_listing_candidates_with_matching_media_image_and_price(): void
    {
        $validated = (new CatalogListingProductValidator(new ProductPageScraper))->validateAndEnrich([
            [
                'name' => 'adidas VL Court 3.0 Women\'s Shoes',
                'url' => 'https://www.kohls.com/product/prd-6554861/adidas-vl-court-30-womens-shoes.jsp',
                'price' => '$44.97',
                'image_url' => 'https://media.kohlsimg.com/is/image/kohls/6554861_Brown?wid=342&hei=342&op_sharpen=1',
            ],
        ]);

        $this->assertCount(1, $validated);
        $this->assertSame('$44.97', $validated[0]['price']);
    }

    public function test_it_keeps_json_import_images_that_do_not_match_retailer_product_ids(): void
    {
        Http::preventStrayRequests();

        $imageUrl = 'https://rukminim2.flixcart.com/image/612/612/xif0q/projector/h/t/y/-original-imahqpx5ptwfjsaa.jpeg?q=70';
        $productUrl = 'https://www.flipkart.com/portronics-beem-440/p/itm3a7b5a9c35131?pid=PROGWMG6UKHH6HKZ';

        $validated = (new CatalogListingProductValidator(new ProductPageScraper))->validateAndEnrich([
            [
                'name' => 'Portronics Beem 440 Projector',
                'url' => $productUrl,
                'price' => '₹6,798',
                'image_url' => $imageUrl,
                'rating' => '4.1',
                'review_count' => '1310',
                'discovery_source' => 'json',
            ],
        ], trustProvidedImages: true);

        $this->assertCount(1, $validated);
        $this->assertSame($imageUrl, $validated[0]['image_url']);
        $this->assertSame('₹6,798', $validated[0]['price']);
    }

    public function test_it_falls_back_to_the_provided_json_image_when_the_product_page_has_no_matching_image(): void
    {
        $productUrl = 'https://www.flipkart.com/crossbeats-lumex-pro/p/itmdcef5cd8cef95?pid=PROHHTF4XMWYPWJE';
        $jsonImage = 'https://rukminim2.flixcart.com/image/612/612/xif0q/projector/y/z/k/-original-imahn65a6nnk7z7q.jpeg?q=70';

        Http::preventStrayRequests();
        Http::fake([
            $productUrl => Http::response('<html><body><h1>Projector</h1></body></html>'),
        ]);

        $validated = (new CatalogListingProductValidator(new ProductPageScraper))->validateAndEnrich([
            [
                'name' => 'CrossBeats Lumex Pro Projector',
                'url' => $productUrl,
                'price' => '₹9,999',
                'image_url' => $jsonImage,
                'discovery_source' => 'json',
            ],
        ], trustProvidedImages: true);

        $this->assertCount(1, $validated);
        $this->assertSame($jsonImage, $validated[0]['image_url']);
    }
}
