<?php
/* ============================================================================
   WBMCZ — MIGRATION · ONE PAGE PER CATEGORY  (06 Sep 2026)

   Run this once in a browser after uploading, then DELETE IT.

       https://wbmcz.online/productsplitmigration.php

   It does four things, all of them safe to run more than once:

     1  checks the new files actually arrived
     2  writes the per-category pages (product_*.php and service_*.php)
     3  gives every category a category_key, if one is missing, because the
        file names and permission keys are built from it
     4  reports what the three new Activity & Task desks can see

   NOTHING IS DELETED and no column is dropped. The only writes are the new
   page files and, where one is missing, a category_key.
   ============================================================================ */

require_once __DIR__ . '/config.php';
require_once __DIR__ . '/db.php';

$ADMIN = __DIR__ . '/admin';
$rows  = [];
function say(&$rows, $ok, $what, $detail = '') { $rows[] = [$ok, $what, $detail]; }

/* ------------------------------------------------------------------ 1. files */
$need = [
    'includes/product_pages.php'                 => 'names the per-category pages',
    'includes/pipeline.php'                      => 'the three new desks live here',
    'includes/acl.php'                           => 'the per-category permission keys',
    'admin/includes/product_engine.php'          => 'the catalogue screen, shared by every category page',
    'admin/includes/pending_services_engine.php' => 'the submission screen, shared the same way',
    'admin/includes/sidebar.php'                 => 'the menu that lists the categories',
    'admin/service_import.php'                   => 'the bulk upload, now locked to the page that started it',
    'admin/services.php'                         => 'writes a new category its pages',
];
$missing = 0;
foreach ($need as $f => $why) {
    $there = is_file(__DIR__ . '/' . $f);
    if (!$there) { $missing++; }
    say($rows, $there, $f, $there ? $why : 'NOT UPLOADED — ' . $why);
}

$fnOk = false;
if ($missing === 0) {
    require_once __DIR__ . '/includes/product_pages.php';
    $fnOk = function_exists('pmp_sync');
    say($rows, $fnOk, 'pmp_sync() is available', $fnOk ? '' : 'includes/product_pages.php is the old copy — upload it again');
}

/* ------------------------------------------------ 2. every category has a key */
$fixedKeys = [];
if ($missing === 0) {
    try {
        foreach ($db->select("SELECT id, category_key, title FROM service_categories") as $c) {
            if (trim((string)$c['category_key']) !== '') { continue; }
            $slug = strtolower(html_entity_decode((string)$c['title'], ENT_QUOTES, 'UTF-8'));
            $slug = trim((string)preg_replace('/[^a-z0-9]+/', '_', $slug), '_');
            if ($slug === '') { $slug = 'cat' . (int)$c['id']; }
            $db->insert("UPDATE service_categories SET category_key = ? WHERE id = ?", ['cat_' . $slug, (int)$c['id']]);
            $fixedKeys[] = $c['title'] . ' → cat_' . $slug;
        }
        say($rows, true, 'Every category has a key',
            $fixedKeys ? 'filled in: ' . implode(', ', $fixedKeys) : 'nothing needed filling in');
    } catch (\Throwable $e) {
        say($rows, false, 'Category keys', $e->getMessage());
    }
}

/* ---------------------------------------------------------- 3. the page files */
$sync = ['made' => [], 'kept' => [], 'failed' => []];
if ($fnOk) {
    $sync = pmp_sync($db, $ADMIN);
    say($rows, empty($sync['failed']), 'Per-category pages',
        count($sync['made']) . ' written, ' . count($sync['kept']) . ' already there'
        . (empty($sync['failed']) ? '' : ', COULD NOT WRITE: ' . implode(', ', $sync['failed'])
            . ' — make the admin folder writable and run this again'));
}

/* ------------------------------------------------------- 4. the new desks */
$desk = [];
if ($missing === 0) {
    require_once __DIR__ . '/includes/pipeline.php';
    if (function_exists('pipe_desks')) {
        $all = pipe_desks();
        foreach (['visit_collect' => 'Visit Collection', 'verify_collect' => 'Verify Collection', 'seller_dues' => 'Seller Dues'] as $k => $label) {
            if (!isset($all[$k])) { say($rows, false, "Desk: $label", 'missing — includes/pipeline.php is the old copy'); continue; }
            $n = '?';
            try { $n = (int)call_user_func($all[$k]['count'], $db, ''); } catch (\Throwable $e) { $n = 'error: ' . $e->getMessage(); }
            say($rows, is_int($n), "Desk: $label", is_int($n) ? "$n waiting right now" : (string)$n);
            $desk[$k] = $n;
        }
    }
}

/* -------------------------------------------------------- 5. permission keys */
$newKeys = [];
if ($missing === 0) {
    require_once __DIR__ . '/includes/acl.php';
    if (function_exists('acl_modules')) {
        $m = acl_modules();
        foreach (array_keys($m['products']['actions'] ?? []) as $a) {
            if (strpos($a, 'view_') === 0 || in_array($a, ['subcat', 'import'], true)) { $newKeys[] = 'products.' . $a; }
        }
        foreach (['subcat', 'import'] as $a) {
            if (isset($m['gov_products']['actions'][$a])) { $newKeys[] = 'gov_products.' . $a; }
        }
        say($rows, !empty($newKeys), 'New permission keys', count($newKeys) . ' available on the Roles screen');
    }
}

$bad = 0;
foreach ($rows as $r) { if (!$r[0]) { $bad++; } }
?><!DOCTYPE html>
<html lang="en"><head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>WBMCZ · category split migration</title>
<style>
 body{font-family:system-ui,-apple-system,"Segoe UI",sans-serif;background:#f8fafc;color:#0f172a;margin:0;padding:40px 20px;line-height:1.6}
 .wrap{max-width:860px;margin:0 auto}
 h1{font-size:23px;margin:0 0 4px} .sub{color:#64748b;font-size:14px;margin:0 0 26px}
 .card{background:#fff;border:1px solid #e2e8f0;border-radius:14px;padding:6px 20px;margin-bottom:20px}
 .row{display:flex;gap:12px;padding:11px 0;border-bottom:1px solid #f1f5f9;align-items:flex-start}
 .row:last-child{border-bottom:0}
 .tick{flex:0 0 20px;font-weight:700}
 .ok{color:#059669}.no{color:#dc2626}
 .what{font-weight:600;font-size:14px}
 .detail{color:#64748b;font-size:12.5px}
 .banner{border-radius:14px;padding:16px 20px;margin-bottom:22px;font-size:14px}
 .green{background:#ecfdf5;border:1px solid #a7f3d0;color:#065f46}
 .red{background:#fef2f2;border:1px solid #fecaca;color:#991b1b}
 code{background:#f1f5f9;padding:1px 6px;border-radius:4px;font-size:12.5px}
 ul{margin:8px 0 0;padding-left:20px} li{margin:4px 0;font-size:13.5px}
</style></head><body><div class="wrap">

<h1>One page per category</h1>
<p class="sub">Run once, then delete this file.</p>

<?php if ($bad === 0): ?>
  <div class="banner green"><b>All done.</b> Every file arrived, the category pages are written and the three new desks answer.
  Delete <code>productsplitmigration.php</code> now.</div>
<?php else: ?>
  <div class="banner red"><b><?php echo $bad; ?> thing(s) need attention.</b> Fix what is marked below and load this page again —
  running it twice changes nothing that is already right.</div>
<?php endif; ?>

<div class="card">
<?php foreach ($rows as $r): ?>
  <div class="row">
    <div class="tick <?php echo $r[0] ? 'ok' : 'no'; ?>"><?php echo $r[0] ? '&#10003;' : '&#10007;'; ?></div>
    <div>
      <div class="what"><?php echo htmlspecialchars($r[1]); ?></div>
      <?php if ($r[2] !== ''): ?><div class="detail"><?php echo htmlspecialchars($r[2]); ?></div><?php endif; ?>
    </div>
  </div>
<?php endforeach; ?>
</div>

<?php if (!empty($sync['made'])): ?>
<div class="card"><div class="row"><div><div class="what">Pages written just now</div>
<ul><?php foreach ($sync['made'] as $f): ?><li><code>admin/<?php echo htmlspecialchars($f); ?></code></li><?php endforeach; ?></ul>
</div></div></div>
<?php endif; ?>

<?php if (!empty($newKeys)): ?>
<div class="card"><div class="row"><div><div class="what">New permissions on the Roles screen</div>
<div class="detail">Give one of these to a staff member and they get that one shelf — nothing else.</div>
<ul><?php foreach ($newKeys as $k): ?><li><code><?php echo htmlspecialchars($k); ?></code></li><?php endforeach; ?></ul>
</div></div></div>
<?php endif; ?>

<div class="card"><div class="row"><div><div class="what">Database</div>
<div class="detail">No table was created, no column was added or dropped. The only database write this
migration can make is filling in a missing <code>service_categories.category_key</code>.</div>
</div></div></div>

</div></body></html>
