<?php
@ini_set('display_errors','1'); @error_reporting(E_ALL);
require_once __DIR__ . '/../includes/auth.php';
require_login();

$page_title = 'Roles Master';
$TABLE = 'jos_admin_roles';
$MENUTBL = 'jos_admin_menus';
global $con;

/* ---------------------------
   Simple user access control
   - non-invasive: checks session keys if present
   - defaults to allow if session capability info is not available
---------------------------- */
function user_is_admin(){
  return !empty($_SESSION['user']['is_admin']);
}
function user_has_cap($cap){
  if (user_is_admin()) return true;
  if (!empty($_SESSION['user']['caps']) && is_array($_SESSION['user']['caps'])){
    return in_array($cap, $_SESSION['user']['caps']);
  }
  if (!empty($_SESSION['user']['capabilities']) && is_array($_SESSION['user']['capabilities'])){
    return in_array($cap, $_SESSION['user']['capabilities']);
  }
  // fallback: allow (so this won't break systems without capability data)
  return true;
}
function can_view(){  return user_has_cap('roles_view'); }
function can_add(){   return user_has_cap('roles_add'); }
function can_edit(){  return user_has_cap('roles_edit'); }
function can_delete(){return user_has_cap('roles_delete'); }

/* ---------- helpers ---------- */
/**
 * Keep params helper — returns full script path + query string.
 * Usage: keep_params(['edit'=>null,'add'=>null])
 * It uses current $_GET, applies changes, and returns e.g. "/adminconsole/masters/roles.php?q=foo&status=1"
 */
function keep_params(array $changes = []) {
  // start from current GET params
  $qs = $_GET;
  foreach ($changes as $k=>$v){
    if ($v === null) {
      unset($qs[$k]);
    } else {
      $qs[$k] = $v;
    }
  }

  $q = http_build_query($qs);
  $script = $_SERVER['PHP_SELF'] ?? '';
  // ensure script isn't empty — fallback to basename
  if (!$script) $script = '/' . basename(__FILE__);
  return $script . ($q !== '' ? ('?' . $q) : '');
}

function clean($v){ return trim((string)$v); }
function col_exists($con,$table,$col){
  $r=mysqli_query($con,"SHOW COLUMNS FROM `$table` LIKE '".mysqli_real_escape_string($con,$col)."'");
  return ($r && mysqli_num_rows($r)>0);
}
function ensure_schema_roles($con,$table){
  if(!col_exists($con,$table,'status'))  mysqli_query($con,"ALTER TABLE `$table` ADD `status` TINYINT(1) NOT NULL DEFAULT 1");
  if(!col_exists($con,$table,'orderby')) mysqli_query($con,"ALTER TABLE `$table` ADD `orderby` INT NOT NULL DEFAULT 0");
  else mysqli_query($con,"ALTER TABLE `$table` MODIFY `orderby` INT NOT NULL DEFAULT 0");
}
ensure_schema_roles($con,$TABLE);

/* ---------- load title from menu master if possible (non-destructive) ---------- */
$script_keyword = 'role'; // sensible keyword fallback
$script = basename(__FILE__);
try {
  $qstr = "%".$script_keyword."%";
  $st = $con->prepare("SELECT title FROM `$MENUTBL` WHERE (link LIKE ? OR path LIKE ? OR title LIKE ?) LIMIT 1");
  if($st){
    $st->bind_param('sss', $qstr, $qstr, $qstr);
    $st->execute();
    $res = $st->get_result();
    if ($r = $res->fetch_assoc()) $page_title = $r['title'] ?: $page_title;
    $st->close();
  }
} catch(Exception $e){
  // ignore
}

/* ---------- flash redirect ---------- */
function back_to_list($msg=''){
  $self = $_SERVER['PHP_SELF'] ?? '';
  if (!$self) $self = '/' . basename(__FILE__);
  header('Location: '.$self.($msg!==''?'?ok='.urlencode($msg):'')); exit;
}
$ok  = clean($_GET['ok'] ?? '');
$err = '';

/* ---------- mode ---------- */
$mode = (isset($_GET['edit']) || isset($_GET['add'])) ? 'form' : 'list';

/* ---------- permission guard for viewing ---------- */
if ($mode === 'list' && !can_view()){
  ob_start(); ?>
  <link rel="stylesheet" href="/adminconsole/assets/ui.css">
  <div class="master-wrap">
    <div class="headbar">
      <div class="headbar-left"><h2 style="margin:0"><?php echo htmlspecialchars($page_title); ?></h2></div>
    </div>
    <div class="card" style="border-left:4px solid #ef4444"><div>Permission denied: You do not have access to view this page.</div></div>
  </div>
  <?php echo ob_get_clean(); exit;
}

/* ---------- POST ---------- */
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  if (!verify_csrf($_POST['csrf'] ?? null)) {
    $err='Invalid request. Please refresh.';
  } else {
    if (isset($_POST['delete'])) {
      if (!can_delete()){
        $err = 'Permission denied: cannot delete.';
      } else {
        $id=(int)($_POST['id'] ?? 0);
        $st=$con->prepare("DELETE FROM $TABLE WHERE id=?");
        $st->bind_param('i',$id);
        if ($st->execute()){ $st->close(); back_to_list('Deleted successfully.'); }
        $err='Delete failed.'; $st->close();
      }
    }

    if (isset($_POST['save'])) {
      $id      = (int)($_POST['id'] ?? 0);
      if ($id>0 && !can_edit()){ $err='Permission denied: cannot edit.'; }
      if ($id===0 && !can_add()){ $err='Permission denied: cannot add.'; }

      $name    = clean($_POST['name'] ?? '');
      $orderby = (int)($_POST['orderby'] ?? 0);
      $status  = (int)($_POST['status'] ?? 1);

      if (!$err && $name===''){ $err='Role name is required.'; }
      else if (!$err) {
        if ($id>0){
          $st=$con->prepare("SELECT id FROM $TABLE WHERE LOWER(name)=LOWER(?) AND id<>?");
          $st->bind_param('si',$name,$id);
        } else {
          $st=$con->prepare("SELECT id FROM $TABLE WHERE LOWER(name)=LOWER(?)");
          $st->bind_param('s',$name);
        }
        $st->execute(); $st->store_result();
        if($st->num_rows>0) $err='Role already exists.'; $st->close();

        if(!$err){
          if ($orderby<=0){
            $q=mysqli_query($con,"SELECT COALESCE(MAX(orderby),0)+1 FROM $TABLE");
            $orderby = ($q && ($r=mysqli_fetch_row($q))) ? (int)$r[0] : 1;
          }
          if ($id>0){
            $st=$con->prepare("UPDATE $TABLE SET name=?, orderby=?, status=? WHERE id=?");
            $st->bind_param('siii',$name,$orderby,$status,$id);
            if ($st->execute()){ $st->close(); back_to_list('Updated successfully.'); }
            $err='Update failed.'; $st->close();
          } else {
            $st=$con->prepare("INSERT INTO $TABLE (name,orderby,status) VALUES (?,?,?)");
            $st->bind_param('sii',$name,$orderby,$status);
            if ($st->execute()){ $st->close(); back_to_list('Added successfully.'); }
            $err='Insert failed.'; $st->close();
          }
        }
      }
    }
  }
}

/* ---------- edit row ---------- */
$edit=null;
if ($mode==='form' && isset($_GET['edit'])){
  $eid=(int)$_GET['edit'];
  $st=$con->prepare("SELECT id,name,orderby,status FROM $TABLE WHERE id=?");
  $st->bind_param('i',$eid); $st->execute();
  $edit=$st->get_result()->fetch_assoc(); $st->close();
}

/* ---------- filters ---------- */
$q      = clean($_GET['q'] ?? '');
$status = clean($_GET['status'] ?? '');
$sort   = clean($_GET['sort'] ?? 'order_asc');
$all    = isset($_GET['all']); $lim = $all ? 0 : 50;

$where=" WHERE 1=1 "; $bind=[]; $type='';
if ($q!==''){ $like="%$q%"; $where.=" AND name LIKE ?"; $bind[]=$like; $type.='s'; }
if ($status!==''){ $stt=(int)$status; $where.=" AND status=?"; $bind[]=$stt; $type.='i'; }

switch ($sort){
  case 'order_desc': $order="ORDER BY orderby DESC, name ASC"; break;
  case 'name_asc':   $order="ORDER BY name ASC"; break;
  case 'name_desc':  $order="ORDER BY name DESC"; break;
  case 'id_desc':    $order="ORDER BY id DESC"; break;
  case 'id_asc':     $order="ORDER BY id ASC"; break;
  default:           $order="ORDER BY orderby ASC, name ASC";
}

/* ---------- counts / list ---------- */
$rows=[]; $total=0;
if ($mode==='list'){
  $st=$con->prepare("SELECT COUNT(*) c FROM $TABLE $where");
  if($bind) $st->bind_param($type, ...$bind);
  $st->execute(); $total=(int)$st->get_result()->fetch_assoc()['c']; $st->close();

  $sql="SELECT id,name,orderby,status FROM $TABLE $where $order";
  if(!$all) $sql.=" LIMIT $lim";
  $st=$con->prepare($sql);
  if($bind) $st->bind_param($type, ...$bind);
  $st->execute();
  $rs=$st->get_result();
  while($r=$rs->fetch_assoc()) $rows[]=$r;
  $st->close();
}

/* ---------- view ---------- */
ob_start(); ?>
<link rel="stylesheet" href="/adminconsole/assets/ui.css">

<div class="master-wrap">
  <div class="headbar">
    <div class="headbar-left"><h2 style="margin:0"><?php echo htmlspecialchars($page_title); ?></h2></div>
    <div class="headbar-right"></div>
  </div>

  <?php if($ok):  ?><div class="card" style="border-left:4px solid #10b981"><div><?php echo htmlspecialchars($ok); ?></div></div><?php endif; ?>
  <?php if($err): ?><div class="card" style="border-left:4px solid #ef4444"><div><?php echo htmlspecialchars($err); ?></div></div><?php endif; ?>

  <?php if ($mode==='list'): ?>
    <div class="card">
      <div class="toolbar">
        <form method="get" class="search">
          <input type="text" name="q" class="inp" placeholder="Search role..." value="<?php echo htmlspecialchars($q); ?>" style="width:320px">
          <select name="status" class="inp small" title="Status">
            <option value="">All Status</option>
            <option value="1" <?php echo ($status==='1')?'selected':''; ?>>Active</option>
            <option value="0" <?php echo ($status==='0')?'selected':''; ?>>Inactive</option>
          </select>
          <select name="sort" class="inp small" title="Sort by">
            <?php
              $opts = [
                'order_asc'  => 'Order Level ↑',
                'order_desc' => 'Order Level ↓',
                'name_asc'   => 'Name A–Z',
                'name_desc'  => 'Name Z–A',
                'id_desc'    => 'Newest first',
                'id_asc'     => 'Oldest first'
              ];
              foreach($opts as $k=>$v){ $sel=($sort===$k)?'selected':''; echo "<option value=\"$k\" $sel>$v</option>"; }
            ?>
          </select>
          <button class="btn gray" type="submit">Search</button>
          <a class="btn gray" href="<?php echo keep_params(['all'=>1]); ?>">View All (<?php echo $total; ?>)</a>
        </form>
        <div style="display:flex;gap:8px">
          <?php if (can_add()): ?>
            <a class="btn green" href="<?php echo keep_params(['add'=>1,'edit'=>null]); ?>">Add New</a>
          <?php endif; ?>
        </div>
      </div>

      <div style="margin:6px 0 12px;color:#9ca3af">
        Showing <strong><?php echo !$all ? count($rows) : $total; ?></strong> of <strong><?php echo $total; ?></strong>
      </div>

      <div class="table-wrap">
        <table>
          <thead><tr><th>SR No</th><th>Name</th><th>Order Level</th><th>Status</th><th>Actions</th></tr></thead>
          <tbody>
            <?php if(!$rows): ?><tr><td colspan="5" style="color:#9ca3af">No records</td></tr><?php endif; ?>
            <?php $sr=0; foreach($rows as $r): $sr++; ?>
              <tr>
                <td><?php echo $sr; ?></td>
                <td><?php echo htmlspecialchars($r['name']); ?></td>
                <td><?php echo (int)$r['orderby']; ?></td>
                <td><span class="badge <?php echo $r['status']?'on':'off'; ?>"><?php echo $r['status']?'Active':'Inactive'; ?></span></td>
                <td>
                  <?php if (can_edit()): ?>
                    <a class="btn gray" href="<?php echo keep_params(['edit'=>$r['id'],'add'=>null]); ?>">Edit</a>
                  <?php endif; ?>
                  <?php if (can_delete()): ?>
                    <form method="post" style="display:inline" onsubmit="return confirm('Delete this role?');">
                      <input type="hidden" name="csrf" value="<?php echo htmlspecialchars(csrf_token()); ?>">
                      <input type="hidden" name="id" value="<?php echo (int)$r['id']; ?>">
                      <button class="btn red" name="delete" type="submit">Delete</button>
                    </form>
                  <?php endif; ?>
                </td>
              </tr>
            <?php endforeach; ?>
          </tbody>
        </table>
      </div>
    </div>

  <?php else: ?>
    <div class="card" id="formTop" style="max-width:620px">
      <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">
        <h3 style="margin:0"><?php echo $edit ? 'Edit Role' : 'Add Role'; ?></h3>
        <!-- Back to list should remove add/edit but preserve other filters -->
        <a class="btn gray" href="<?php echo keep_params(['edit'=>null,'add'=>null]); ?>">Back to List</a>
      </div>

      <form method="post" style="display:grid;grid-template-columns:1fr 1fr;gap:12px" autocomplete="off">
        <input type="hidden" name="csrf" value="<?php echo htmlspecialchars(csrf_token()); ?>">
        <?php if($edit): ?><input type="hidden" name="id" value="<?php echo (int)$edit['id']; ?>"><?php endif; ?>

        <div style="grid-column:1/-1">
          <label>Role Name*</label>
          <input name="name" class="inp" required value="<?php echo htmlspecialchars($edit['name'] ?? ''); ?>" <?php echo (!$edit && !can_add())?'readonly':''; ?>>
        </div>

        <div>
          <label>Order Level</label>
          <input type="number" name="orderby" class="inp" value="<?php echo htmlspecialchars($edit['orderby'] ?? 0); ?>">
        </div>

        <div>
          <label>Status</label>
          <?php $st = isset($edit['status']) ? (int)$edit['status'] : 1; ?>
          <select name="status" class="inp" <?php echo (!$edit && !can_add())?'disabled':''; ?>>
            <option value="1" <?php echo $st===1?'selected':''; ?>>Active</option>
            <option value="0" <?php echo $st===0?'selected':''; ?>>Inactive</option>
          </select>
        </div>

        <div style="grid-column:1/-1">
          <?php if (($edit && can_edit()) || (!$edit && can_add())): ?>
            <button class="btn green" name="save" type="submit">Save</button>
          <?php else: ?>
            <button class="btn gray" type="button" disabled>Save (no permission)</button>
          <?php endif; ?>
        </div>
      </form>
    </div>

    <script>
      (function(){
        function toTop(){ window.scrollTo({top:0, behavior:'instant'}); }
        if('scrollRestoration' in history) history.scrollRestoration='manual';
        window.addEventListener('load',function(){ toTop(); setTimeout(toTop,50); setTimeout(toTop,150); });
      })();
    </script>
  <?php endif; ?>
</div>
<?php echo ob_get_clean();
