<?php

// petition-map.php defines cache-path constants and functions.
// petitionMapBuildData() takes an explicit $csvPath so it can be tested
// with temp files; the cache constants are not touched by these tests.
//
// Context is already stubbed in PetitionFormTest.php (loaded first alphabetically),
// so we do not redeclare it here.
require_once CUSTOM_DIR . '/plugins/page/petition-map.php';

// CSV header row shared across tests
const PETITION_MAP_CSV_HEADER = ['timestamp', 'email', 'firstname', 'surname', 'region', 'display', 'status', 'token', 'token_created', 'ip_hash'];

/**
 * Write rows to a temp file and return its path.
 * The caller is responsible for unlinking it.
 */
function mapTestCsv(array $rows): string
{
    $path = tempnam(sys_get_temp_dir(), 'map_test_');
    $fp = fopen($path, 'w');
    foreach ($rows as $row) {
        fputcsv($fp, $row, ',', '"', '');
    }
    fclose($fp);
    return $path;
}

// --- petitionMapBuildData: missing / empty file ---

it('returns empty data when CSV does not exist', function () {
    $result = petitionMapBuildData('/tmp/nonexistent-petition-map-test.csv');
    expect($result['total'])->toBe(0);
    expect($result)->toHaveKey('generated');
});

it('returns zero total for a CSV with only pending signatures', function () {
    $path = mapTestCsv([
        PETITION_MAP_CSV_HEADER,
        [time(), 'a@b.com', 'Ola', 'Hansen', 'oslo', 'semi', 'pending', 'tok1', time(), 'hash1'],
    ]);
    expect(petitionMapBuildData($path)['total'])->toBe(0);
    unlink($path);
});

it('returns zero total for a CSV with only the header', function () {
    $path = mapTestCsv([PETITION_MAP_CSV_HEADER]);
    expect(petitionMapBuildData($path)['total'])->toBe(0);
    unlink($path);
});

// --- petitionMapBuildData: counting confirmed signatures ---

it('counts confirmed signatures and groups them by region', function () {
    $path = mapTestCsv([
        PETITION_MAP_CSV_HEADER,
        [time(), 'a@b.com', 'Kari', 'Hansen', 'oslo',   'semi', 'confirmed', 't1', time(), 'h1'],
        [time(), 'b@b.com', 'Ola',  'Nilsen', 'oslo',   'semi', 'confirmed', 't2', time(), 'h2'],
        [time(), 'c@b.com', 'Per',  'Olsen',  'bergen', 'semi', 'confirmed', 't3', time(), 'h3'],
    ]);
    $result = petitionMapBuildData($path);
    expect($result['total'])->toBe(3);
    expect($result['regions']['oslo']['count'])->toBe(2);
    expect($result['regions']['bergen']['count'])->toBe(1);
    unlink($path);
});

it('ignores non-confirmed rows (pending, deleted, etc.)', function () {
    $path = mapTestCsv([
        PETITION_MAP_CSV_HEADER,
        [time(), 'a@b.com', 'Kari', 'Hansen', 'oslo', 'semi', 'confirmed', 't1', time(), 'h1'],
        [time(), 'b@b.com', 'Ola',  'Nilsen', 'oslo', 'semi', 'pending',   't2', time(), 'h2'],
        [time(), 'c@b.com', 'Per',  'Olsen',  'oslo', 'semi', 'deleted',   't3', time(), 'h3'],
    ]);
    $result = petitionMapBuildData($path);
    expect($result['total'])->toBe(1);
    unlink($path);
});

it('skips confirmed entries that have no region', function () {
    $path = mapTestCsv([
        PETITION_MAP_CSV_HEADER,
        [time(), 'a@b.com', 'Kari', 'Hansen', '', 'semi', 'confirmed', 't1', time(), 'h1'],
    ]);
    expect(petitionMapBuildData($path)['total'])->toBe(0);
    unlink($path);
});

// --- petitionMapBuildData: name handling ---

it('uses only the first word of the firstname', function () {
    $path = mapTestCsv([
        PETITION_MAP_CSV_HEADER,
        [time(), 'a@b.com', 'Kari Marte', 'Hansen', 'oslo', 'semi', 'confirmed', 't1', time(), 'h1'],
    ]);
    $signer = petitionMapBuildData($path)['regions']['oslo']['signers'][0];
    expect($signer['n'])->toBe('Kari');
    unlink($path);
});

it('sets name to null and anonymous flag true for anonymous display', function () {
    $path = mapTestCsv([
        PETITION_MAP_CSV_HEADER,
        [time(), 'a@b.com', 'Kari', 'Hansen', 'oslo', 'anonymous', 'confirmed', 't1', time(), 'h1'],
    ]);
    $signer = petitionMapBuildData($path)['regions']['oslo']['signers'][0];
    expect($signer['n'])->toBeNull();
    expect($signer['a'])->toBeTrue();
    unlink($path);
});

it('sets anonymous flag false for non-anonymous display', function () {
    $path = mapTestCsv([
        PETITION_MAP_CSV_HEADER,
        [time(), 'a@b.com', 'Lars', 'Berg', 'oslo', 'semi', 'confirmed', 't1', time(), 'h1'],
    ]);
    $signer = petitionMapBuildData($path)['regions']['oslo']['signers'][0];
    expect($signer['a'])->toBeFalse();
    unlink($path);
});

it('does not include emails, surnames, tokens, or ip_hashes in the output', function () {
    $path = mapTestCsv([
        PETITION_MAP_CSV_HEADER,
        [time(), 'secret@b.com', 'Lars', 'SecretSurname', 'oslo', 'semi', 'confirmed', 'secret-token', time(), 'secret-hash'],
    ]);
    $result = petitionMapBuildData($path);
    $json = json_encode($result);
    expect($json)->not->toContain('secret@b.com');
    expect($json)->not->toContain('SecretSurname');
    expect($json)->not->toContain('secret-token');
    expect($json)->not->toContain('secret-hash');
    unlink($path);
});
