<?php

namespace Tests\Feature;

use PHPUnit\Framework\TestCase;

/**
 * Covers the canonical <link> logic in core/templates/head.twig.
 *
 * The fallback canonical used to read request.url_without_url_params, which any
 * controller passing a local `request` to its render (e.g. the Members auth
 * pages) would clobber, silently dropping the canonical tag. The fallback now
 * lives on a dedicated canonical_fallback_url global that no controller sets.
 */
class CanonicalTagTest extends TestCase
{
    /**
     * Render the real head.twig with the OpenGraph/Hotjar blocks gated off so
     * the canonical logic can be asserted in isolation.
     */
    private function renderHead(array $context): string
    {
        $defaults = [
            'seo_tags' => ['canonical' => ''],
            'canonical_fallback_url' => '',
            'page_meta' => ['id' => '', 'title' => '', 'description' => ''],
            'settings' => [
                'SITE_URL' => 'https://example.com',
                'THEME_PATH' => '/sites/default',
                'OPEN_GRAPH_META' => false,
                'HOTJAR_TRACKING_CODE' => '',
            ],
        ];

        return app('twig')->render('head.twig', array_replace_recursive($defaults, $context));
    }

    public function testAdminCanonicalTakesPrecedenceAndIsAbsolute(): void
    {
        $html = $this->renderHead([
            'seo_tags' => ['canonical' => '/online-doctor'],
            'canonical_fallback_url' => '/pharmacy/cf-3815-online-doctor',
        ]);

        $this->assertStringContainsString(
            '<link rel="canonical" href="https://example.com/online-doctor" />',
            $html
        );
        // The admin canonical wins; the fallback path must not appear.
        $this->assertStringNotContainsString('/pharmacy/cf-3815-online-doctor', $html);
    }

    public function testFallbackIsUsedWhenNoAdminCanonicalAndIsAbsolute(): void
    {
        $html = $this->renderHead([
            'canonical_fallback_url' => '/pharmacy/3815-online-doctor',
        ]);

        $this->assertStringContainsString(
            '<link rel="canonical" href="https://example.com/pharmacy/3815-online-doctor" />',
            $html
        );
    }

    public function testNoCanonicalIsRenderedWhenBothSourcesEmpty(): void
    {
        $html = $this->renderHead([]);

        $this->assertStringNotContainsString('rel="canonical"', $html);
    }

    /**
     * Regression for the clobbering bug: a controller passing a local `request`
     * variable to its render must not affect the canonical, because the
     * canonical now reads the dedicated fallback global instead of `request`.
     */
    public function testLocalRequestVariableDoesNotClobberCanonical(): void
    {
        $html = $this->renderHead([
            'canonical_fallback_url' => '/members/register',
            // Simulates a controller doing $twig_variables['request'] = $_REQUEST
            'request' => ['some_form_field' => 'value'],
        ]);

        $this->assertStringContainsString(
            '<link rel="canonical" href="https://example.com/members/register" />',
            $html
        );
    }
}
