#!/usr/bin/env php
<?php
/**
 * Mock petition data generator — DEV ONLY.
 *
 * Generates realistic-looking confirmed petition signatures for testing
 * the map widget. Writes directly to the real CSV (dev environment only).
 *
 * Run from host:
 *   podman exec stopplidelsen.no php /var/www/custom/tools/generate-mock-petitions.php
 */

// Safety check: refuse to run outside the dev container
$inContainer = file_exists('/var/www/html') && file_exists('/var/www/custom');
if (!$inContainer && !in_array('--force', $argv)) {
    echo "Warning: this script is intended to run inside the dev container.\n";
    echo "  podman exec stopplidelsen.no php /var/www/custom/tools/generate-mock-petitions.php\n";
    echo "  Pass --force to run anyway.\n";
    exit(1);
}

$csvPath = '/var/www/custom/data/petitions/medisinsk-cannabis-pa-resept.csv';

// ------- Name lists -------

$firstNames = [
    'Kari', 'Ola', 'Anne', 'Per', 'Ingrid', 'Lars', 'Kristin', 'Erik',
    'Marianne', 'Tor', 'Hanne', 'Bjørn', 'Silje', 'Trond', 'Nina', 'Morten',
    'Lene', 'Håkon', 'Anita', 'Svein', 'Marit', 'Gunnar', 'Tonje', 'Rune',
    'Bente', 'Terje', 'Camilla', 'Geir', 'Astrid', 'Jon', 'Trine', 'Anders',
    'Heidi', 'Vegard', 'Siri', 'Frode', 'Marte', 'Steinar', 'Lise', 'Øyvind',
    'Karianne', 'Petter', 'Tone', 'Kenneth', 'Gro', 'Vidar', 'Line', 'Eivind',
    'Maria', 'Jonas', 'Ida', 'Martin', 'Katrine', 'Fredrik', 'Kirsten', 'Helge',
    'Turid', 'Ole', 'Berit', 'Arild', 'Wendy', 'Ragnar', 'Stine', 'Ivar',
    'Åse', 'Knut', 'Elise', 'Harald', 'Solveig', 'Dag', 'Kristine', 'Leif',
    'Elin', 'Nils', 'Mia', 'Eirik', 'Randi', 'Sigurd', 'Thea', 'Magnus',
];

$surnames = [
    'Hansen', 'Johansen', 'Olsen', 'Larsen', 'Andersen', 'Pedersen', 'Nilsen',
    'Kristiansen', 'Jensen', 'Karlsen', 'Johnsen', 'Pettersen', 'Eriksen',
    'Berg', 'Haugen', 'Hagen', 'Johannessen', 'Bakke', 'Strand', 'Lie',
    'Halvorsen', 'Solberg', 'Lund', 'Dahl', 'Moen', 'Sørensen', 'Bøe',
    'Berge', 'Aas', 'Holm', 'Martinsen', 'Paulsen', 'Jakobsen', 'Stensrud',
    'Nygaard', 'Christoffersen', 'Amundsen', 'Svendsen', 'Lunde', 'Sæther',
    'Eide', 'Henriksen', 'Myhre', 'Fjeld', 'Vik', 'Thorsen', 'Bakken',
    'Aasen', 'Mathisen', 'Elstad', 'Vold', 'Lindqvist', 'Torp', 'Nesse',
    'Ruud', 'Brekke', 'Midtbø', 'Grøtting', 'Kleven', 'Hauge', 'Skogen',
];

$regions = [
    'agder', 'akershus', 'buskerud', 'finnmark', 'innlandet',
    'more_og_romsdal', 'nordland', 'oslo', 'rogaland', 'telemark',
    'troms', 'trondelag', 'vestfold', 'vestland', 'ostfold',
];

$displayOptions = ['semi', 'semi', 'semi', 'full', 'anonymous']; // weighted

// ------- Prompt helpers -------

function prompt(string $question, string $default = ''): string {
    echo $question;
    if ($default !== '') echo " [$default]";
    echo ': ';
    $line = trim(fgets(STDIN));
    return $line === '' ? $default : $line;
}

function promptInt(string $question, int $default, int $min = 1, int $max = PHP_INT_MAX): int {
    while (true) {
        $val = (int)prompt($question, (string)$default);
        if ($val >= $min && $val <= $max) return $val;
        echo "  Please enter a number between $min and $max.\n";
    }
}

function promptFloat(string $question, float $default, float $min = 0.0, float $max = 1.0): float {
    while (true) {
        $val = (float)prompt($question, (string)$default);
        if ($val >= $min && $val <= $max) return $val;
        echo "  Please enter a number between $min and $max.\n";
    }
}

// ------- Distribution helpers -------

/**
 * Generate a biased region distribution.
 *
 * @param int   $n         Total signatures to distribute
 * @param float $variance  0.0 = perfectly even, 1.0 = highly concentrated (Oslo-heavy)
 * @return array           [region => count]
 */
function generateRegionDistribution(int $n, float $variance, array $regions): array {
    // Base weights (approx. Norwegian population distribution, normalized)
    $baseWeights = [
        'oslo'           => 12.0,
        'akershus'       => 11.5,
        'vestland'       => 9.0,
        'rogaland'       => 8.0,
        'trondelag'      => 7.5,
        'innlandet'      => 5.5,
        'buskerud'       => 5.0,
        'vestfold'       => 4.5,
        'ostfold'        => 4.5,
        'more_og_romsdal'=> 4.5,
        'agder'          => 4.0,
        'telemark'       => 3.5,
        'nordland'       => 4.0,
        'troms'          => 3.5,
        'finnmark'       => 1.5,
    ];

    // Blend between uniform (variance=0) and biased (variance=1)
    $uniform = 1.0 / count($regions);
    $total = array_sum($baseWeights);
    $weights = [];

    foreach ($regions as $r) {
        $biased = ($baseWeights[$r] ?? 1.0) / $total;
        $weights[$r] = (1 - $variance) * $uniform + $variance * $biased;
    }

    // Normalise
    $wsum = array_sum($weights);
    foreach ($weights as &$w) $w /= $wsum;

    // Allocate counts
    $counts = [];
    $remaining = $n;
    $keys = array_keys($weights);

    foreach ($keys as $i => $r) {
        if ($i === count($keys) - 1) {
            $counts[$r] = $remaining;
        } else {
            $c = (int)round($n * $weights[$r]);
            $counts[$r] = $c;
            $remaining -= $c;
        }
    }

    return $counts;
}

// ------- CSV writer -------

function appendSignature(string $csvPath, array $data): void {
    $fp = fopen($csvPath, 'a');
    if (!$fp) {
        echo "ERROR: Cannot open $csvPath\n";
        exit(1);
    }
    fputcsv($fp, $data, ',', '"', '');
    fclose($fp);
}

function initCsv(string $csvPath): void {
    $fp = fopen($csvPath, 'w');
    if (!$fp) {
        echo "ERROR: Cannot create $csvPath\n";
        exit(1);
    }
    fputcsv($fp, ['timestamp', 'email', 'firstname', 'surname', 'region', 'display', 'status', 'token', 'token_created', 'ip_hash'], ',', '"', '');
    fclose($fp);
}

// ------- Main -------

echo "\n";
echo "╔══════════════════════════════════════════════╗\n";
echo "║   Mock Petition Data Generator — DEV ONLY   ║\n";
echo "╚══════════════════════════════════════════════╝\n\n";

$existingCount = 0;
if (file_exists($csvPath)) {
    $fp = fopen($csvPath, 'r');
    fgetcsv($fp, null, ',', '"', ''); // skip header
    while (fgetcsv($fp, null, ',', '"', '')) $existingCount++;
    fclose($fp);
    echo "  Current CSV: $csvPath\n";
    echo "  Existing rows: $existingCount\n\n";
} else {
    echo "  CSV does not exist yet, will create it.\n\n";
}

$action = prompt("  Action — [a]ppend or [r]eplace (wipes existing data)", 'a');
$replace = strtolower($action[0] ?? 'a') === 'r';

if ($replace && $existingCount > 0) {
    $confirm = prompt("  ⚠️  This will delete $existingCount existing rows. Type 'yes' to confirm", '');
    if (strtolower($confirm) !== 'yes') {
        echo "  Aborted.\n";
        exit(0);
    }
}

echo "\n";
$count = promptInt("  How many mock petitioners to generate", 1000, 1, 100000);

echo "\n  Regional distribution:\n";
echo "    0.0 = perfectly even across all fylker\n";
echo "    1.0 = highly concentrated (Oslo/Akershus heavy, matches real population)\n";
$variance = promptFloat("  Variance (0.0 – 1.0)", 0.7, 0.0, 1.0);

echo "\n";

// Generate distribution
$dist = generateRegionDistribution($count, $variance, $regions);

echo "  Distribution preview:\n";
arsort($dist);
foreach ($dist as $r => $c) {
    $bar = str_repeat('█', (int)round($c / $count * 40));
    printf("    %-20s %4d  %s\n", $r, $c, $bar);
}
echo "\n";

$go = prompt("  Generate $count signatures? [y/n]", 'y');
if (strtolower($go[0] ?? 'n') !== 'y') {
    echo "  Aborted.\n";
    exit(0);
}

// Prepare CSV
if ($replace || !file_exists($csvPath)) {
    initCsv($csvPath);
}

// Generate signatures
$fp = fopen($csvPath, 'a');
if (!$fp) {
    echo "ERROR: Cannot open $csvPath for writing\n";
    exit(1);
}

$now = time();
$generated = 0;
$usedEmails = [];

foreach ($dist as $region => $regionCount) {
    for ($i = 0; $i < $regionCount; $i++) {
        $firstname = $GLOBALS['firstNames'][array_rand($GLOBALS['firstNames'])];
        $surname   = $GLOBALS['surnames'][array_rand($GLOBALS['surnames'])];
        $display   = $GLOBALS['displayOptions'][array_rand($GLOBALS['displayOptions'])];

        // Unique-ish email
        $slug = strtolower($firstname . '.' . $surname . '.' . $generated);
        $email = $slug . '@mock.test';

        // Timestamp spread over last 60 days
        $timestamp = $now - random_int(0, 60 * 86400);
        $token = bin2hex(random_bytes(32));
        $ipHash = bin2hex(random_bytes(32));

        fputcsv($fp, [
            $timestamp,
            $email,
            $firstname,
            $surname,
            $region,
            $display,
            'confirmed',   // all mock sigs are confirmed
            $token,
            $timestamp,
            $ipHash,
        ], ',', '"', '');

        $generated++;
    }
}

fclose($fp);

echo "\n  ✓ Generated $generated mock signatures.\n";
echo "  ✓ Written to: $csvPath\n\n";

// Invalidate map cache (both private cache and public static file)
foreach ([
    '/var/www/custom/data/petition-map-cache.json',
    '/var/www/custom/assets/petition-map-data.json',
] as $cacheFile) {
    if (file_exists($cacheFile)) {
        unlink($cacheFile);
        echo "  ✓ Cleared: $cacheFile\n";
    }
}

echo "\n";
