<?php
/* ============================================================
   subscription_plans.php — COMPLETE FILE
   - NO col_exists / SHOW COLUMNS
   - Features multi-select works on ADD + EDIT (and saves correctly)
   - Shows selected features on EDIT + shows selected preview chips
   - List page shows feature NAMES (not only count)
   ============================================================ */

/* ---------- DEV ERROR REPORTING (turn OFF on production) ---------- */
@ini_set('display_errors','1');
@ini_set('display_startup_errors','1');
@error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

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

/* ---------- page config ---------- */
$page_title = 'Subscription Plans';
$TABLE      = 'jos_app_subscription_plans';
$LOGTABLE   = 'jos_app_usersubscriptionlog';
$USERSTAB   = 'jos_app_users';
$FEATTABLE  = 'jos_app_userfeatures';
$PTTABLE    = 'jos_app_profile_types';
$MENUTABLE  = 'jos_admin_menus';

/* ---------- 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); }
function back_to_list($msg){ header('Location: '.keep_params(['add'=>null,'edit'=>null,'ok'=>$msg])); exit; }

/* ---------- menu title + perms (no schema checks) ---------- */
function fetch_menu_info(mysqli $con, string $script_name, string $menu_table, string $fallback_title): array {
  $out = ['title'=>$fallback_title, 'perms'=>['view'=>true,'add'=>true,'edit'=>true,'delete'=>true]];
  $script_base = basename($script_name);

  $stmt = @$con->prepare("SELECT menu_name FROM `$menu_table` WHERE status=1 AND menu_link LIKE CONCAT('%',?,'%') LIMIT 1");
  if ($stmt) {
    $stmt->bind_param("s", $script_base);
    $stmt->execute();
    $res = $stmt->get_result();
    if ($res && ($row = $res->fetch_assoc())) {
      if (!empty($row['menu_name'])) $out['title'] = $row['menu_name'];
    }
    $stmt->close();
  }
  return $out;
}

$menu_info  = fetch_menu_info($con, $_SERVER['PHP_SELF'] ?? __FILE__, $MENUTABLE, $page_title);
$page_title = $menu_info['title'] ?? $page_title;

function can_action($action) {
  global $menu_info;
  $action = strtolower((string)$action);
  return !empty($menu_info['perms'][$action]);
}

/* ---------- profile types & features (static columns per your DB) ---------- */
function fetch_profile_types(mysqli $con): array {
  $out = [];
  $rs = mysqli_query($con, "SELECT id, profile_name FROM `$GLOBALS[PTTABLE]` ORDER BY id");
  if ($rs) {
    while($r = mysqli_fetch_assoc($rs)){
      $out[(int)$r['id']] = (string)$r['profile_name'];
    }
  }
  return $out ?: [1=>'Employer',2=>'Job Seeker',3=>'Promoter'];
}

function fetch_features_flat(mysqli $con): array {
  $out = [];
  $rs = mysqli_query(
    $con,
    "SELECT id, name, COALESCE(profile_type,0) AS pt
     FROM `$GLOBALS[FEATTABLE]`
     WHERE status=1
     ORDER BY profile_type, orderby, name"
  );
  if ($rs) {
    while($r=mysqli_fetch_assoc($rs)){
      $out[] = ['id'=>(int)$r['id'],'name'=>(string)$r['name'],'pt'=>(int)$r['pt']];
    }
  }
  return $out;
}

function fetch_feature_name_map(mysqli $con): array {
  $map = [];
  $rs = mysqli_query($con, "SELECT id, name FROM `$GLOBALS[FEATTABLE]` WHERE status=1");
  if ($rs) {
    while($r=mysqli_fetch_assoc($rs)){
      $map[(int)$r['id']] = (string)$r['name'];
    }
  }
  return $map;
}

function parse_feature_ids($csv): array {
  $csv = trim((string)$csv);
  if ($csv === '') return [];
  $parts = preg_split('/\s*,\s*/', $csv);
  $ids = [];
  foreach ($parts as $p) {
    $p = trim($p);
    if ($p === '') continue;
    $ids[] = (int)$p;
  }
  $ids = array_values(array_unique(array_filter($ids, fn($x)=>$x>0)));
  sort($ids);
  return $ids;
}

/* ---------- flash ---------- */
$err = clean($_GET['err'] ?? '');
$ok  = clean($_GET['ok'] ?? '');

/* ---------- POST handling ---------- */
if ($_SERVER['REQUEST_METHOD']==='POST') {
  if (!verify_csrf($_POST['csrf'] ?? null)) {
    $err = 'Invalid request. Please refresh and try again.';
  } else {

    // delete
    if (isset($_POST['delete'])) {
      if (!can_action('delete')) { $err = 'Permission denied.'; }
      else {
        $id = (int)($_POST['id'] ?? 0);
        if ($id>0) {
          $stmt=$con->prepare("DELETE FROM `$TABLE` WHERE id=?");
          $stmt->bind_param("i",$id);
          $stmt->execute();
          $stmt->close();
          back_to_list('Deleted successfully');
        } else { $err='Invalid row selected.'; }
      }
    }

    // save (add/edit)
    if (isset($_POST['save']) && !$err) {
      if (!can_action('edit') && !can_action('add')) {
        $err = 'Permission denied.';
      } else {

        // IMPORTANT: keep correct id even if POST id is missing
        $id = (int)($_POST['id'] ?? 0);
        if ($id <= 0 && isset($_GET['edit'])) $id = (int)$_GET['edit'];

        $plan_name       = clean($_POST['plan_name'] ?? '');
        $profile_type    = (int)($_POST['profile_type'] ?? 0);
        $validity_months = (int)($_POST['validity_months'] ?? 0);
        $walkin_limit    = (int)($_POST['walkin_limit'] ?? 0);
        $vacancy_limit   = (int)($_POST['vacancy_limit'] ?? 0);
        $gst             = (float)($_POST['gst'] ?? 0);
        $final_amount    = (float)($_POST['final_amount'] ?? 0);

        // features multi select (ensure enabled on submit via JS below)
        $feat_ids_arr = array_map('intval', $_POST['features_ids'] ?? []);
        $feat_ids_arr = array_values(array_unique(array_filter($feat_ids_arr, fn($x)=>$x>0)));
        sort($feat_ids_arr);
        $features_csv = implode(',', $feat_ids_arr);

        $plan_status    = (int)($_POST['plan_status'] ?? 0);
        $premium_status = (int)($_POST['premium_status'] ?? 0);
        $display_status = (int)($_POST['display_status'] ?? 0);
        $plan_access    = clean($_POST['plan_access'] ?? '');
        $status         = (int)($_POST['status'] ?? 1);
        $orderby        = (int)($_POST['orderby'] ?? 0);

        if ($plan_name === '') { $err = 'Plan name is required.'; }
        if (!$err && $profile_type <= 0) { $err = 'Please choose a Profile Type.'; }

        /* ---------- duplicate check (ignore same id + only when changed) ---------- */
        if (!$err) {
          $old_name = '';
          $old_pt   = 0;

          if ($id > 0) {
            $st = $con->prepare("SELECT plan_name, profile_type FROM `$TABLE` WHERE id=? LIMIT 1");
            $st->bind_param("i", $id);
            $st->execute();
            $cur = $st->get_result()->fetch_assoc();
            $st->close();
            if ($cur) {
              $old_name = (string)$cur['plan_name'];
              $old_pt   = (int)$cur['profile_type'];
            }
          }

          $changed = (strtolower(trim($old_name)) !== strtolower(trim($plan_name))) || ((int)$old_pt !== (int)$profile_type);

          if ($changed) {
            if ($id > 0) {
              $dup = $con->prepare("SELECT id FROM `$TABLE` WHERE TRIM(LOWER(plan_name))=TRIM(LOWER(?)) AND profile_type=? AND id<>? LIMIT 1");
              $dup->bind_param("sii", $plan_name, $profile_type, $id);
            } else {
              $dup = $con->prepare("SELECT id FROM `$TABLE` WHERE TRIM(LOWER(plan_name))=TRIM(LOWER(?)) AND profile_type=? LIMIT 1");
              $dup->bind_param("si", $plan_name, $profile_type);
            }
            $dup->execute();
            $dup->store_result();
            if ($dup->num_rows > 0) $err = 'Duplicate plan for the same profile type.';
            $dup->close();
          }
        }

        // auto orderby if empty
        if (!$err && $orderby<=0){
          $r = mysqli_query($con,"SELECT COALESCE(MAX(orderby),0)+1 AS nxt FROM `$TABLE`");
          $orderby = (int)(mysqli_fetch_assoc($r)['nxt'] ?? 1);
        }

        // insert/update
        if (!$err) {
          if ($id > 0) {
            if (!can_action('edit')) {
              $err = 'Permission denied for edit.';
            } else {
              $sql = "UPDATE `$TABLE` SET
                        plan_name=?, profile_type=?, validity_months=?, walkin_limit=?, vacancy_limit=?,
                        gst=?, final_amount=?, features=?, plan_status=?, premium_status=?, display_status=?,
                        plan_access=?, status=?, orderby=?
                      WHERE id=?";
              $stmt = $con->prepare($sql);
              // 15 vars => 15 types
              $stmt->bind_param(
                "siiiiddsiiisiii",
                $plan_name, $profile_type, $validity_months, $walkin_limit, $vacancy_limit,
                $gst, $final_amount, $features_csv, $plan_status, $premium_status, $display_status,
                $plan_access, $status, $orderby, $id
              );
              $stmt->execute();
              $stmt->close();
              back_to_list('Saved successfully');
            }
          } else {
            if (!can_action('add')) {
              $err = 'Permission denied for add.';
            } else {
              $sql = "INSERT INTO `$TABLE`
                        (plan_name, profile_type, validity_months, walkin_limit, vacancy_limit, gst, final_amount, features,
                         plan_status, premium_status, display_status, plan_access, status, orderby, created_at)
                      VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW())";
              $stmt = $con->prepare($sql);
              // 14 vars => 14 types
              $stmt->bind_param(
                "siiiiddsiiisii",
                $plan_name, $profile_type, $validity_months, $walkin_limit, $vacancy_limit,
                $gst, $final_amount, $features_csv, $plan_status, $premium_status, $display_status,
                $plan_access, $status, $orderby
              );
              $stmt->execute();
              $stmt->close();
              back_to_list('Saved successfully');
            }
          }
        }
      }
    }
  }
}

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

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

<style>
.card { background: rgba(10,15,25,0.8); border-radius:12px; padding:20px; box-sizing:border-box; }
.card-head { display:flex; align-items:center; justify-content:space-between; margin-bottom:14px; gap:12px; }
.card-head .title { font-size:1.2rem; font-weight:600; margin:0; color: #e6eef6; }
.header-actions { display:flex; gap:8px; align-items:center; }
.btn-back { background:#2b3947; color:#fff; padding:8px 14px; border-radius:10px; border:1px solid rgba(255,255,255,0.08); text-decoration:none; font-size:0.95rem; transition:all .12s ease; display:inline-block; }
.btn-back:hover { transform:translateY(-1px); }
.btn-save-header { background:#009c5f; color:#fff; padding:8px 14px; border-radius:8px; border:none; cursor:pointer; }
.form-grid-3 { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:12px; }
@media(max-width:950px){ .form-grid-3{grid-template-columns:repeat(2,minmax(0,1fr));} }
@media(max-width:600px){ .form-grid-3{grid-template-columns:1fr;} .toolbar { flex-direction:column; align-items:stretch; } }
.toolbar { display:flex; gap:12px; align-items:center; flex-wrap:wrap; }
.toolbar .right { margin-left:auto; display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
.card .inp, .card input[type="text"], .card input[type="number"], .card select { box-sizing:border-box; width:100%; }
.flash-err { background:#4d2222; color:#ffdede; padding:8px 10px; border-radius:8px; }
.flash-ok  { background:#1f3b27; color:#c8f6d1; padding:8px 10px; border-radius:8px; }

#featuresSelect{
  background:#0b1220;
  border:1px solid #334155;
  border-radius:12px;
  padding:10px;
  color:#e6eef6;
  height:260px;
}
#featuresSelect option{ background:#0b1220; color:#e6eef6; }

.selected-preview{
  margin-top:10px;
  display:flex;
  flex-wrap:wrap;
  gap:8px;
}
.selected-preview .chip{
  background:#1f3b27;
  border:1px solid rgba(255,255,255,0.08);
  color:#fff;
  padding:6px 10px;
  border-radius:999px;
  font-size:12px;
  line-height:1;
}
.small-muted{ font-size:12px; opacity:0.85; }
</style>

<div class="master-wrap">
  <div class="headbar" style="display:flex;align-items:center;justify-content:space-between;gap:12px;">
    <h2 style="margin:0"><?=htmlspecialchars($page_title)?></h2>
    <div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;">
      <?php if($ok): ?><div class="flash-ok"><?=htmlspecialchars($ok)?></div><?php endif; ?>
      <?php if($err): ?><div class="flash-err"><?=htmlspecialchars($err)?></div><?php endif; ?>
    </div>
  </div>

<?php if($mode==='form'): ?>
  <?php
  $id = (int)($_GET['edit'] ?? 0);
  $row = [
    'plan_name'=>'','profile_type'=>0,'validity_months'=>0,'walkin_limit'=>0,'vacancy_limit'=>0,'gst'=>0,
    'final_amount'=>0,'features'=>'','plan_status'=>0,'premium_status'=>0,'display_status'=>0,'plan_access'=>'',
    'status'=>1,'orderby'=>0
  ];
  if ($id>0){
    $q=$con->prepare("SELECT * FROM `$TABLE` WHERE id=? LIMIT 1");
    $q->bind_param("i",$id);
    $q->execute();
    $res=$q->get_result();
    if($res && $res->num_rows) $row=$res->fetch_assoc();
    $q->close();
  }

  $pt_list  = fetch_profile_types($con);
  $features = fetch_features_flat($con);

  // Preselected features (EDIT) — robust parsing
  $selected = parse_feature_ids($row['features'] ?? '');
  $sel_map  = array_fill_keys($selected, true);
  ?>
  <div class="card">
    <div class="card-head">
      <h3 class="title"><?= $id>0 ? 'Edit Plan' : 'Add Plan' ?></h3>

      <div class="header-actions">
        <?php if ((($id>0 && can_action('edit')) || ($id===0 && can_action('add')))): ?>
          <button type="button" class="btn-save-header" id="headerSaveBtn">Save</button>
        <?php endif; ?>
        <a class="btn-back" href="<?= keep_params(['add'=>null,'edit'=>null]) ?>">Back to List</a>
      </div>
    </div>

    <form method="post" id="planForm">
      <input type="hidden" name="csrf" value="<?=htmlspecialchars(csrf_token())?>">
      <input type="hidden" name="id" value="<?= (int)$id ?>">
      <button type="submit" name="save" value="1" id="hiddenSaveBtn" style="position:absolute;left:-9999px;top:-9999px;"></button>

      <div class="form-grid-3">
        <label>Plan Name*<br><input class="inp" name="plan_name" value="<?=htmlspecialchars($row['plan_name'])?>" required></label>

        <label>Profile Type<br>
          <select class="inp" name="profile_type" id="profile_type" required>
            <option value="">-- Select --</option>
            <?php foreach($pt_list as $pid=>$pname): ?>
              <option value="<?=$pid?>" <?=$pid==(int)$row['profile_type']?'selected':''?>><?=htmlspecialchars($pname)?></option>
            <?php endforeach; ?>
          </select>
        </label>

        <label>Validity (months)<br><input class="inp" type="number" name="validity_months" value="<?= (int)$row['validity_months'] ?>"></label>

        <label>Premium Post Job Limit<br><input class="inp" type="number" name="walkin_limit" value="<?= (int)$row['walkin_limit'] ?>"></label>
        <label>Standard Job Post Limit<br><input class="inp" type="number" name="vacancy_limit" value="<?= (int)$row['vacancy_limit'] ?>"></label>
        <label>Final Amount<br><input class="inp" type="number" step="0.01" name="final_amount" value="<?= htmlspecialchars((string)$row['final_amount']) ?>"></label>

        <label>GST %<br><input class="inp" type="number" step="0.01" name="gst" value="<?= htmlspecialchars((string)$row['gst']) ?>"></label>
        <label>Order Level<br><input class="inp" type="number" name="orderby" value="<?= (int)$row['orderby'] ?>"></label>
        <label>Display Status (int)<br><input class="inp" type="number" name="display_status" value="<?= (int)$row['display_status'] ?>"></label>

        <label>Plan Status (0/1)<br><input class="inp" type="number" name="plan_status" value="<?= (int)$row['plan_status'] ?>"></label>
        <label>Premium Status (0/1)<br><input class="inp" type="number" name="premium_status" value="<?= (int)$row['premium_status'] ?>"></label>
        <label>Plan Access (text)<br><input class="inp" name="plan_access" value="<?= htmlspecialchars((string)$row['plan_access']) ?>"></label>
      </div>

      <!-- ================= FEATURES MULTI-SELECT ================= -->
      <div class="toolbar" style="margin:16px 0 8px">
        <strong>Features</strong>
        <span class="hint" id="featCount" style="margin-left:8px"></span>

        <div class="right">
          <input type="text" class="inp" id="featSearch" placeholder="Search features..." style="max-width:320px">
          <button type="button" class="btn secondary" id="featSelectAllBtn">Select All</button>
          <button type="button" class="btn secondary" id="featClearBtn">Clear</button>
        </div>
      </div>

      <label style="display:block">
        <select class="inp" name="features_ids[]" id="featuresSelect" multiple size="10">
          <?php foreach($features as $f):
            $isSel = isset($sel_map[$f['id']]); ?>
            <option value="<?=$f['id']?>" data-pt="<?=$f['pt']?>" <?=$isSel?'selected':''?>>
              <?=htmlspecialchars($f['name'])?><?= $f['pt'] ? " (PT ".$f['pt'].")" : "" ?>
            </option>
          <?php endforeach; ?>
        </select>

        <div class="small-muted" style="margin-top:6px">
          Tip: Hold <b>Ctrl</b> (Windows) / <b>Cmd</b> (Mac) to select multiple.
        </div>

        <div class="selected-preview" id="selectedPreview"></div>
      </label>
      <!-- ========================================================= -->

      <div class="toolbar" style="margin-top:14px">
        <label>Status<br>
          <select class="inp" name="status">
            <option value="1" <?=((int)$row['status']===1)?'selected':''?>>Active</option>
            <option value="0" <?=((int)$row['status']===0)?'selected':''?>>Inactive</option>
          </select>
        </label>
        <div class="right"></div>
      </div>
    </form>
  </div>

  <script>
  (function(){
    const form    = document.getElementById('planForm');
    const ptSel   = document.getElementById('profile_type');
    const sel     = document.getElementById('featuresSelect');
    const countEl = document.getElementById('featCount');
    const btnAll  = document.getElementById('featSelectAllBtn');
    const btnClr  = document.getElementById('featClearBtn');
    const search  = document.getElementById('featSearch');
    const preview = document.getElementById('selectedPreview');

    // header save triggers hidden submit
    const headerSave = document.getElementById('headerSaveBtn');
    if (headerSave) {
      headerSave.addEventListener('click', function(){
        const hidden = document.getElementById('hiddenSaveBtn');
        if (hidden) hidden.click();
      });
    }

    function getVisibleOptions(){
      return [...sel.options].filter(o => !o.hidden);
    }

    function syncCount(){
      const n = [...sel.options].filter(o => o.selected).length;
      if (countEl) countEl.textContent = '(' + n + ' selected)';
    }

    function syncPreview(){
      if (!preview) return;
      const chosen = [...sel.options].filter(o => o.selected).map(o => o.textContent.trim());
      preview.innerHTML = '';
      if (!chosen.length) return;
      chosen.slice(0, 40).forEach(t => {
        const s = document.createElement('span');
        s.className = 'chip';
        s.textContent = t;
        preview.appendChild(s);
      });
      if (chosen.length > 40) {
        const more = document.createElement('span');
        more.className = 'chip';
        more.textContent = '+' + (chosen.length - 40) + ' more';
        preview.appendChild(more);
      }
    }

    // FILTERING:
    // - NEVER disable options (disabled options are NOT submitted)
    // - Only hide non-matching; keep selected always visible
    function applyFilters(){
      const pt = parseInt(ptSel.value || '0', 10);
      const q  = (search && search.value) ? search.value.trim().toLowerCase() : '';

      [...sel.options].forEach(opt => {
        const fpt = parseInt(opt.dataset.pt || '0', 10);
        const byPT = (!pt || fpt === pt);
        const byQ  = (!q || (opt.textContent || '').toLowerCase().includes(q));

        // Keep selected visible even if search/pt doesn't match (so user sees what is saved)
        const show = (opt.selected) || (byPT && byQ);
        opt.hidden = !show;
      });

      syncCount();
      syncPreview();
    }

    function onPTChange(){
      // When PT changes, unselect features that don't match PT (business rule)
      const pt = parseInt(ptSel.value || '0', 10);
      if (pt) {
        [...sel.options].forEach(opt => {
          const fpt = parseInt(opt.dataset.pt || '0', 10);
          if (opt.selected && fpt !== pt) opt.selected = false;
        });
      }
      applyFilters();
    }

    if (btnAll) {
      btnAll.addEventListener('click', () => {
        // select all visible (after filtering)
        applyFilters();
        getVisibleOptions().forEach(opt => { opt.selected = true; });
        syncCount();
        syncPreview();
      });
    }

    if (btnClr) {
      btnClr.addEventListener('click', () => {
        [...sel.options].forEach(opt => opt.selected = false);
        applyFilters();
      });
    }

    if (sel) sel.addEventListener('change', () => { applyFilters(); });
    if (ptSel) ptSel.addEventListener('change', onPTChange);
    if (search) search.addEventListener('input', applyFilters);

    // IMPORTANT: before submit, show all options (so browser posts all selected)
    if (form) {
      form.addEventListener('submit', () => {
        [...sel.options].forEach(opt => { opt.hidden = false; });
      });
    }

    // initial
    applyFilters();
  })();
  </script>

<?php else: ?>
  <?php
  $q      = clean($_GET['q'] ?? '');
  $level  = (isset($_GET['level']) && $_GET['level']!=='') ? (int)$_GET['level'] : '';
  $sort   = clean($_GET['sort'] ?? 'order_asc');
  $view   = clean($_GET['view'] ?? 'last50');
  $no_rec = (int)($_GET['no_records'] ?? 0);

  $where = " WHERE 1=1 ";
  $binds=[]; $types='';

  if($q!==''){ $where .= " AND (plan_name LIKE CONCAT('%',?,'%')) "; $types.='s'; $binds[]=$q; }
  if($level!==''){ $where .= " AND orderby=? "; $types.='i'; $binds[]=(int)$level; }

  $order_sql = " ORDER BY orderby ASC, id DESC ";
  if($sort==='order_desc') $order_sql=" ORDER BY orderby DESC, id DESC ";
  if($sort==='name_asc')   $order_sql=" ORDER BY plan_name ASC ";
  if($sort==='name_desc')  $order_sql=" ORDER BY plan_name DESC ";
  if($sort==='id_desc')    $order_sql=" ORDER BY id DESC ";
  if($sort==='id_asc')     $order_sql=" ORDER BY id ASC ";

  $limit_sql = ($view==='all') ? "" : " LIMIT 50 ";
  $sql = "SELECT id, plan_name, profile_type, validity_months, final_amount, orderby, status, features
          FROM `$TABLE` $where $order_sql $limit_sql";
  $stmt = $con->prepare($sql);
  $rows = [];
  if($stmt){
    if($types) $stmt->bind_param($types, ...$binds);
    $stmt->execute();
    $rows = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
    $stmt->close();
  }

  $pt_names = fetch_profile_types($con);
  $feat_map = fetch_feature_name_map($con);

  // usage counts
  $ids = array_column($rows,'id');
  $counts = [];
  if ($ids) {
    $in = implode(',', array_map('intval',$ids));
    $q1 = mysqli_query($con,"SELECT plan_id AS pid, COUNT(*) c FROM `$LOGTABLE` WHERE plan_id IN ($in) GROUP BY plan_id");
    while($r=mysqli_fetch_assoc($q1)){ $counts[(int)$r['pid']] = ((int)($counts[(int)$r['pid']] ?? 0)) + (int)$r['c']; }

    $q2 = @mysqli_query($con,"SELECT active_plan_id AS pid, COUNT(*) c FROM `$USERSTAB` WHERE active_plan_id IN ($in) GROUP BY active_plan_id");
    if ($q2) {
      while($r=mysqli_fetch_assoc($q2)){ $counts[(int)$r['pid']] = ((int)($counts[(int)$r['pid']] ?? 0)) + (int)$r['c']; }
    }
  }

  if ($no_rec) {
    $rows = array_values(array_filter($rows, function($r) use($counts){
      return (int)($counts[(int)$r['id']] ?? 0)===0;
    }));
  }

  function feature_names_for_row(array $r, array $feat_map): array {
    $ids = parse_feature_ids($r['features'] ?? '');
    $names = [];
    foreach ($ids as $fid) {
      $names[] = $feat_map[$fid] ?? ('#'.$fid);
    }
    return $names;
  }
  ?>

  <div class="card">
    <div class="card-head">
      <h3 class="title">Subscription Plans</h3>
      <div>
        <?php if (can_action('add')): ?>
          <a class="btn-back" href="<?=keep_params(['add'=>1])?>">Add New</a>
        <?php endif; ?>
      </div>
    </div>

    <div class="table-wrap" style="max-height:70vh">
      <table class="table">
        <thead><tr>
          <th style="width:70px">SR No</th>
          <th>Name</th>
          <th style="width:180px">Profile Type</th>
          <th style="width:120px">Validity (m)</th>
          <th style="width:120px">Final Amount</th>
          <th style="width:120px">Order Level</th>
          <th style="width:260px">Features</th>
          <th style="width:110px">Usage</th>
          <th style="width:110px">Status</th>
          <th style="width:160px">Actions</th>
        </tr></thead>
        <tbody>
          <?php if(!$rows): ?>
            <tr><td colspan="10" class="muted">No plans found.</td></tr>
          <?php endif; ?>
          <?php $sr=1; foreach($rows as $r):
            $names = feature_names_for_row($r, $feat_map);
            $full  = implode(', ', $names);
            $short = $full;
            if (mb_strlen($short) > 70) $short = mb_substr($short, 0, 70).'...';
          ?>
            <tr>
              <td><?= $sr++ ?></td>
              <td><?= htmlspecialchars((string)$r['plan_name']) ?></td>
              <td><?= htmlspecialchars($pt_names[(int)$r['profile_type']] ?? (string)(int)$r['profile_type']) ?></td>
              <td><?= (int)$r['validity_months'] ?></td>
              <td><?= number_format((float)$r['final_amount'],2) ?></td>
              <td><?= (int)$r['orderby'] ?></td>
              <td title="<?=htmlspecialchars($full)?>"><?= htmlspecialchars($short ?: '-') ?></td>
              <td><?= (int)($counts[(int)$r['id']] ?? 0) ?></td>
              <td><?= ((int)$r['status']===1) ? '<span class="badge green">Active</span>' : '<span class="badge red">Inactive</span>' ?></td>
              <td>
                <?php if (can_action('edit')): ?>
                  <a class="btn secondary" href="<?=keep_params(['edit'=>$r['id']])?>">Edit</a>
                <?php endif; ?>
                <?php if (can_action('delete')): ?>
                  <form method="post" style="display:inline" onsubmit="return confirm('Delete this plan?')">
                    <input type="hidden" name="csrf" value="<?=htmlspecialchars(csrf_token())?>">
                    <input type="hidden" name="id" value="<?=$r['id']?>">
                    <button class="btn danger" name="delete" value="1">Delete</button>
                  </form>
                <?php endif; ?>
              </td>
            </tr>
          <?php endforeach; ?>
        </tbody>
      </table>
    </div>
  </div>

<?php endif; ?>

</div>
<?php
echo ob_get_clean();
