<?php
// pages/roles.php — Eden RMS: Roles & Permissions manager
// Requires: includes/auth.php (ec_db(), ec_require_min_role(), ec_role(), etc.)

ini_set('display_errors', 1);
error_reporting(E_ALL);

require_once __DIR__ . '/../includes/auth.php';
ec_require_min_role('admin'); // only admin/super_admin can manage roles

$db = ec_db();
if (!$db) { die('DB connection error'); }
$db->set_charset('utf8mb4');

/* ---------- Helpers (define if not already) ---------- */
if (!function_exists('db_has')) {
  function db_has(mysqli $db, string $tbl): bool {
    $tbl = $db->real_escape_string($tbl);
    $res = $db->query("SHOW TABLES LIKE '{$tbl}'");
    return $res && $res->num_rows > 0;
  }
}
if (!function_exists('col_exists')) {
  function col_exists(mysqli $db, string $tbl, string $col): bool {
    $tbl = $db->real_escape_string($tbl);
    $col = $db->real_escape_string($col);
    $res = $db->query("SHOW COLUMNS FROM `{$tbl}` LIKE '{$col}'");
    return $res && $res->num_rows > 0;
  }
}

/* ---------- Canonical permission set ---------- */
$ALL_PERMS = [
  'batches.view'     => 'Batches — View',
  'batches.manage'   => 'Batches — Manage',
  'students.manage'  => 'Students — Manage',
  'courses.manage'   => 'Courses — Manage',
  'payments.manage'  => 'Payments — Manage',
  'reports.view'     => 'Reports — View',
  'users.manage'     => 'Users — Manage',
  'roles.manage'     => 'Roles — Manage',
  'settings.manage'  => 'Settings — Manage',
  'marks.add'        => 'Marks — Add',
  'marks.verify'     => 'Marks — Verify',
];

/* ---------- Ensure permissions table contains the canonical set ---------- */
if (db_has($db, 'permissions')) {
  $have = [];
  $rs = $db->query("SELECT slug FROM permissions");
  while ($row = $rs->fetch_assoc()) { $have[$row['slug']] = true; }
  $ins = [];
  foreach ($ALL_PERMS as $slug => $name) {
    if (!isset($have[$slug])) {
      $ins[] = "('" . $db->real_escape_string($name) . "', '" . $db->real_escape_string($slug) . "')";
    }
  }
  if ($ins) {
    $db->query("INSERT INTO permissions (name, slug) VALUES " . implode(',', $ins));
  }
}

/* ---------- Verify schema presence; if roles or role_permissions missing, show help ---------- */
if (!db_has($db, 'roles') || !db_has($db, 'role_permissions') || !db_has($db, 'permissions')) {
  $needRoles  = !db_has($db, 'roles');
  $needPerms  = !db_has($db, 'permissions');
  $needMap    = !db_has($db, 'role_permissions');
  $schemaSQL = <<<SQL
-- Create tables if missing
CREATE TABLE IF NOT EXISTS roles (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  name VARCHAR(100) NOT NULL,
  slug VARCHAR(100) NOT NULL UNIQUE,
  is_default TINYINT(1) NOT NULL DEFAULT 0,
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS permissions (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  name VARCHAR(150) NOT NULL,
  slug VARCHAR(150) NOT NULL UNIQUE,
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS role_permissions (
  role_id INT UNSIGNED NOT NULL,
  perm_id INT UNSIGNED NOT NULL,
  PRIMARY KEY (role_id, perm_id),
  CONSTRAINT fk_rp_role FOREIGN KEY (role_id) REFERENCES roles(id)
    ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT fk_rp_perm FOREIGN KEY (perm_id) REFERENCES permissions(id)
    ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
SQL;
  ?>
  <!doctype html>
  <html lang="en"><head>
  <meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
  <title>Roles & Permissions — Missing Schema</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
  </head>
  <body class="bg-light">
  <div class="container py-4">
    <div class="alert alert-danger">
      <strong>Missing tables:</strong>
      <ul class="mb-0">
        <?php if ($needRoles): ?><li><code>roles</code></li><?php endif; ?>
        <?php if ($needPerms): ?><li><code>permissions</code></li><?php endif; ?>
        <?php if ($needMap): ?><li><code>role_permissions</code></li><?php endif; ?>
      </ul>
    </div>
    <div class="card">
      <div class="card-body">
        <h5 class="card-title mb-3">Run this SQL in your RMS database</h5>
        <pre class="mb-0" style="white-space:pre-wrap"><?= htmlspecialchars($schemaSQL) ?></pre>
      </div>
    </div>
  </div>
  </body></html>
  <?php
  exit;
}

/* ---------- Load roles ---------- */
$roles = [];
$hasDefault = col_exists($db, 'roles', 'is_default');

$sql = $hasDefault
  ? "SELECT id, name, slug, is_default FROM roles
     ORDER BY FIELD(slug,'super_admin','admin','manager','staff'), name"
  : "SELECT id, name, slug, 0 AS is_default FROM roles
     ORDER BY FIELD(slug,'super_admin','admin','manager','staff'), name";

$res = $db->query($sql);
while ($r = $res->fetch_assoc()) { $roles[] = $r; }

/* ---------- Save handler ---------- */
$msg = '';
if (($_SERVER['REQUEST_METHOD'] ?? '') === 'POST' && isset($_POST['role_id'])) {
  $rid   = (int)($_POST['role_id'] ?? 0);
  $name  = trim($_POST['name'] ?? '');
  $slug  = strtolower(trim($_POST['slug'] ?? ''));

  if ($rid <= 0 || $name === '' || $slug === '') {
    $msg = 'Invalid input.';
  } else {
    // Protect super_admin slug from being changed
    $stmt = $db->prepare("SELECT slug FROM roles WHERE id=?");
    $stmt->bind_param('i', $rid);
    $stmt->execute();
    $orig = $stmt->get_result()->fetch_assoc();
    $stmt->close();
    $origSlug = $orig['slug'] ?? '';

    if ($origSlug === 'super_admin') {
      $slug = 'super_admin';
    }

    $db->begin_transaction();
    try {
      if ($hasDefault) {
        // Keep is_default as-is (no toggle UI here); only name/slug update
        $stmt = $db->prepare("UPDATE roles SET name=?, slug=? WHERE id=?");
        $stmt->bind_param('ssi', $name, $slug, $rid);
        $stmt->execute();
        $stmt->close();
      } else {
        $stmt = $db->prepare("UPDATE roles SET name=?, slug=? WHERE id=?");
        $stmt->bind_param('ssi', $name, $slug, $rid);
        $stmt->execute();
        $stmt->close();
      }

      // Replace permissions
      $db->query("DELETE FROM role_permissions WHERE role_id=" . $rid);

      $sel = $_POST['perm'] ?? [];
      if (!empty($sel)) {
        $in  = implode("','", array_map(fn($s) => $db->real_escape_string($s), array_keys($sel)));
        $sql = "INSERT INTO role_permissions (role_id, perm_id)
                SELECT ?, p.id FROM permissions p WHERE p.slug IN ('{$in}')";
        $stmt = $db->prepare($sql);
        $stmt->bind_param('i', $rid);
        $stmt->execute();
        $stmt->close();
      }

      $db->commit();
      $msg = 'Saved.';
      // reload current role after save
      header('Location: '.$_SERVER['PHP_SELF'].'?id='.$rid.'&_ok=1');
      exit;
    } catch (Throwable $e) {
      $db->rollback();
      $msg = 'Save failed: ' . $e->getMessage();
    }
  }
}

/* ---------- Determine current role to show ---------- */
$roleId = isset($_GET['id']) ? (int)$_GET['id'] : ($roles[0]['id'] ?? 0);
$cur = null;
foreach ($roles as $r) {
  if ((int)$r['id'] === $roleId) { $cur = $r; break; }
}
if (!$cur && $roles) { $cur = $roles[0]; }

/* ---------- Load current role permissions ---------- */
$curPerms = [];
if ($cur) {
  $stmt = $db->prepare("SELECT p.slug FROM role_permissions rp JOIN permissions p ON p.id = rp.perm_id WHERE rp.role_id = ?");
  $stmt->bind_param('i', $cur['id']);
  $stmt->execute();
  $rs = $stmt->get_result();
  while ($row = $rs->fetch_assoc()) { $curPerms[$row['slug']] = true; }
  $stmt->close();
}

?>
<!doctype html>
<html lang="en"><head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Roles & Permissions — Eden RMS</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
  body { background:#f5f7fb; }
  .role-list .active { background:#eef3ff; }
</style>
<body>
<?php
require_once __DIR__.'/../includes/auth.php';

// Option A: whole page requires Manager+
ec_require_min_role('manager');   // manager, admin, super_admin can enter

// Option B: fine-grained permission (use with or without Option A)
if (!ec_can('payments.manage')) {
  header('Location: /edenrms/pages/403.php'); exit;
}
$ACTIVE = 'Payment Manager';                 // set per page
require_once __DIR__ . '/../includes/header.php';
require_once __DIR__ . '/../includes/sidebar.php';
?>
<main class="ec-main">
<div class="container py-4">
  <div class="d-flex align-items-center justify-content-between mb-3">
    <h4 class="mb-0">Roles & Permissions</h4>
    <span class="text-muted small">You are: <strong><?= htmlspecialchars(ec_role()) ?></strong></span>
  </div>

  <?php if ($msg): ?>
    <div class="alert alert-info py-2"><?= htmlspecialchars($msg) ?></div>
  <?php elseif (!empty($_GET['_ok'])): ?>
    <div class="alert alert-success py-2">Saved.</div>
  <?php endif; ?>

  <div class="row g-3">
    <!-- Roles list -->
    <div class="col-md-3">
      <div class="list-group role-list">
        <?php foreach ($roles as $r): ?>
          <a class="list-group-item list-group-item-action <?= $r['id'] == ($cur['id'] ?? 0) ? 'active' : '' ?>"
             href="?id=<?= (int)$r['id'] ?>">
            <?= htmlspecialchars($r['name']) ?>
            <div class="small text-muted"><?= htmlspecialchars($r['slug']) ?></div>
          </a>
        <?php endforeach; ?>
      </div>
    </div>

    <!-- Editor -->
    <div class="col-md-9">
      <?php if ($cur): ?>
      <form method="post" class="card shadow-sm">
        <div class="card-body">
          <input type="hidden" name="role_id" value="<?= (int)$cur['id'] ?>">

          <div class="row g-3 align-items-end">
            <div class="col-md-5">
              <label class="form-label">Role Name</label>
              <input class="form-control" name="name" id="rname" value="<?= htmlspecialchars($cur['name']) ?>" required>
              <div class="form-text">Visible label (e.g., “Staff”)</div>
            </div>
            <div class="col-md-5">
              <label class="form-label">Slug</label>
              <input class="form-control" name="slug" id="rslug" value="<?= htmlspecialchars($cur['slug']) ?>" required <?= $cur['slug']==='super_admin'?'readonly':'' ?>>
              <div class="form-text text-muted"><small id="slugPreview"><?= htmlspecialchars($cur['slug']) ?></small></div>
            </div>
            <div class="col-md-2 text-end">
              <button class="btn btn-primary">Save</button>
            </div>
          </div>

          <hr>

          <div class="row row-cols-1 row-cols-md-2 g-2">
            <?php foreach ($ALL_PERMS as $slug => $label): ?>
              <div class="col">
                <div class="form-check">
                  <input class="form-check-input" type="checkbox"
                         name="perm[<?= htmlspecialchars($slug) ?>]"
                         id="p_<?= md5($slug) ?>"
                         <?= isset($curPerms[$slug]) ? 'checked' : '' ?>>
                  <label class="form-check-label" for="p_<?= md5($slug) ?>"><?= htmlspecialchars($label) ?></label>
                </div>
              </div>
            <?php endforeach; ?>
          </div>

        </div>
      </form>
      <?php endif; ?>
    </div>
  </div>
</div>

<script>
  // Auto-slug from name & neat preview (prevents stray text under the form)
  const nameI = document.getElementById('rname');
  const slugI = document.getElementById('rslug');
  const prev  = document.getElementById('slugPreview');
  function slugify(s){ return s.toLowerCase().trim().replace(/[^a-z0-9]+/g,'-').replace(/^-+|-+$/g,''); }
  if (nameI && slugI && prev && !slugI.readOnly) {
    nameI.addEventListener('input', ()=>{
      if (!slugI.dataset.touched) {
        slugI.value = slugify(nameI.value);
        prev.textContent = slugI.value;
      }
    });
    slugI.addEventListener('input', ()=>{
      slugI.dataset.touched = "1";
      prev.textContent = slugify(slugI.value);
    });
  }
</script>
</main>
</body></html>
