<?php

// PetitionFormTest.php (which loads first alphabetically) already required
// petition-form.php and defined Context / Hook / Hooks stubs.
// This file only adds tests — no re-requires or re-declarations needed.

/**
 * Build a minimal Context mock that supports get('translations') and get('currentLang').
 */
function mockContext(array $translations = [], string $lang = 'no'): object
{
    return new class($translations, $lang) extends Context {
        public function __construct(
            private array $translations,
            private string $lang
        ) {}

        public function get(string $key, mixed $default = null): mixed
        {
            return match ($key) {
                'translations' => $this->translations,
                'currentLang'  => $this->lang,
                default        => $default,
            };
        }
    };
}

// --- petitionT ---

it('returns the key when no translation is found', function () {
    $ctx = mockContext([]);
    expect(petitionT($ctx, 'petition', 'missing_key'))->toBe('missing_key');
});

it('returns the translated string when found', function () {
    $ctx = mockContext(['petition.greeting' => 'Hei!']);
    expect(petitionT($ctx, 'petition', 'greeting'))->toBe('Hei!');
});

it('applies placeholder replacements', function () {
    $ctx = mockContext(['petition.email_greeting' => 'Hei {name}!']);
    expect(petitionT($ctx, 'petition', 'email_greeting', ['name' => 'Kari']))->toBe('Hei Kari!');
});

it('applies multiple replacements in a single string', function () {
    $ctx = mockContext(['petition.thanks' => 'Takk {name} for {title}']);
    $result = petitionT($ctx, 'petition', 'thanks', ['name' => 'Ola', 'title' => 'kampanjen']);
    expect($result)->toBe('Takk Ola for kampanjen');
});

it('uses the section as part of the translation key', function () {
    $ctx = mockContext(['regions.oslo' => 'Oslo', 'petition.oslo' => 'Wrong']);
    expect(petitionT($ctx, 'regions', 'oslo'))->toBe('Oslo');
});

// --- petitionGetIdFromPath ---

it('returns the basename of a path as the petition ID', function () {
    expect(petitionGetIdFromPath('/content/underskriftskampanje/my-petition'))->toBe('my-petition');
});

it('strips a leading numeric prefix from the folder name', function () {
    expect(petitionGetIdFromPath('/content/01-my-petition'))->toBe('my-petition');
    expect(petitionGetIdFromPath('/content/001-my-petition'))->toBe('my-petition');
});

it('leaves non-prefixed names intact', function () {
    expect(petitionGetIdFromPath('/content/medisinsk-cannabis'))->toBe('medisinsk-cannabis');
});

it('returns null when the basename is empty', function () {
    expect(petitionGetIdFromPath('/'))->toBeNull();
});

// --- petitionFormatDate ---

it('formats a date in Norwegian by default', function () {
    date_default_timezone_set('UTC');
    $ctx = mockContext([], 'no');
    // 2024-03-15 10:05:00 UTC
    $ts = mktime(10, 5, 0, 3, 15, 2024);
    expect(petitionFormatDate($ts, $ctx))->toBe('15. mars 2024, 10:05');
});

it('formats a date in English when lang is en', function () {
    date_default_timezone_set('UTC');
    $ctx = mockContext([], 'en');
    $ts = mktime(10, 5, 0, 3, 15, 2024);
    expect(petitionFormatDate($ts, $ctx))->toBe('March 15, 2024, 10:05');
});

it('uses Norwegian month names for an unknown language', function () {
    date_default_timezone_set('UTC');
    $ctx = mockContext([], 'fr');
    $ts = mktime(0, 0, 0, 1, 1, 2024);
    $result = petitionFormatDate($ts, $ctx);
    expect($result)->toContain('januar');
});

it('uses the correct Norwegian month names', function () {
    date_default_timezone_set('UTC');
    $ctx = mockContext([], 'no');
    $months = ['januar','februar','mars','april','mai','juni',
               'juli','august','september','oktober','november','desember'];
    foreach ($months as $i => $name) {
        $ts = mktime(0, 0, 0, $i + 1, 1, 2024);
        expect(petitionFormatDate($ts, $ctx))->toContain($name);
    }
});

// --- petitionFormatSignature ---

it('shows only first name and region for semi display', function () {
    $ctx = mockContext([
        'petition.from_region' => 'fra',
        'regions.oslo'         => 'Oslo',
    ]);
    $sig = ['firstname' => 'Kari', 'surname' => 'Hansen', 'region' => 'oslo', 'display' => 'semi'];
    $result = petitionFormatSignature($sig, $ctx);
    expect($result)->toBe('Kari fra Oslo');
    expect($result)->not->toContain('Hansen');
});

it('shows full name and region for full display', function () {
    $ctx = mockContext([
        'petition.from_region' => 'fra',
        'regions.oslo'         => 'Oslo',
    ]);
    $sig = ['firstname' => 'Kari', 'surname' => 'Hansen', 'region' => 'oslo', 'display' => 'full'];
    expect(petitionFormatSignature($sig, $ctx))->toBe('Kari Hansen fra Oslo');
});

it('shows anonymous label for anonymous display', function () {
    $ctx = mockContext([
        'petition.from_region'   => 'fra',
        'petition.anonymous_name' => 'Anonym',
        'regions.oslo'            => 'Oslo',
    ]);
    $sig = ['firstname' => 'Kari', 'surname' => 'Hansen', 'region' => 'oslo', 'display' => 'anonymous'];
    $result = petitionFormatSignature($sig, $ctx);
    expect($result)->toContain('Anonym');
    expect($result)->not->toContain('Kari');
    expect($result)->not->toContain('Hansen');
});

it('HTML-escapes names in full display mode', function () {
    $ctx = mockContext([
        'petition.from_region' => 'fra',
        'regions.oslo'         => 'Oslo',
    ]);
    $sig = ['firstname' => '<b>Kari</b>', 'surname' => '<script>', 'region' => 'oslo', 'display' => 'full'];
    $result = petitionFormatSignature($sig, $ctx);
    expect($result)->toContain('&lt;b&gt;');
    expect($result)->not->toContain('<b>');
});

it('falls back to the region key when no translation exists', function () {
    $ctx = mockContext(['petition.from_region' => 'fra']);
    $sig = ['firstname' => 'Ola', 'surname' => 'Nilsen', 'region' => 'trondelag', 'display' => 'semi'];
    expect(petitionFormatSignature($sig, $ctx))->toContain('trondelag');
});
