<?php
// Every other public entry point defines BASE_DIR before pulling in the shared
// includes. These did not, which is the only reason header.php, footer.php and
// seo.php could not carry the direct-access guard that every other include in
// this system has. Added here so they can.
if (!defined('BASE_DIR')) define('BASE_DIR', __DIR__ . '/');

// ============================================================
// SYNC= — SITEMAP.XML GENERATOR
// Aliased to /sitemap.xml via .htaccess (same trick as index.php -> /).
// Rebuilt from the live JSON files on every request, so it can never drift
// out of date the way a hand-maintained static sitemap would.
// ============================================================
require_once __DIR__ . '/seo.php';
require_once __DIR__ . '/routes.php';

header('Content-Type: application/xml; charset=UTF-8');

$urls = []; // path (no leading slash) => ['priority' => x, 'changefreq' => y]

function sitemap_add(&$urls, $path, $priority = '0.5', $changefreq = 'weekly') {
    $path = ltrim($path, '/');
    if (!isset($urls[$path])) $urls[$path] = ['priority' => $priority, 'changefreq' => $changefreq];
}

// ---- Core pages ----
sitemap_add($urls, '/', '1.0', 'weekly');
$core = [
    'about.php'          => '0.6',
    'brands.php'          => '0.6',
    'clearance.php'       => '0.7',
    'sale-catalogue.php'  => '0.7',
    'stock.php'           => '0.6',
    'stock-catalogue.php' => '0.6',
    // Not listed: catalogue.php (it only ever forwards to the homepage),
    // enquiry.php (a form handler, not a page), gdpr.php (refuses a visit), and
    // privacy.php / terms.php, which ask Google not to index them.
];
foreach ($core as $file => $priority) {
    if (file_exists(__DIR__ . '/' . $file)) sitemap_add($urls, $file, $priority);
}

// ---- Category landing + catalogue pairs ----
foreach (['accent', 'bedroom', 'dining', 'flooring', 'livingroom', 'misc'] as $cat) {
    if (file_exists(__DIR__ . "/{$cat}.php"))           sitemap_add($urls, "{$cat}.php", '0.8');
    if (file_exists(__DIR__ . "/{$cat}-catalogue.php"))  sitemap_add($urls, "{$cat}-catalogue.php", '0.8');
}

// ---- CMS pages from pages.json — covers the builtin category pages above
// again (harmless, sitemap_add dedupes) plus any custom page the admin adds
// through the page editor, without this file needing to know about it.
$pages_file = __DIR__ . '/pages.json';
$pages = file_exists($pages_file) ? (json_decode(file_get_contents($pages_file), true) ?: []) : [];
foreach ($pages as $p) {
    if (empty($p['active']) || !empty($p['noindex'])) continue;
    $slug = $p['slug'] ?? '';
    // index.php is the homepage under its raw filename — already covered by
    // '/' above, and .htaccess 301s /index.php to / anyway, so adding it here
    // would just put a redirecting URL in the sitemap alongside the real one.
    if ($slug === 'index.php') continue;
    if ($slug && substr($slug, -4) === '.php') {
        if (file_exists(__DIR__ . '/' . $slug)) sitemap_add($urls, $slug, '0.7');
    } elseif ($slug !== '' && file_exists(__DIR__ . '/' . strtok($slug, '?'))) {
        // A page added in the admin gets the slug
        // "page-catalogue.php?page=<id>", which does not END in .php, so it
        // used to fall past this and get published as "page.php?id=<id>" --
        // an address that 302s to the homepage. The navigation always
        // linked to the slug; only the sitemap disagreed.
        sitemap_add($urls, $slug, '0.7');
    } elseif (!empty($p['id'])) {
        sitemap_add($urls, 'page.php?id=' . urlencode($p['id']), '0.6');
    }
}

$sup_file  = __DIR__ . '/suppliers.json';
$prod_file = __DIR__ . '/products.json';
$suppliers = file_exists($sup_file)  ? (json_decode(file_get_contents($sup_file), true) ?: [])  : [];
$products  = file_exists($prod_file) ? (json_decode(file_get_contents($prod_file), true) ?: []) : [];

// ---- Individual product pages — one per active product ----
// Visible means `active` is not false — absent counts as visible, exactly as
// every other page reads it. empty() here left out any product without the key.
foreach ($products as $p) {
    if (!is_array($p) || !($p['active'] ?? true) || empty($p['id'])) continue;
    sitemap_add($urls, 'product.php?id=' . urlencode($p['id']), '0.6', 'weekly');
}

// ---- Brand pages — one per brand a customer may see, with a visible product ----
// This listed a page for every supplier with a live product, trade accounts
// and all, while brand.php now only opens for brands ticked "Show on Our
// Brands page". See public-brand.php.
require_once BASE_DIR . 'public-brand.php';
$active_supplier_ids = array_unique(array_filter(array_column(
    array_filter($products, fn($p) => is_array($p) && ($p['active'] ?? true)),
    'supplier_id'
)));
foreach ($suppliers as $s) {
    if (!public_brand_supplier($s) || empty($s['id'])) continue;
    if (!in_array($s['id'], $active_supplier_ids, true)) continue;
    sitemap_add($urls, 'brand.php?s=' . urlencode($s['id']), '0.5', 'monthly');
}

// ---- The bed builder: its three pages and a page per bed ----
// Only while it is switched on (and prices are shown), and only the beds the
// shop has not hidden — exactly what bed-builder.php lets the pages show.
require_once BASE_DIR . 'theme.php';        // prices_shown(): no beds listed while prices are off
require_once BASE_DIR . 'bed-builder.php';
if (function_exists('bb_enabled') && bb_enabled()) {
    foreach (array_keys(bb_hubs()) as $bb_k) {
        $bb_h = bb_hub_text($bb_k);
        if ($bb_h['on']) sitemap_add($urls, $bb_h['slug'], '0.8', 'weekly');
    }
    // Only beds the lists show (bed-builder.php): one that isn't listed keeps
    // its page for old links, out of Google.
    foreach (bb_catalogue()['models'] as $bb_m) if (!empty($bb_m['listed'])) sitemap_add($urls, $bb_m['slug'], '0.6', 'weekly');
}

// ---- Sofas and recliners: a page per range the lists show ----
// The two lists themselves (/recliner-chairs, /living-room-furniture) are the
// site's own pages and are listed with them; a range off the lists keeps its
// page for old links, out of Google, as the beds.
require_once BASE_DIR . 'seat-listings.php';
if (seat_enabled()) {
    foreach (array_keys(seat_hubs()) as $st_k) { $st_h = seat_hub_text($st_k); if ($st_h['on']) sitemap_add($urls, $st_h['slug'], '0.8', 'weekly'); }
    foreach (seat_catalogue()['models'] as $st_m) if (!empty($st_m['listed'])) sitemap_add($urls, $st_m['slug'], '0.6', 'weekly');
}

// ---- Output ----
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
foreach ($urls as $path => $meta) {
    // seo_abs('') returns '' (empty paths are treated as falsy there), so the
    // homepage — stored under the empty-string key — needs handling here
    // instead of going through seo_abs() like every other entry.
    // Every address as its short one (routes.php): /living-room, /bliss-3-seater-sofa.
    $abs = $path === '' ? seo_base_url() . '/' : seo_abs(ltrim(site_url('/' . ltrim($path, '/')), '/'));
    $loc = htmlspecialchars($abs, ENT_XML1 | ENT_QUOTES, 'UTF-8');
    echo "  <url>\n";
    echo "    <loc>{$loc}</loc>\n";
    echo "    <changefreq>{$meta['changefreq']}</changefreq>\n";
    echo "    <priority>{$meta['priority']}</priority>\n";
    echo "  </url>\n";
}
echo '</urlset>' . "\n";
