<?php
/**
 * Zenith Cannabis — sitemap.xml, generated live on every request.
 *
 * Why this is PHP instead of a static file: the catalog (2,300+ products),
 * brand list, category list and the Journal (blog) all change through the
 * admin panel, and a hand-maintained static sitemap drifts out of sync the
 * moment anyone adds/removes a product, brand or post — which is exactly
 * what had happened here (a "merch" category and 45 products with no
 * sitemap entry, two discontinued brands still listed, several current
 * brands missing, all 10 state landing pages and all 20+ Journal posts
 * absent entirely). Generating from the same JSON files the site itself
 * reads means the sitemap can never go stale again.
 *
 * .htaccess maps this .xml file through PHP the same way it does for
 * product.html / blog-post.html; a plain request for /sitemap.xml still
 * gets a normal application/xml response, just computed on the fly.
 */
header('Content-Type: application/xml; charset=UTF-8');

$SITE = 'https://www.zenithcannabisdispensary.com';
$DATA = __DIR__ . '/data';
$today = date('Y-m-d');

function zc_read_json($path) {
    $raw = @file_get_contents($path);
    if ($raw === false) return [];
    $data = json_decode($raw, true);
    return is_array($data) ? $data : [];
}

/** XML-safe <loc> value: percent-encode the query value first (handles
 *  apostrophes/spaces/&), which also makes further XML-entity escaping
 *  unnecessary for anything produced by rawurlencode(). */
function zc_loc($path) { return htmlspecialchars($path, ENT_QUOTES | ENT_XML1, 'UTF-8'); }

function zc_url($loc, $lastmod = null, $changefreq = null, $priority = null) {
    $out = "  <url>\n    <loc>" . zc_loc($loc) . "</loc>\n";
    if ($lastmod) $out .= "    <lastmod>" . zc_loc($lastmod) . "</lastmod>\n";
    if ($changefreq) $out .= "    <changefreq>" . $changefreq . "</changefreq>\n";
    if ($priority !== null) $out .= "    <priority>" . $priority . "</priority>\n";
    $out .= "  </url>\n";
    echo $out;
}

echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";

// ---- core, hand-curated pages (low churn — priorities/frequencies are a
// deliberate editorial call, not derived from data) ----
zc_url($SITE . '/',                       '2026-08-08', 'daily',   '1.0');
zc_url($SITE . '/shop.html',              '2026-08-08', 'daily',   '0.9');
zc_url($SITE . '/deals.html',             '2026-08-08', 'daily',   '0.8');
zc_url($SITE . '/brands.html',            '2026-08-08', 'weekly',  '0.7');
zc_url($SITE . '/about.html',             '2026-08-08', 'monthly', '0.6');
zc_url($SITE . '/blog.html',              '2026-08-08', 'weekly',  '0.7');
zc_url($SITE . '/store-locator.html',     '2026-08-08', 'monthly', '0.8');
zc_url($SITE . '/faq.html',               '2026-08-08', 'monthly', '0.7');
zc_url($SITE . '/privacy.html',           '2026-08-08', 'yearly',  '0.3');
zc_url($SITE . '/terms.html',             '2026-08-08', 'yearly',  '0.3');
zc_url($SITE . '/shipping-policy.html',   '2026-08-09', 'yearly',  '0.3');
zc_url($SITE . '/rewards.html',           '2026-08-09', 'monthly', '0.6');
zc_url($SITE . '/discounts.html',         '2026-08-09', 'monthly', '0.6');
zc_url($SITE . '/medical.html',           '2026-08-09', 'monthly', '0.6');
zc_url($SITE . '/gift-cards.html',        '2026-08-09', 'monthly', '0.5');
zc_url($SITE . '/careers.html',           '2026-08-09', 'weekly',  '0.4');
zc_url($SITE . '/wholesale.html',         '2026-08-09', 'monthly', '0.4');
zc_url($SITE . '/giving-back.html',       '2026-08-09', 'monthly', '0.4');

// ---- state delivery landing pages (10 states, hardcoded — a new one is a
// deliberate content addition, not a data-driven change) ----
$states = ['california', 'colorado', 'illinois', 'michigan', 'minnesota',
           'nevada', 'new-jersey', 'new-york', 'ohio', 'virginia'];
foreach ($states as $s) {
    zc_url($SITE . '/cannabis-delivery-' . $s . '.html', $today, 'weekly', '0.8');
}

// ---- shop category landing pages — one per live category ----
foreach (zc_read_json($DATA . '/categories.json') as $c) {
    if (empty($c['slug'])) continue;
    zc_url($SITE . '/shop.html?category=' . rawurlencode($c['slug']), null, 'weekly', '0.5');
}

// ---- shop brand landing pages — one per live brand ----
$brands = zc_read_json($DATA . '/brands.json');
foreach ($brands as $b) {
    $name = is_array($b) ? ($b['name'] ?? null) : $b;
    if (!$name) continue;
    zc_url($SITE . '/shop.html?brand=' . rawurlencode($name), null, 'weekly', '0.5');
}

// ---- Journal (blog) posts ----
foreach (zc_read_json($DATA . '/blog-posts.json') as $p) {
    if (empty($p['slug'])) continue;
    zc_url($SITE . '/blog-post.html?post=' . rawurlencode($p['slug']), $p['date'] ?? $today, 'monthly', '0.6');
}

// ---- every product in the catalog ----
foreach (zc_read_json($DATA . '/products.json') as $p) {
    if (empty($p['id'])) continue;
    zc_url($SITE . '/product.html?id=' . rawurlencode($p['id']), null, 'weekly', '0.5');
}

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