<?php

// newsletter-signup.php calls session_start() at load time — pre-initialise
// $_SESSION so the guard fires correctly without emitting headers.
$_SESSION = [];
$_SERVER['REMOTE_ADDR'] ??= '127.0.0.1';
$_SERVER['HTTP_HOST']   ??= 'localhost';

require_once CUSTOM_DIR . '/plugins/page/newsletter-signup.php';

// --- newsletterT ---

it('returns the fallback value when no global context is present', function () {
    unset($GLOBALS['ctx']);
    expect(newsletterT('name_label'))->toBe('Navn');
    expect(newsletterT('submit_button'))->toBe('Meld deg på');
    expect(newsletterT('success_message'))->toBe('Sjekk innboksen din!');
});

it('returns the key itself for an unknown key when no context is present', function () {
    unset($GLOBALS['ctx']);
    expect(newsletterT('nonexistent_key'))->toBe('nonexistent_key');
});

it('returns a translation from context when available', function () {
    $GLOBALS['ctx'] = new class {
        public function get(string $key, mixed $default = null): mixed
        {
            return $key === 'translations'
                ? ['newsletter.name_label' => 'Name']
                : $default;
        }
    };
    expect(newsletterT('name_label'))->toBe('Name');
    unset($GLOBALS['ctx']);
});

it('falls back to the key when context has no matching translation', function () {
    $GLOBALS['ctx'] = new class {
        public function get(string $key, mixed $default = null): mixed
        {
            return $key === 'translations' ? [] : $default;
        }
    };
    expect(newsletterT('name_label'))->toBe('name_label');
    unset($GLOBALS['ctx']);
});

// --- newsletterCheckRateLimit ---

it('returns true when no previous submission is recorded in the session', function () {
    unset($_SESSION['newsletter_last_submit']);
    expect(newsletterCheckRateLimit())->toBeTrue();
});

it('returns false immediately after a submission', function () {
    $_SESSION['newsletter_last_submit'] = time();
    expect(newsletterCheckRateLimit())->toBeFalse();
});

it('returns false when 29 seconds have elapsed', function () {
    $_SESSION['newsletter_last_submit'] = time() - 29;
    expect(newsletterCheckRateLimit())->toBeFalse();
});

it('returns true when exactly 30 seconds have elapsed', function () {
    $_SESSION['newsletter_last_submit'] = time() - 30;
    expect(newsletterCheckRateLimit())->toBeTrue();
});

it('returns true when more than 30 seconds have elapsed', function () {
    $_SESSION['newsletter_last_submit'] = time() - 60;
    expect(newsletterCheckRateLimit())->toBeTrue();
});

// --- newsletterGetTranslations ---

it('returns all expected translation keys', function () {
    unset($GLOBALS['ctx']);
    expect(newsletterGetTranslations())->toHaveKeys([
        'nameLabel', 'namePlaceholder', 'emailLabel', 'emailPlaceholder',
        'notice', 'submitButton', 'successMessage', 'successConfirm', 'errorMessage',
    ]);
});

it('HTML-escapes special characters in translation values', function () {
    $GLOBALS['ctx'] = new class {
        public function get(string $key, mixed $default = null): mixed
        {
            return $key === 'translations'
                ? ['newsletter.name_label' => '<b>Name & "Label"</b>']
                : $default;
        }
    };
    $translations = newsletterGetTranslations();
    expect($translations['nameLabel'])->toBe('&lt;b&gt;Name &amp; &quot;Label&quot;&lt;/b&gt;');
    unset($GLOBALS['ctx']);
});

it('returns string values for all keys', function () {
    unset($GLOBALS['ctx']);
    foreach (newsletterGetTranslations() as $key => $value) {
        expect($value)->toBeString("Key '{$key}' should be a string");
    }
});
