<?php
/**
 * Dynamische sitemap.xml. Bevat alle vaste pagina's + recente meldingen
 * (laatste 100, want oudere worden alsnog cleanup'd).
 */
require_once __DIR__ . '/includes/bootstrap.php';

header('Content-Type: application/xml; charset=utf-8');
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";

$base = 'https://' . $CONFIG['domein'];
$today = date('Y-m-d');

/**
 * Bepaal de lastmod voor een vaste pagina:
 * - Folder met index.php → filemtime van index.php (verandert bij content-edit)
 * - Pages die feed-content tonen (home, dorp, hulpdienst) → vandaag
 * - Statische info-pages → filemtime
 */
$siteRoot = __DIR__;
function lastmod_voor(string $urlPath, string $siteRoot, string $today): string {
    $rel = trim($urlPath, '/');
    if ($rel === '') $rel = '';
    $candidates = [
        $siteRoot . '/' . $rel . '/index.php',
        $siteRoot . ($rel ? '/' . $rel : '') . '/index.php',
    ];
    foreach (array_unique($candidates) as $f) {
        if (is_file($f)) {
            return date('Y-m-d', filemtime($f));
        }
    }
    return $today;
}
// Config-driven: welke dienst-pages bestaan op deze site?
// Map dienst-code (BRA/AMB/POL/KNRM) → URL-segment (brandweer/ambulance/politie/knrm)
$_dienstSegment = ['BRA' => 'brandweer', 'AMB' => 'ambulance', 'POL' => 'politie', 'KNRM' => 'knrm'];
$_actieveDiensten = [];
foreach ($CONFIG['hulpdiensten'] as $code => $_label) {
    if ($code !== '' && isset($_dienstSegment[$code])) {
        $_actieveDiensten[] = $_dienstSegment[$code];
    }
}
$_heeftHeelRegio = !empty($CONFIG['heel_regio']);

// /gister/ + /eergister/ canonicaliseren naar /archief/{datum}/ (V1) en horen
// daarom NIET meer in de sitemap (canonical-naar-elders = tegenstrijdig signaal).
// /vandaag/ blijft self-canonical en dus wél opgenomen.
$feedPages = ['/', alles_url($CONFIG),
    '/vandaag/', '/live-kaart/',
    '/statistieken/', '/zoeken/', '/archief/', '/112-nieuws/'];
foreach ($_actieveDiensten as $d) {
    $feedPages[] = hulpdienst_url($d, $CONFIG);
}
if ($_heeftHeelRegio) {
    $feedPages[] = '/heel-' . $CONFIG['site_suffix'] . '/';
}

// Vaste pagina's
$paginas = [
    '/'                                => '1.0',
    alles_url($CONFIG)                 => '0.9',
    hulpdiensten_info_url($CONFIG)     => '0.6',
    '/live-kaart/'                     => '0.6',
    '/vandaag/'                        => '0.8',
    '/archief/'                        => '0.6',
    '/statistieken/'                   => '0.6',
    '/helikopters-' . $CONFIG['site_suffix'] . '/' => '0.7',
    '/zoeken/'                         => '0.3',
    '/112-nieuws/'                     => '0.7',
    '/informatie/'                     => '0.5',
    '/andere-regios/'                  => '0.5',
    '/over-ons/'                       => '0.5',
    '/privacy/'                        => '0.3',
    '/disclaimer/'                     => '0.3',
];
// Alleen in de sitemap zodra de shop live is (veiligheidsadvies_enabled).
if (veiligheidsadvies_enabled()) {
    $paginas['/veiligheidsadvies/'] = '0.5';
}
foreach ($_actieveDiensten as $d) {
    $paginas[hulpdienst_url($d, $CONFIG)] = '0.8';
}
if ($_heeftHeelRegio) {
    $paginas['/heel-' . $CONFIG['site_suffix'] . '/'] = '0.7';
}
foreach ($CONFIG['dorp_slugs'] as $slug => $naam) {
    $paginas['/p2000-meldingen-' . $slug . '/'] = '0.7';
    $feedPages[] = '/p2000-meldingen-' . $slug . '/';
    // Long-tail combo-pages per dienst (config-driven, geen 404's)
    foreach ($_actieveDiensten as $dienst) {
        $paginas['/p2000-meldingen-' . $slug . '-' . $dienst . '/'] = '0.6';
        $feedPages[] = '/p2000-meldingen-' . $slug . '-' . $dienst . '/';
    }
}

foreach ($paginas as $url => $prio) {
    // Feed-pagina's wijzigen iedere keer dat er een melding binnenkomt → "vandaag"
    // Statische info-pagina's: filemtime van het bestand
    $lastmod = in_array($url, $feedPages, true)
        ? $today
        : lastmod_voor($url, $siteRoot, $today);
    echo "  <url>\n";
    echo "    <loc>$base" . htmlspecialchars($url) . "</loc>\n";
    echo "    <lastmod>$lastmod</lastmod>\n";
    echo "    <priority>$prio</priority>\n";
    echo "  </url>\n";
}

// Archief-dagen: laatste 93 dagen (3 maanden retentie).
// Priority-staging: recent (≤7d) hoger want vaker bezocht/relevant,
// midden (8-30d) standaard, oud (>30d) lager, helpt crawl-budget.
for ($i = 0; $i < 93; $i++) {
    $d = date('Y-m-d', strtotime("-$i days"));
    $archiefPrio = $i <= 7 ? '0.5' : ($i <= 30 ? '0.4' : '0.3');
    echo "  <url>\n";
    echo "    <loc>$base/archief/$d/</loc>\n";
    echo "    <lastmod>$d</lastmod>\n";
    echo "    <priority>$archiefPrio</priority>\n";
    echo "  </url>\n";
}

// Long-tail per-dorp-archief: laatste 30 dagen × elke dorp-slug.
// Pattern /archief/{date}/{dorp-slug}/, router + archief/index.php handelen
// deze pretty-URLs af (canonical/title/descr al config-driven). Iets lagere
// priority dan plain date-archief omdat het long-tail is.
for ($i = 0; $i < 30; $i++) {
    $d = date('Y-m-d', strtotime("-$i days"));
    foreach ($CONFIG['dorp_slugs'] as $slug => $naam) {
        echo "  <url>\n";
        echo "    <loc>$base/archief/$d/$slug/</loc>\n";
        echo "    <lastmod>$d</lastmod>\n";
        echo "    <priority>0.35</priority>\n";
        echo "  </url>\n";
    }
}

// Statistieken — pretty-URLs (scope + periode). De kale /statistieken/ staat al
// in $paginas hierboven. Hier de long-tail: per plaats + per jaar (en per jaar
// × plaats, maar alleen waar een vastgevroren jaar-snapshot bestaat → geen
// dunne/lege pagina's in de sitemap).
foreach ($CONFIG['dorp_slugs'] as $slug => $naam) {
    echo "  <url>\n";
    echo "    <loc>$base/statistieken/$slug/</loc>\n";
    echo "    <lastmod>$today</lastmod>\n";
    echo "    <priority>0.5</priority>\n";
    echo "  </url>\n";
}
// Jaar-overzichten uit jaar_stats: per-jaar (site) + per-jaar×plaats (frozen).
$_statsJaarSite = [];
$_statsJaarPlaats = [];   // 'jaar' => ['scope_value', ...]
try {
    if (class_exists('LocalDb') && LocalDb::isConfigured()) {
        foreach (LocalDb::fetchAll("SELECT DISTINCT jaar FROM jaar_stats WHERE scope='site' ORDER BY jaar DESC") as $r) {
            $_statsJaarSite[] = (int) $r['jaar'];
        }
        foreach (LocalDb::fetchAll("SELECT jaar, scope_value FROM jaar_stats WHERE scope='plaats'") as $r) {
            $_statsJaarPlaats[(int) $r['jaar']][] = $r['scope_value'];
        }
    }
} catch (\Throwable $e) { /* geen snapshots = geen jaar-URLs */ }
$_plaatsNaarSlug = [];
foreach ($CONFIG['dorp_slugs'] as $slug => $naam) { $_plaatsNaarSlug[$naam] = $slug; }
foreach ($_statsJaarSite as $jaar) {
    echo "  <url>\n";
    echo "    <loc>$base/statistieken/$jaar/</loc>\n";
    echo "    <lastmod>$today</lastmod>\n";
    echo "    <priority>0.6</priority>\n";
    echo "  </url>\n";
    foreach ($_statsJaarPlaats[$jaar] ?? [] as $plaatsNaam) {
        $slug = $_plaatsNaarSlug[$plaatsNaam] ?? null;
        if (!$slug) continue;   // alleen plaatsen die een eigen dorp-slug hebben
        echo "  <url>\n";
        echo "    <loc>$base/statistieken/$jaar/$slug/</loc>\n";
        echo "    <lastmod>$today</lastmod>\n";
        echo "    <priority>0.45</priority>\n";
        echo "  </url>\n";
    }
}
// Jaaroverzichten (redactionele terugblik): bevroren jaren + het lopende jaar.
$_joJaren = $_statsJaarSite;
if (!in_array((int) date('Y'), $_joJaren, true)) $_joJaren[] = (int) date('Y');
foreach ($_joJaren as $jaar) {
    echo "  <url>\n";
    echo "    <loc>$base/jaaroverzicht/$jaar/</loc>\n";
    echo "    <lastmod>$today</lastmod>\n";
    echo "    <priority>0.6</priority>\n";
    echo "  </url>\n";
}
// Detail-pagina's: laatste 200 feed-entries (nieuws-berichten + solo's).
// Bundle-status: alleen bundels met is_nieuws=1 krijgen /112-nieuws/{slug}/-URL.
// Niet-news bundels worden in sitemap als losse meldingen behandeld (priority 0.5).
// Plus: als site nieuws-pagina's uit heeft staan, NIETS naar /112-nieuws/-URLs sturen.
$_nieuwsPagesOn = nieuws_pages_enabled();
$resp = $API->meldingen([], 200);
$seenIncidents = [];
foreach ($resp['meldingen'] ?? [] as $m) {
    $datum = substr($m['pubdate'], 0, 10);
    $isNieuwsBundle = $_nieuwsPagesOn
        && !empty($m['nieuws']['slug'])
        && (int) ($m['nieuws']['is_nieuws'] ?? 0) === 1;
    if ($isNieuwsBundle) {
        if (isset($seenIncidents[$m['nieuws']['slug']])) continue;
        $seenIncidents[$m['nieuws']['slug']] = true;
    }
    echo "  <url>\n";
    echo "    <loc>$base" . htmlspecialchars(melding_url($m), ENT_XML1) . "</loc>\n";
    echo "    <lastmod>$datum</lastmod>\n";
    // Priority: groot-gemarkeerde nieuws-berichten (is_groot=1) 0.7 (echt nieuws),
    // gewone nieuws-bundels 0.65, solo meldingen 0.5.
    $isGroot = $isNieuwsBundle && !empty($m['nieuws']['is_groot']);
    echo "    <priority>" . ($isGroot ? '0.7' : ($isNieuwsBundle ? '0.65' : '0.5')) . "</priority>\n";
    echo "  </url>\n";
}

// Losse nieuws-berichten van laatste 30 dagen, vangt bundels op die niet in de
// detail-200 hierboven zaten (oudere voorvallen waarvan de meldingen al uit de
// recent-feed zijn gerold). Direct DB-fetch zoals de hub zelf ook doet.
// is_nieuws = 1 spiegelt de hub-filter — niet-news bundels niet in sitemap.
// Skip volledig als site nieuws-pagina's uit heeft staan.
$_nieuwsRijen = [];
if ($_nieuwsPagesOn) {
    require_once __DIR__ . '/../api/src/Db.php';
    $_apiCfg = require __DIR__ . '/../api/config/config.php';
    \P2000\Api\Db::init($_apiCfg['db']);
    // Anker op MAX(laatste_pubdate) per site ipv NOW(), klok-onafhankelijk.
    $_nieuwsRijen = \P2000\Api\Db::fetchAll(
        "SELECT slug, laatste_pubdate FROM nieuws
         WHERE site_slug = ? AND is_nieuws = 1
           AND laatste_pubdate > (SELECT COALESCE(MAX(laatste_pubdate), NOW()) FROM nieuws WHERE site_slug = ?) - INTERVAL 30 DAY
         ORDER BY laatste_pubdate DESC LIMIT 200",
        [$CONFIG['site_slug'], $CONFIG['site_slug']]
    );
}
foreach ($_nieuwsRijen as $n) {
    if (isset($seenIncidents[$n['slug']])) continue;
    $seenIncidents[$n['slug']] = true;
    $datum = substr($n['laatste_pubdate'], 0, 10);
    echo "  <url>\n";
    echo "    <loc>$base/112-nieuws/" . htmlspecialchars($n['slug'], ENT_XML1) . "/</loc>\n";
    echo "    <lastmod>$datum</lastmod>\n";
    echo "    <priority>0.65</priority>\n";
    echo "  </url>\n";
}

// Helikoptervluchten, alleen voltooide (live = noindex zoals op detail-pagina).
// Cap op 200 recente voltooide vluchten met relevantie voor deze site, of
// melding-gekoppeld. Heli's groeien snel; cap voorkomt sitemap-explosie.
// Zelfde echte-vlucht-criteria als Api::ECHTE_VLUCHT_SQL (detail-endpoint):
// zonder dit stonden er vlucht-URLs in de sitemap die op de detail-pagina
// 404 geven (ghost-/gefilterde vluchten) — slecht indexeringssignaal.
$_heliRijen = \P2000\Api\Db::fetchAll(
    "SELECT id, eind_tijd, laatst_geupdate FROM helikoptervluchten
     WHERE phase = 'voltooid'
       AND FIND_IN_SET(?, relevante_sites)
       AND (aantal_punten >= 3
            AND (afstand_km > 0.5 OR max_hoogte > 50 OR max_snelheid > 30)
            AND (heli_type != 'lifeliner' OR melding_id IS NOT NULL))
     ORDER BY eind_tijd DESC LIMIT 200",
    [$CONFIG['site_slug']]
);
foreach ($_heliRijen as $h) {
    $datum = substr($h['eind_tijd'] ?: $h['laatst_geupdate'], 0, 10);
    echo "  <url>\n";
    echo "    <loc>$base/helikoptervlucht/" . (int) $h['id'] . "/</loc>\n";
    echo "    <lastmod>$datum</lastmod>\n";
    echo "    <priority>0.55</priority>\n";
    echo "  </url>\n";
}

echo '</urlset>' . "\n";
