<?php

namespace Tests\Unit\Services\AI;

use App\Services\AI\LaravelAiCatalogPageDataResolver;
use App\Services\ProductPageScraper;
use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\Http;
use Laravel\Ai\StructuredAnonymousAgent;
use Tests\TestCase;

class LaravelAiCatalogPageDataResolverTest extends TestCase
{
    public function test_it_reconciles_scraped_images_and_product_urls(): void
    {
        Http::preventStrayRequests();
        Http::fake([
            'https://example.com/can' => Http::response('<html><meta property="og:image" content="https://cdn.example.com/can.png"><body>Watering can $18</body></html>'),
            'https://example.com/rake' => Http::response('<html><meta property="og:image" content="https://cdn.example.com/rake.png"><body>Garden rake $22</body></html>'),
        ]);

        StructuredAnonymousAgent::fake([
            $this->catalogPayload(),
        ]);

        $catalog = (new LaravelAiCatalogPageDataResolver(new ProductPageScraper))->resolve(
            'Hoe',
            ['https://example.com/can', 'https://example.com/rake'],
            advertiserId: '15881',
            campaignId: '122609',
        );

        $this->assertSame('Hoe', $catalog->brand);
        $this->assertSame('15881', $catalog->advertiserId);
        $this->assertSame('122609', $catalog->campaignId);
        $this->assertCount(2, $catalog->products);
        $this->assertSame('https://example.com/can', $catalog->products[0]->retailerUrl);
        $this->assertSame('https://example.com/rake', $catalog->products[1]->retailerUrl);
        $this->assertSame('https://cdn.example.com/can.png', $catalog->products[0]->imageUrl);
        $this->assertSame('https://cdn.example.com/rake.png', $catalog->products[1]->imageUrl);

        Http::assertSent(fn (Request $request) => str_contains(
            (string) ($request->header('User-Agent')[0] ?? ''),
            'Chrome',
        ));
    }

    public function test_it_uses_json_ld_content_url_instead_of_image_object_type(): void
    {
        Http::preventStrayRequests();
        $jsonLd = json_encode([
            '@type' => 'Product',
            'name' => 'Magellan Desk',
            'image' => [
                '@type' => 'ImageObject',
                'contentUrl' => 'https://cdn.officedepot.com/desks/magellan.jpg',
            ],
        ]);

        Http::fake([
            'https://www.officedepot.com/desk' => Http::response(
                '<html><script type="application/ld+json">'.$jsonLd.'</script><body>Magellan desk $379.99</body></html>'
            ),
        ]);

        StructuredAnonymousAgent::fake([
            $this->catalogPayload([
                'products' => [
                    $this->productPayload(
                        'Magellan Desk',
                        'https://wrong.example.com/desk',
                        'https://www.officedepot.com/a/products/956652/ImageObject',
                    ),
                ],
            ]),
        ]);

        $catalog = (new LaravelAiCatalogPageDataResolver(new ProductPageScraper))->resolve(
            'Office Depot',
            ['https://www.officedepot.com/desk'],
        );

        $this->assertSame('Office Depot', $catalog->brand);
        $this->assertSame('https://www.officedepot.com/desk', $catalog->products[0]->retailerUrl);
        $this->assertSame('https://cdn.officedepot.com/desks/magellan.jpg', $catalog->products[0]->imageUrl);
    }

    /**
     * @param  array<string, mixed>  $overrides
     * @return array<string, mixed>
     */
    private function catalogPayload(array $overrides = []): array
    {
        return [
            'Brand' => 'garden-tools-v1',
            'advertiser_id' => '',
            'campaign_id' => '',
            'subcategory' => 'Garden Tools',
            'category' => 'Home',
            'updated' => 'May 2026',
            'hero_title' => 'Find the right garden tools.',
            'review_sources' => [
                [
                    'name' => 'Wirecutter',
                    'url' => 'https://www.nytimes.com/wirecutter/reviews/best-watering-cans/',
                    'angle' => 'Ranked watering cans',
                ],
            ],
            'products' => [
                $this->productPayload('Watering Can', 'https://wrong.example.com/can', 'https://cdn.example.com/wrong-can.png'),
                $this->productPayload('Garden Rake', 'https://wrong.example.com/rake', 'https://cdn.example.com/wrong-rake.png'),
            ],
            ...$overrides,
        ];
    }

    /**
     * @return array<string, mixed>
     */
    private function productPayload(string $name, string $retailerUrl, string $imageUrl): array
    {
        return [
            'name' => $name,
            'brand' => 'Hoe',
            'best_for' => 'Best Overall',
            'price' => '$18',
            'list_price' => '',
            'discount' => '',
            'rating' => '4.7',
            'review_count' => '12',
            'price_history' => '',
            'image_url' => $imageUrl,
            'retailer_url' => $retailerUrl,
            'chips' => ['Shopper favorite'],
            'convertibility' => '',
            'certification' => '',
            'summary' => $name.' summary',
            'summary_short' => $name.' short',
            'why_it_stands_out' => $name.' stands out',
            'why_short' => $name.' why',
            'pros' => ['Durable'],
            'cons' => ['Heavy'],
            'tradeoff_note' => 'Sturdy but heavy.',
            'sources_note' => 'Shopper favorite.',
        ];
    }
}
