<?php

namespace Tests\Feature;

use App\Models\Page;
use App\Models\Product;
use App\Models\Setting;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Cache;
use Tests\TestCase;

class SecurityPerformanceTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();
        \App\Models\Setting::clearCache();
        Setting::setValue('site_name', 'Sawdabazar', 'general');
    }

    /**
     * Test that security headers are present on all storefront responses.
     */
    public function test_security_headers_are_present_on_storefront()
    {
        $response = $this->get('/');

        $response->assertHeader('X-Content-Type-Options', 'nosniff');
        $response->assertHeader('X-Frame-Options', 'SAMEORIGIN');
        $response->assertHeader('X-XSS-Protection', '1; mode=block');
        $response->assertHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
        $response->assertHeader('Permissions-Policy', 'camera=(), microphone=(), geolocation=()');
    }

    /**
     * Test that robots.txt disallows restricted paths.
     */
    public function test_robots_txt_disallows_restricted_paths()
    {
        $response = $this->get('/robots.txt');

        $response->assertStatus(200);
        $this->assertStringStartsWith('text/plain', $response->headers->get('Content-Type'));
        $response->assertSee('Disallow: /admin', false);
        $response->assertSee('Disallow: /checkout', false);
        $response->assertSee('Disallow: /dashboard', false);
        $response->assertSee('Sitemap:', false);
    }

    /**
     * Test that Setting::getValue() caches results and returns from cache on second call.
     */
    public function test_setting_value_is_cached_on_read()
    {
        Cache::flush();

        Setting::setValue('test_cache_key', 'hello_world', 'general');

        // Cache should not exist yet (setValue clears, but getValue hasn't run)
        $this->assertFalse(Cache::has('setting_test_cache_key'));

        // First call — populates cache
        $value = Setting::getValue('test_cache_key');
        $this->assertEquals('hello_world', $value);

        // Cache should now exist
        $this->assertTrue(Cache::has('setting_test_cache_key'));
    }

    /**
     * Test that Setting::setValue() clears the cache automatically.
     */
    public function test_setting_value_clears_cache_on_save()
    {
        // Warm up the cache
        Setting::setValue('cache_clear_key', 'old_value', 'general');
        Setting::getValue('cache_clear_key'); // populate cache

        $this->assertTrue(Cache::has('setting_cache_clear_key'));

        // Update value — should clear cache
        Setting::setValue('cache_clear_key', 'new_value', 'general');

        $this->assertFalse(Cache::has('setting_cache_clear_key'));

        // Getting again should return updated value
        $this->assertEquals('new_value', Setting::getValue('cache_clear_key'));
    }

    /**
     * Test that the product detail page contains JSON-LD structured data.
     */
    public function test_product_detail_page_contains_json_ld()
    {
        $product = Product::create([
            'name' => 'Test Headphones',
            'slug' => 'test-headphones',
            'sku' => 'TH-001',
            'price' => 2500.00,
            'quantity' => 10,
            'is_visible' => true,
            'is_featured' => false,
            'seo_title' => 'Test Headphones - Best Quality',
            'seo_description' => 'Crystal clear audio experience.',
        ]);

        $response = $this->get('/products/' . $product->id);
        $response->assertStatus(200);

        $response->assertSee('"@type": "Product"', false);
        $response->assertSee('"name": "Test Headphones"', false);
        $response->assertSee('"sku": "TH-001"', false);
        $response->assertSee('"priceCurrency": "BDT"', false);
        $response->assertSee('"@type": "Offer"', false);
    }

    /**
     * Test that the dynamic page view contains WebPage JSON-LD and canonical tag.
     */
    public function test_dynamic_page_contains_json_ld_and_canonical()
    {
        $page = Page::create([
            'title' => 'Privacy Policy',
            'slug' => 'privacy-policy',
            'is_active' => true,
            'meta_title' => 'Privacy Policy - Sawdabazar',
            'meta_description' => 'Read our full privacy policy.',
        ]);

        $response = $this->get('/pages/privacy-policy');
        $response->assertStatus(200);

        $response->assertSee('"@type": "WebPage"', false);
        $response->assertSee('"name": "Privacy Policy - Sawdabazar"', false);
        $response->assertSee('<link rel="canonical"', false);
    }
}
