<?php

namespace Tests\Unit;

use App\Support\BackUrl;
use Illuminate\Support\Arr;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\TestCase;

class BackUrlAppendBackTest extends TestCase
{
    public static function withBackCases(): array
    {
        $back = '/admin/platform-orders/2';
        $backQuery = Arr::query(['back' => $back]);

        return [
            'no query' => ['/admin/site-subscriptions/2', $back, '/admin/site-subscriptions/2?' . $backQuery],
            'question mark only' => ['/admin/site-subscriptions/2?', $back, '/admin/site-subscriptions/2?' . $backQuery],
            'question mark with ampersand' => ['/admin/site-subscriptions/2?&', $back, '/admin/site-subscriptions/2?' . $backQuery],
            'has query' => ['/admin/site-subscriptions/2?order_sync_status=syncable', $back, '/admin/site-subscriptions/2?order_sync_status=syncable&' . $backQuery],
            'has query with trailing &' => ['/admin/site-subscriptions/2?order_sync_status=syncable&', $back, '/admin/site-subscriptions/2?order_sync_status=syncable&' . $backQuery],
        ];
    }

    #[DataProvider('withBackCases')]
    public function test_with_back_should_not_generate_question_ampersand(string $path, string $back, string $expected): void
    {
        $url = BackUrl::withBack($path, $back);

        $this->assertSame($expected, $url);
        $this->assertStringNotContainsString('?&', $url);
    }

    public function test_with_back_should_ignore_non_relative_path(): void
    {
        $url = BackUrl::withBack('https://example.com/a?x=1', '/admin/x');
        $this->assertSame('https://example.com/a?x=1', $url);
    }

    public function test_with_back_first_should_put_back_in_front(): void
    {
        $back = '/admin/platform-orders/2';
        $backQuery = Arr::query(['back' => $back]);

        $url = BackUrl::withBackFirst('/admin/site-subscriptions/2?order_sync_status=syncable', $back);

        $this->assertSame('/admin/site-subscriptions/2?' . $backQuery . '&order_sync_status=syncable', $url);
    }

    public function test_with_back_first_and_fragment_should_keep_fragment_whitelist(): void
    {
        $back = '/admin/platform-orders/2';
        $backQuery = Arr::query(['back' => $back]);

        $url = BackUrl::withBackFirstAndFragment('/admin/site-subscriptions/2?order_sync_status=syncable', $back, 'syncable-batch');

        $this->assertSame('/admin/site-subscriptions/2?' . $backQuery . '&order_sync_status=syncable#syncable-batch', $url);

        $url2 = BackUrl::withBackFirstAndFragment('/admin/site-subscriptions/2?order_sync_status=syncable', $back, 'bad#frag');
        $this->assertSame('/admin/site-subscriptions/2?' . $backQuery . '&order_sync_status=syncable', $url2);
    }
}
