<?php
/**
 * Master Page Generator (Agent Console) — FIXED MENU TABLE AUTODETECT
 * Run via: /adminconsole/tools/agent.php
 *
 * Example args are same as before; NEW: you can pass "parent_name": "Masters"
 */

if (!isset($con)) { die("Run me via Agent Console."); }

$A = json_decode($safe_args ?: "{}", true) ?: [];
$PAGE        = trim($A['page_title'] ?? 'New Master');
$TABLE       = trim($A['table'] ?? '');
$SLUG        = trim($A['slug'] ?? '');                // used if menu table has a slug column
$FILE        = trim($A['filename'] ?? ($SLUG ? "$SLUG.php" : 'master.php'));

$LABEL_COL   = trim($A['label_column']   ?? 'name');
$STATUS_COL  = trim($A['status_column']  ?? 'status');
$ORDERBY_COL = trim($A['orderby_column'] ?? 'orderby');

$ENSURE      = !empty($A['ensure_status_orderby']);
$ADD_MENU    = !empty($A['add_menu']);
$PARENT_SLUG = trim($A['parent_slug'] ?? 'masters');  // for tables that have slug column
$PARENT_NAME = trim($A['parent_name'] ?? 'Masters');  // for tables that don’t have slug column (your case)
$ORDER       = intval($A['order'] ?? 10);
$FORCE       = !empty($A['force']);

if ($TABLE==='' || $SLUG==='') { die("Missing required: table or slug"); }

$mastersDir = __DIR__ . '/../../masters';
@mkdir($mastersDir, 0775, true);
$dest = $mastersDir . "/$FILE";
if (file_exists($dest) && !$FORCE) {
  echo "File exists: /adminconsole/masters/$FILE (use {\"force\":true} to overwrite)\n"; exit;
}

/* ---------------- Template (unchanged list/form page) ---------------- */
$template = <<<'PHT'
<?php
@ini_set('display_errors','1'); @error_reporting(E_ALL);

require_once __DIR__ . '/../includes/auth.php';  require_login();
require_once __DIR__ . '/../includes/initialize.php'; // $con (mysqli)

/* ===========================================================
  %%PAGE_TITLE%%  (Generated)
  Table: %%TABLE%%
  Columns:
    - Label: %%LABEL_COL%%
    - Status: %%STATUS_COL%%
    - Order: %%ORDERBY_COL%%
   =========================================================== */

$page_title = '%%PAGE_TITLE%%';
$TABLE      = '%%TABLE%%';
$LABEL_COL  = '%%LABEL_COL%%';
$STATUS_COL = '%%STATUS_COL%%';
$ORDER_COL  = '%%ORDERBY_COL%%';

/* ---------- helpers ---------- */
function keep_params(array $changes = []){
  $qs = $_GET; foreach ($changes as $k=>$v){ if ($v===null) unset($qs[$k]); else $qs[$k] = $v; }
  $q = http_build_query($qs); return $q ? ('?'.$q) : '';
}
function clean($v){ return trim((string)$v); }

/* SHOW COLUMNS cannot be prepared; escape and run directly. */
function col_exists(mysqli $con, string $table, string $col): bool {
  $table = preg_replace('/[^a-zA-Z0-9_]/','', $table);
  $col   = $con->real_escape_string($col);
  $sql   = "SHOW COLUMNS FROM `{$table}` LIKE '{$col}'";
  $res   = $con->query($sql);
  return ($res && $res->fetch_assoc()) ? true : false;
}

/* ensure schema (status/order columns) */
function ensure_schema(mysqli $con, string $table, string $statusCol, string $orderCol){
  if (!col_exists($con,$table,$statusCol))  { $con->query("ALTER TABLE `{$table}` ADD `{$statusCol}`  TINYINT DEFAULT 1"); }
  if (!col_exists($con,$table,$orderCol))   { $con->query("ALTER TABLE `{$table}` ADD `{$orderCol}` INT     DEFAULT 0"); }
  $con->query("ALTER TABLE `{$table}` MODIFY `{$statusCol}`  TINYINT DEFAULT 1");
  $con->query("ALTER TABLE `{$table}` MODIFY `{$orderCol}` INT     DEFAULT 0");
}

/* only define csrf helpers if not already present */
if (!function_exists('csrf_token')) {
  function csrf_token(){
    if (session_status()!==PHP_SESSION_ACTIVE) session_start();
    if (empty($_SESSION['csrf'])) $_SESSION['csrf'] = bin2hex(random_bytes(16));
    return $_SESSION['csrf'];
  }
}
if (!function_exists('verify_csrf')) {
  function verify_csrf($t){
    return (session_status()===PHP_SESSION_ACTIVE
            && !empty($_SESSION['csrf'])
            && hash_equals($_SESSION['csrf'], (string)$t));
  }
}

/* flash redirect */
function flash_redirect(string $msg='Saved', string $type='ok'){
  $qs = $_GET; unset($qs['add'], $qs['edit']);
  $qs[$type] = $msg;
  header('Location: ?'.http_build_query($qs)); exit;
}

/* ensure schema if requested */
%%ENSURE_HOOK%%

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

/* ---------- POST handler ---------- */
$err = ''; $ok = '';
if ($_SERVER['REQUEST_METHOD']==='POST'){
  if (!verify_csrf($_POST['csrf'] ?? '')) { die('CSRF failed'); }

  if (isset($_POST['save'])){
    $id       = (int)($_POST['id'] ?? 0);
    $label    = clean($_POST['label'] ?? '');
    $status   = (int)($_POST['status'] ?? 1);
    $orderby  = (int)($_POST['orderby'] ?? 0);

    if ($label==='') $err = 'Name is required.';
    else {
      // duplicate check on label column
      $sql = "SELECT id FROM $TABLE WHERE LOWER($LABEL_COL)=LOWER(?) ".($id>0?"AND id<>$id":"")." LIMIT 1";
      $st  = $con->prepare($sql); $st->bind_param('s',$label);
      $st->execute(); $dup = $st->get_result()->fetch_assoc(); $st->close();
      if ($dup) $err = 'Duplicate name.';
    }

    if (!$err){
      if ($orderby<=0){
        $mx=0; $r=$con->query("SELECT COALESCE(MAX($ORDER_COL),0) mx FROM $TABLE");
        if ($r && $row=$r->fetch_assoc()) $mx=(int)$row['mx'];
        $orderby = $mx + 1;
      }

      if ($id>0){
        $st = $con->prepare("UPDATE $TABLE SET $LABEL_COL=?, $STATUS_COL=?, $ORDER_COL=? WHERE id=?");
        $st->bind_param('siii', $label,$status,$orderby,$id);
        if ($st->execute()) { $st->close(); flash_redirect('Updated successfully'); }
        $err = 'Update failed'; $st->close();
      } else {
        $st = $con->prepare("INSERT INTO $TABLE ($LABEL_COL, $STATUS_COL, $ORDER_COL) VALUES (?,?,?)");
        $st->bind_param('sii', $label,$status,$orderby);
        if ($st->execute()) { $st->close(); flash_redirect('Saved successfully'); }
        $err = 'Insert failed'; $st->close();
      }
    }
  }

  if (isset($_POST['delete'])){
    $id = (int)($_POST['id'] ?? 0);
    $st = $con->prepare("DELETE FROM $TABLE WHERE id=?");
    $st->bind_param('i',$id);
    if ($st->execute()) { $st->close(); flash_redirect('Deleted successfully'); }
    $err = 'Delete failed'; $st->close();
  }
}

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

/* ---------- filters ---------- */
$q        = clean($_GET['q'] ?? '');
$level    = clean($_GET['level'] ?? '');
$sort     = clean($_GET['sort'] ?? 'order_asc');
$all      = isset($_GET['all']);
$limit    = $all ? 1000000 : 50;

/* ---------- list query ---------- */
$order_sql = "ORDER BY $ORDER_COL ASC";
if ($sort==='order_desc') $order_sql = "ORDER BY $ORDER_COL DESC";
if ($sort==='name_asc')   $order_sql = "ORDER BY $LABEL_COL ASC";
if ($sort==='name_desc')  $order_sql = "ORDER BY $LABEL_COL DESC";
if ($sort==='id_desc')    $order_sql = "ORDER BY id DESC";
if ($sort==='id_asc')     $order_sql = "ORDER BY id ASC";

$where   = "WHERE 1";
if ($q!==''){ $qLike='%'.$con->real_escape_string($q).'%'; $where.=" AND $LABEL_COL LIKE '$qLike'"; }
if ($level!==''){ $lv=(int)$level; $where.=" AND $ORDER_COL=$lv"; }

$sql="SELECT id, $LABEL_COL AS label, $ORDER_COL AS orderby, $STATUS_COL AS status FROM $TABLE $where $order_sql LIMIT $limit";
$res=$con->query($sql);

/* ---------- view ---------- */
ob_start(); ?>
<link rel="stylesheet" href="/adminconsole/assets/ui.css">
<style>
  .toolbar { display:flex; justify-content:space-between; align-items:flex-end; gap:12px; }
  .toolbar .form { flex:1; }
  .grid-filters { display:grid; grid-template-columns: 1fr 180px 140px 160px; gap:10px; }
  .inp { width:100%; }
  .alert.ok { background:#14532d; color:#d1fae5; padding:8px 12px; border-radius:6px; margin:10px 0; }
  .alert.err,.alert.warn { background:#7c2d12; color:#fee2e2; padding:8px 12px; border-radius:6px; margin:10px 0; }
</style>

<div class="master-wrap">
  <div class="headbar">
    <h2><?=htmlspecialchars($page_title)?></h2>
  </div>

  <?php if ($mode==='list'): ?>
    <?php if(isset($_GET['ok'])): ?><div class="alert ok"><?=htmlspecialchars($_GET['ok'])?></div><?php endif; ?>
    <?php if(isset($_GET['err'])): ?><div class="alert err"><?=htmlspecialchars($_GET['err'])?></div><?php endif; ?>

    <div class="card">
      <div class="toolbar">
        <!-- LEFT: filters -->
        <form method="get" class="form">
          <div class="grid-filters">
            <input class="inp" type="text" name="q" value="<?=htmlspecialchars($q)?>" placeholder="Search ...">
            <input class="inp" type="number" name="level" value="<?=htmlspecialchars($level)?>" placeholder="Order Level">
            <select class="inp" name="sort">
              <option value="order_asc"  <?=($sort==='order_asc'?'selected':'')?>>Order Level ↑</option>
              <option value="order_desc" <?=($sort==='order_desc'?'selected':'')?>>Order Level ↓</option>
              <option value="name_asc"   <?=($sort==='name_asc'?'selected':'')?>>Name A–Z</option>
              <option value="name_desc"  <?=($sort==='name_desc'?'selected':'')?>>Name Z–A</option>
              <option value="id_desc"    <?=($sort==='id_desc'?'selected':'')?>>Newest first</option>
              <option value="id_asc"     <?=($sort==='id_asc'?'selected':'')?>>Oldest first</option>
            </select>
            <button class="btn gray" type="submit">Apply</button>
          </div>
        </form>

        <!-- RIGHT: actions -->
        <div class="toolbar" style="gap:8px;">
          <?php if (!isset($_GET['all'])): ?>
            <a class="btn secondary" href="<?=keep_params(['all'=>1])?>">View All</a>
          <?php else: ?>
            <a class="btn secondary" href="<?=keep_params(['all'=>null])?>">Last 50</a>
          <?php endif; ?>
          <a class="btn success" href="<?=keep_params(['add'=>1])?>">+ Add New</a>
        </div>
      </div>

      <div class="table-wrap">
        <table class="table">
          <thead style="position:sticky; top:0;">
            <tr>
              <th style="width:70px;">SR No</th>
              <th>Label</th>
              <th>Order Level</th>
              <th>Status</th>
              <th style="width:160px;">Actions</th>
            </tr>
          </thead>
          <tbody>
          <?php
          if ($res && $res->num_rows){
            $sr=1;
            while($r=$res->fetch_assoc()){
              echo '<tr>';
              echo '<td>'.($sr++).'</td>';
              echo '<td>'.htmlspecialchars($r['label']).'</td>';
              echo '<td>'.intval($r['orderby']).'</td>';
              echo '<td><span class="badge '.($r['status']?'success':'danger').'">'.($r['status']?'Active':'Inactive').'</span></td>';
              echo '<td>';
              echo '<a class="btn secondary" href="'.keep_params(['edit'=>$r['id']]).'">Edit</a> ';
              echo '<form method="post" style="display:inline" onsubmit="return confirm(\'Delete?\');">';
              echo '<input type="hidden" name="csrf" value="'.htmlspecialchars(csrf_token()).'">';
              echo '<input type="hidden" name="id" value="'.$r['id'].'">';
              echo '<button class="btn danger" name="delete" type="submit">Delete</button>';
              echo '</form>';
              echo '</td>';
              echo '</tr>';
            }
          } else {
            echo '<tr><td colspan="5">No records.</td></tr>';
          }
          ?>
          </tbody>
        </table>
      </div>
    </div>

  <?php else: /* form */ 
    $row = ['id'=>0,'label'=>'','status'=>1,'orderby'=>0];
    if ($edit){ $row = $edit; }
    $LIST_URL = htmlspecialchars(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
  ?>
    <div class="card" style="max-width:820px">
      <div class="toolbar" style="justify-content:space-between">
        <h3 style="margin:0"><?= $row['id']? 'Edit':'Add New' ?></h3>
        <a class="btn secondary" href="<?=$LIST_URL?>">Back to List</a>
      </div>

      <?php if($ok): ?><div class="alert ok"><?=htmlspecialchars($ok)?></div><?php endif; ?>
      <?php if($err): ?><div class="alert err"><?=htmlspecialchars($err)?></div><?php endif; ?>

      <form method="post" class="form">
        <input type="hidden" name="csrf" value="<?=htmlspecialchars(csrf_token())?>">
        <?php if($row['id']): ?><input type="hidden" name="id" value="<?=$row['id']?>"><?php endif; ?>

        <div class="grid" style="grid-template-columns:1fr 160px 140px; gap:12px">
          <div>
            <label>Label*</label>
            <input class="inp" name="label" required value="<?=htmlspecialchars($row['label'])?>">
          </div>
          <div>
            <label>Order Level</label>
            <input class="inp" type="number" name="orderby" value="<?=intval($row['orderby'])?>">
          </div>
          <div>
            <label>Status</label>
            <select class="inp" name="status">
              <option value="1" <?=($row['status']==1?'selected':'')?>>Active</option>
              <option value="0" <?=($row['status']==0?'selected':'')?>>Inactive</option>
            </select>
          </div>
        </div>

        <div class="toolbar" style="margin-top:12px">
          <button class="btn success" name="save" type="submit">Save</button>
        </div>
      </form>
    </div>
  <?php endif; ?>
</div>

<?php
echo ob_get_clean();
PHT;

/* ----- Build the template with substitutions ----- */
$ensure = $ENSURE ? "ensure_schema(\$con, \$TABLE, \$STATUS_COL, \$ORDER_COL);" : "";
$out = str_replace(
  ['%%PAGE_TITLE%%','%%TABLE%%','%%LABEL_COL%%','%%STATUS_COL%%','%%ORDERBY_COL%%','%%ENSURE_HOOK%%'],
  [$PAGE, $TABLE, $LABEL_COL, $STATUS_COL, $ORDERBY_COL, $ensure],
  $template
);

if (!file_put_contents($dest, $out)) { die("Failed writing $dest"); }
echo "Master created: /adminconsole/masters/$FILE\n";

/* ================== Menu wiring (AUTO-DETECT) ================== */
if ($ADD_MENU){

  // tiny helpers
  $tbl_exists = function(string $t) use ($con){
    $t = $con->real_escape_string($t);
    $r = $con->query("SHOW TABLES LIKE '{$t}'");
    return ($r && $r->num_rows>0);
  };
  $col_exists = function(string $t, string $c) use ($con){
    $t = preg_replace('/[^a-zA-Z0-9_]/','',$t);
    $c = $con->real_escape_string($c);
    $r = $con->query("SHOW COLUMNS FROM `{$t}` LIKE '{$c}'");
    return ($r && $r->num_rows>0);
  };

  $page = $con->real_escape_string($PAGE);
  $slug = $con->real_escape_string($SLUG);
  $path = $con->real_escape_string("/adminconsole/masters/$FILE");
  $parent_slug = $con->real_escape_string($PARENT_SLUG);
  $parent_name = $con->real_escape_string($PARENT_NAME);
  $ord  = (int)$ORDER;

  if ($tbl_exists('jos_admin_menus')) {
    // Your schema: id, name, route, parent_id, icon, orderby, status
    $T = 'jos_admin_menus';
    $has_icon = $col_exists($T,'icon');
    $icon_val = $has_icon ? "'menu'" : "NULL";

    // Find parent id by name (case-insensitive)
    $parentId = 0;
    $rp = $con->query("SELECT id FROM {$T} WHERE LOWER(name)=LOWER('{$parent_name}') LIMIT 1");
    if ($rp && ($pr = $rp->fetch_assoc())) $parentId = (int)$pr['id'];

    // Upsert only if not already present (by exact route OR exact name under same parent)
    $exists = $con->query("SELECT id FROM {$T} WHERE route='{$path}' OR (LOWER(name)=LOWER('{$page}') AND parent_id={$parentId}) LIMIT 1");
    if ($exists && $exists->num_rows==0){
      $con->query(
        "INSERT INTO {$T}(name, route, parent_id, ".($has_icon?'icon, ':'')."orderby, status)
         VALUES ('{$page}', '{$path}', ".($parentId?:'NULL').", ".($has_icon?"{$icon_val}, ":'')." {$ord}, 1)"
      );
      echo "Menu added in {$T} (name={$PAGE}, route={$path}).\n";
    } else {
      echo "Menu already exists in {$T} (skipped).\n";
    }

  } elseif ($tbl_exists('jos_admin_menu')) {
    // Old schema: name, slug, path, parent_id, orderby, status, is_tool
    $T = 'jos_admin_menu';
    $has_slug  = $col_exists($T,'slug');
    $has_path  = $col_exists($T,'path');
    $has_tool  = $col_exists($T,'is_tool');

    // Find parent: prefer slug if present, else fallback to name
    $parentId = 'NULL';
    if ($has_slug){
      $rp = $con->query("SELECT id FROM {$T} WHERE slug='{$parent_slug}' LIMIT 1");
      if ($rp && ($pr = $rp->fetch_assoc())) $parentId = (int)$pr['id'];
    } else {
      $rp = $con->query("SELECT id FROM {$T} WHERE LOWER(name)=LOWER('{$parent_name}') LIMIT 1");
      if ($rp && ($pr = $rp->fetch_assoc())) $parentId = (int)$pr['id'];
    }

    // Build columns / values dynamically
    $cols = ['name','orderby','status'];
    $vals = ["'{$page}'",$ord,1];
    if ($has_slug) { $cols[]='slug'; $vals[]="'{$slug}'"; }
    if ($has_path) { $cols[]='path'; $vals[]="'{$path}'"; }
    $cols[]='parent_id'; $vals[]= is_numeric($parentId) ? (string)$parentId : 'NULL';
    if ($has_tool){ $cols[]='is_tool'; $vals[]=0; }

    // Deduplicate by path/slug/name
    $whereParts = [];
    if ($has_path) $whereParts[] = "path='{$path}'";
    if ($has_slug) $whereParts[] = "slug='{$slug}'";
    $whereParts[] = "LOWER(name)=LOWER('{$page}')";
    $where = implode(' OR ', $whereParts);

    $exists = $con->query("SELECT id FROM {$T} WHERE {$where} LIMIT 1");
    if ($exists && $exists->num_rows==0){
      $con->query("INSERT INTO {$T}(".implode(',', $cols).") VALUES (".implode(',', $vals).")");
      echo "Menu added in {$T} (name={$PAGE}).\n";
    } else {
      echo "Menu already exists in {$T} (skipped).\n";
    }

  } else {
    echo "[WARN] No admin menu table found (looked for jos_admin_menus and jos_admin_menu). Menu not added.\n";
  }
}

