<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);

session_start();
require 'config.php';

/* ═══════════════════════════════
   ADMIN ACCESS
═══════════════════════════════ */
if (!isset($_SESSION['role']) || !in_array($_SESSION['role'], ['admin','superadmin'])) {
    die("Access Denied");
}

/* ═══════════════════════════════
   INLINE ROW UPDATE (AJAX)
   FIX: id + reporting_manager_id are VARCHAR(11) in the DB, not INT.
   They must be bound as strings ("s"), not "i". Using intval()+"i"
   silently mangled/zeroed IDs and caused 0-row updates that still
   reported "success" in the JSON response.
═══════════════════════════════ */
if (isset($_POST['inline_save'])) {
    header('Content-Type: application/json');

    $id = trim($_POST['id'] ?? '');
    // id is VARCHAR(11) — just require a non-empty value that fits the
    // column, don't assume it's purely numeric (some ID schemes use
    // prefixes/letters). The query is parameterized, so this is a
    // sanity check, not an injection guard.
    if ($id === '' || strlen($id) > 11) {
        echo json_encode(['ok'=>false,'msg'=>'Invalid ID']);
        exit;
    }

    $role        = $_POST['role']               ?? '';
    $level       = $_POST['level']               ?? '';
    $manager     = trim($_POST['manager']         ?? '');
    $division    = trim($_POST['division']       ?? '');
    $designation = trim($_POST['designation']    ?? '');
    $location    = trim($_POST['location']       ?? '');

    // reporting_manager_id is VARCHAR too — same rule: non-empty & fits
    // the column, else treat as "no manager" (NULL).
    $managerVal = ($manager === '' || strlen($manager) > 11) ? NULL : $manager;

    $stmt = $conn->prepare("UPDATE users SET role=?,level=?,reporting_manager_id=?,division=?,designation=?,location=? WHERE id=?");
    $stmt->bind_param("sssssss", $role, $level, $managerVal, $division, $designation, $location, $id);
    $ok = $stmt->execute();

    echo json_encode([
        'ok'  => $ok,
        'msg' => $ok ? ($stmt->affected_rows > 0 ? 'Saved' : 'No changes made') : $stmt->error
    ]);
    exit;
}

/* ═══════════════════════════════
   SAVE SINGLE ASSIGNMENT (FORM)
═══════════════════════════════ */
$success = "";
$error   = "";

if (isset($_POST['save'])) {
    $id = trim($_POST['user_id'] ?? '');

    if ($id === '' || strlen($id) > 11) {
        $error = "Please select an employee.";
    } else {
        $role        = $_POST['role']               ?? 'employee';
        $level       = $_POST['level']               ?? 'L1';
        $manager     = trim($_POST['manager']         ?? '');
        $division    = trim($_POST['division']       ?? '');
        $designation = trim($_POST['designation']    ?? '');
        $location    = trim($_POST['location']       ?? '');

        $managerVal = ($manager === '' || strlen($manager) > 11) ? NULL : $manager;

        $stmt = $conn->prepare("UPDATE users SET role=?,level=?,reporting_manager_id=?,division=?,designation=?,location=? WHERE id=?");
        $stmt->bind_param("sssssss", $role, $level, $managerVal, $division, $designation, $location, $id);

        if ($stmt->execute()) {
            $success = "Assignment saved successfully.";
        } else {
            $error = "Update failed: " . $stmt->error;
        }
    }
}

/* ═══════════════════════════════
   BULK MANAGER ASSIGNMENT
   FIX: same varchar-vs-int issue — ids and bulk_manager are strings.
═══════════════════════════════ */
if (isset($_POST['bulk_save'])) {
    $selected_ids = $_POST['selected_ids'] ?? [];
    $bulk_manager = trim($_POST['bulk_manager'] ?? '');

    if (empty($selected_ids)) {
        $error = "No employees selected.";
    } elseif ($bulk_manager === '' || strlen($bulk_manager) > 11) {
        $error = "Please select a manager for bulk assignment.";
    } else {
        // keep only non-empty IDs that fit the varchar(11) column
        $ids = array_values(array_filter(array_map('trim', $selected_ids), function($v) {
            return $v !== '' && strlen($v) <= 11;
        }));

        if (empty($ids)) {
            $error = "No valid employees selected.";
        } else {
            $placeholders = implode(',', array_fill(0, count($ids), '?'));
            $types  = str_repeat('s', count($ids) + 1); // +1 for bulk_manager
            $params = array_merge([$bulk_manager], $ids);

            $stmt = $conn->prepare("UPDATE users SET reporting_manager_id=? WHERE id IN ($placeholders)");
            $stmt->bind_param($types, ...$params);

            if ($stmt->execute()) {
                $success = count($ids) . " employee(s) manager updated.";
            } else {
                $error = "Bulk update failed: " . $stmt->error;
            }
        }
    }
}

/* ═══════════════════════════════
   FETCH DISTINCT VALUES
═══════════════════════════════ */
$divisions_list = [];
$div_res = $conn->query("SELECT DISTINCT division FROM users WHERE division IS NOT NULL AND division != '' ORDER BY division ASC");
if ($div_res) { while ($r = $div_res->fetch_assoc()) $divisions_list[] = $r['division']; }

$designations_list = [];
$desig_res = $conn->query("SELECT DISTINCT designation FROM users WHERE designation IS NOT NULL AND designation != '' ORDER BY designation ASC");
if ($desig_res) { while ($r = $desig_res->fetch_assoc()) $designations_list[] = $r['designation']; }

$locations_list = [];
$loc_res = $conn->query("SELECT DISTINCT location FROM users WHERE location IS NOT NULL AND location != '' ORDER BY location ASC");
if ($loc_res) { while ($r = $loc_res->fetch_assoc()) $locations_list[] = $r['location']; }

/* ═══════════════════════════════
   FETCH ALL DATA
═══════════════════════════════ */
$users = $conn->query("SELECT id,first_name,last_name,role,level,reporting_manager_id,division,designation,location FROM users WHERE status='active' ORDER BY first_name");
$users_data = [];
if ($users) { while ($r = $users->fetch_assoc()) $users_data[$r['id']] = $r; }

$managers = $conn->query("SELECT id,first_name,last_name FROM users WHERE role IN ('manager','admin','superadmin','md') AND status='active' ORDER BY first_name");
$managers_data = [];
if ($managers) { while ($r = $managers->fetch_assoc()) $managers_data[] = $r; }

$assigned = $conn->query("
    SELECT e.id, e.first_name, e.last_name, e.role, e.level, e.division, e.designation, e.location,
           e.reporting_manager_id,
           m.first_name AS manager_first, m.last_name AS manager_last
    FROM users e
    LEFT JOIN users m ON m.id = e.reporting_manager_id
    WHERE e.status='active'
    ORDER BY e.first_name
");

$filter_roles = $filter_levels = $filter_divs = $filter_mgrs = $filter_locs = [];
$all_rows = [];
if ($assigned) {
    while ($r = $assigned->fetch_assoc()) {
        $all_rows[] = $r;
        if ($r['role']     && !in_array($r['role'],     $filter_roles))  $filter_roles[]  = $r['role'];
        if ($r['level']    && !in_array($r['level'],    $filter_levels)) $filter_levels[] = $r['level'];
        if ($r['division'] && !in_array($r['division'], $filter_divs))   $filter_divs[]   = $r['division'];
        if ($r['location'] && !in_array($r['location'], $filter_locs))   $filter_locs[]   = $r['location'];
        $mn = trim(($r['manager_first']??'').' '.($r['manager_last']??''));
        if ($mn && !in_array($mn, $filter_mgrs)) $filter_mgrs[] = $mn;
    }
    sort($filter_roles); sort($filter_levels); sort($filter_divs); sort($filter_mgrs); sort($filter_locs);
}

$divisions_json    = json_encode($divisions_list);
$designations_json = json_encode($designations_list);
$locations_json    = json_encode($locations_list);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Employee Assignment — Admin Panel</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700;1,9..40,400&family=Syne:wght@600;700;800&display=swap" rel="stylesheet">
<style>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{
  --navy:#0d1b2a;--teal:#0ea5a0;--teal2:#0ccfc9;--amber:#f59e0b;
  --surface:#f0f4f8;--card:#fff;--border:#dde3ec;
  --text:#1e293b;--muted:#64748b;--danger:#ef4444;--success:#10b981;
  --shadow:0 4px 24px rgba(13,27,42,.10);--radius:14px;
}
body{font-family:'DM Sans',sans-serif;background:var(--surface);color:var(--text);min-height:100vh}

.topnav{background:var(--navy);padding:0 2.5rem;height:60px;display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:200;box-shadow:0 2px 16px rgba(0,0,0,.25)}
.topnav-brand{font-family:'Syne',sans-serif;font-weight:800;font-size:1.1rem;color:#fff;display:flex;align-items:center;gap:10px}
.topnav-brand span{background:linear-gradient(135deg,var(--teal),var(--teal2));color:#fff;font-size:.65rem;font-weight:700;padding:2px 8px;border-radius:20px;text-transform:uppercase}
.back-btn{display:inline-flex;align-items:center;gap:6px;background:rgba(255,255,255,.08);color:rgba(255,255,255,.85);border:1px solid rgba(255,255,255,.12);padding:6px 16px;border-radius:8px;font-size:.82rem;font-weight:500;text-decoration:none;transition:.2s}
.back-btn:hover{background:rgba(255,255,255,.15);color:#fff}

.page{max-width:1400px;margin:0 auto;padding:2.5rem 1.5rem 4rem}
.page-header{margin-bottom:2rem}
.page-header h1{font-family:'Syne',sans-serif;font-size:1.75rem;font-weight:700;color:var(--navy)}
.page-header p{color:var(--muted);margin-top:4px;font-size:.9rem}

.alert{display:flex;align-items:center;gap:12px;padding:14px 20px;border-radius:10px;font-size:.9rem;font-weight:500;margin-bottom:1.5rem;animation:slideIn .35s ease}
.alert-success{background:#ecfdf5;border:1px solid #6ee7b7;color:#065f46}
.alert-danger{background:#fef2f2;border:1px solid #fca5a5;color:#991b1b}
@keyframes slideIn{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}

.card{background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow);border:1px solid var(--border);margin-bottom:2rem;overflow:hidden}
.card-head{padding:1.25rem 1.75rem;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:12px}
.card-head-icon{width:38px;height:38px;border-radius:10px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.icon-teal{background:rgba(14,165,160,.12);color:var(--teal)}
.icon-navy{background:rgba(13,27,42,.08);color:var(--navy)}
.card-head h3{font-family:'Syne',sans-serif;font-weight:700;font-size:1rem;color:var(--navy)}
.card-head p{font-size:.78rem;color:var(--muted);margin-top:1px}
.card-body{padding:1.75rem}

.form-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:1.25rem}
.form-grid-5{display:grid;grid-template-columns:repeat(5,1fr);gap:1.25rem;margin-top:1.25rem}
.field label{display:block;font-size:.78rem;font-weight:600;color:var(--muted);letter-spacing:.05em;text-transform:uppercase;margin-bottom:6px}
.field select,.field input{width:100%;padding:10px 14px;border:1.5px solid var(--border);border-radius:9px;font-family:'DM Sans',sans-serif;font-size:.88rem;color:var(--text);background:#fff;transition:.2s}
.field select{appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2.5'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 12px center;padding-right:36px;cursor:pointer}
.field select:focus,.field input:focus{outline:none;border-color:var(--teal);box-shadow:0 0 0 3px rgba(14,165,160,.12)}
.form-divider{height:1px;background:var(--border);margin:1.5rem 0}
.form-actions{display:flex;align-items:center;gap:12px;margin-top:1.5rem}

/* COMBOBOX */
.combo-wrap{position:relative}
.combo-wrap input{padding-right:36px}
.combo-arrow{position:absolute;right:12px;top:50%;transform:translateY(-50%);pointer-events:none;color:var(--muted)}
.combo-dropdown{position:absolute;top:calc(100% + 4px);left:0;right:0;background:#fff;border:1.5px solid var(--teal);border-radius:9px;box-shadow:0 8px 24px rgba(13,27,42,.12);z-index:300;max-height:220px;overflow-y:auto;display:none}
.combo-dropdown.open{display:block}
.combo-item{padding:9px 14px;font-size:.87rem;color:var(--text);cursor:pointer;transition:background .12s}
.combo-item:hover,.combo-item.active{background:rgba(14,165,160,.09);color:var(--teal)}
.combo-item.no-match{color:var(--muted);font-style:italic;cursor:default}
.combo-item.no-match:hover{background:none;color:var(--muted)}

.btn-primary{display:inline-flex;align-items:center;gap:8px;background:linear-gradient(135deg,#0d8f8b,var(--teal));color:#fff;border:none;padding:11px 26px;border-radius:9px;font-family:'DM Sans',sans-serif;font-size:.9rem;font-weight:600;cursor:pointer;transition:.15s;box-shadow:0 4px 14px rgba(14,165,160,.35)}
.btn-primary:hover{transform:translateY(-1px);box-shadow:0 6px 20px rgba(14,165,160,.45)}
.btn-amber{display:inline-flex;align-items:center;gap:8px;background:linear-gradient(135deg,#d97706,var(--amber));color:#fff;border:none;padding:11px 26px;border-radius:9px;font-family:'DM Sans',sans-serif;font-size:.9rem;font-weight:600;cursor:pointer;transition:.15s;box-shadow:0 4px 14px rgba(245,158,11,.35)}
.btn-amber:hover{transform:translateY(-1px)}
.btn-amber:disabled{opacity:.45;cursor:not-allowed;transform:none}
.btn-reset{display:inline-flex;align-items:center;gap:6px;background:transparent;color:var(--muted);border:1.5px solid var(--border);padding:10px 20px;border-radius:9px;font-family:'DM Sans',sans-serif;font-size:.9rem;font-weight:500;cursor:pointer;transition:.2s}
.btn-reset:hover{border-color:#b0bec5;color:var(--text)}
.btn-icon{display:inline-flex;align-items:center;justify-content:center;width:29px;height:29px;border-radius:7px;border:none;cursor:pointer;transition:.15s}
.btn-edit-row{background:rgba(14,165,160,.10);color:var(--teal)}
.btn-edit-row:hover{background:rgba(14,165,160,.22)}
.btn-save-inline{background:rgba(16,185,129,.12);color:#059669}
.btn-save-inline:hover{background:rgba(16,185,129,.25)}
.btn-cancel-inline{background:rgba(100,116,139,.1);color:var(--muted)}
.btn-cancel-inline:hover{background:rgba(100,116,139,.2)}

/* BULK */
.bulk-panel{display:none;align-items:center;gap:14px;padding:12px 1.75rem;background:#fffbeb;border-bottom:1px solid #fde68a;flex-wrap:wrap}
.bulk-panel.active{display:flex}
.bulk-count{font-size:.85rem;font-weight:600;color:#92400e}

/* FILTER BAR */
.filter-bar{display:flex;align-items:flex-end;gap:10px;padding:14px 1.75rem 12px;border-bottom:1px solid var(--border);background:#f8fafc;flex-wrap:wrap}
.ff label{display:block;font-size:.7rem;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:4px}
.ff select,.ff input[type="text"]{padding:7px 10px;border:1.5px solid var(--border);border-radius:8px;font-family:'DM Sans',sans-serif;font-size:.82rem;color:var(--text);background:#fff;min-width:110px;transition:.2s}
.ff select{appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2.5'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 7px center;padding-right:24px;cursor:pointer}
.ff select:focus,.ff input[type="text"]:focus{outline:none;border-color:var(--teal)}
.ff-search{position:relative}
.ff-search svg{position:absolute;left:9px;top:50%;transform:translateY(-50%);color:var(--muted);pointer-events:none}
.ff-search input{padding-left:28px;min-width:190px}
.btn-clear-f{display:inline-flex;align-items:center;gap:5px;background:transparent;color:var(--muted);border:1.5px solid var(--border);padding:7px 13px;border-radius:8px;font-family:'DM Sans',sans-serif;font-size:.8rem;cursor:pointer;transition:.2s;white-space:nowrap}
.btn-clear-f:hover{border-color:#adb5c5;color:var(--text)}

/* TOOLBAR */
.table-toolbar{display:flex;align-items:center;justify-content:space-between;padding:1rem 1.75rem;border-bottom:1px solid var(--border);gap:1rem;flex-wrap:wrap}
.table-toolbar h4{font-family:'Syne',sans-serif;font-size:.95rem;color:var(--navy);font-weight:700}
.count-pill{background:var(--teal);color:#fff;font-size:.7rem;font-weight:700;padding:2px 9px;border-radius:20px;margin-left:8px}

/* TABLE */
.table-wrap{overflow-x:auto}
table{width:100%;border-collapse:separate;border-spacing:0;font-size:.84rem}
thead th{background:#f8fafc;padding:10px 11px;font-size:.69rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);border-bottom:1.5px solid var(--border);white-space:nowrap;text-align:left}
thead th:first-child,thead th:last-child{text-align:center}
tbody tr{transition:background .15s;cursor:pointer}
tbody tr:hover:not(.editing-row){background:#f8fafc}
tbody tr.row-selected{background:#fffbeb!important}
tbody tr.editing-row{background:#f0fdf4!important;cursor:default}
tbody td{padding:10px 11px;border-bottom:1px solid #eef1f6;color:var(--text);vertical-align:middle}
tbody tr:last-child td{border-bottom:none}
tbody td:first-child,tbody td:last-child{cursor:default;text-align:center}

/* INLINE EDIT */
.cell-display{display:block}
.cell-edit{display:none}
.editing-row .cell-display{display:none}
.editing-row .cell-edit{display:block}
.act-display{display:inline-flex}
.act-edit{display:none;gap:4px;align-items:center}
.editing-row .act-display{display:none}
.editing-row .act-edit{display:inline-flex}
.isel{width:100%;padding:5px 22px 5px 7px;border:1.5px solid var(--teal);border-radius:6px;font-family:'DM Sans',sans-serif;font-size:.8rem;color:var(--text);background:#fff;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='9' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2.5'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 5px center;outline:none;cursor:pointer}
.iinput{width:100%;padding:5px 7px;border:1.5px solid var(--teal);border-radius:6px;font-family:'DM Sans',sans-serif;font-size:.8rem;color:var(--text);background:#fff;outline:none}

/* INLINE COMBO */
.icombo-wrap{position:relative}
.icombo-wrap .iinput{padding-right:22px}
.icombo-dd{position:absolute;top:calc(100% + 2px);left:0;right:0;background:#fff;border:1.5px solid var(--teal);border-radius:6px;box-shadow:0 6px 18px rgba(13,27,42,.13);z-index:400;max-height:160px;overflow-y:auto;display:none}
.icombo-dd.open{display:block}
.icombo-item{padding:6px 9px;font-size:.78rem;color:var(--text);cursor:pointer;transition:background .1s}
.icombo-item:hover,.icombo-item.hi{background:rgba(14,165,160,.09);color:var(--teal)}
.icombo-item.nm{color:var(--muted);font-style:italic;cursor:default}
.icombo-item.nm:hover{background:none;color:var(--muted)}

/* CHECKBOX */
.cb-wrap{display:flex;align-items:center;justify-content:center}
input[type="checkbox"]{width:16px;height:16px;border-radius:4px;accent-color:var(--teal);cursor:pointer}

/* BADGES */
.badge{display:inline-block;padding:3px 10px;border-radius:20px;font-size:.72rem;font-weight:600;white-space:nowrap}
.badge-role-employee{background:#eff6ff;color:#1d4ed8}
.badge-role-manager{background:#fefce8;color:#854d0e}
.badge-role-admin{background:#fdf4ff;color:#7e22ce}
.badge-role-superadmin{background:#fef2f2;color:#9f1239}
.badge-role-md{background:#ecfdf5;color:#065f46}
.badge-level{background:#f0fdf4;color:#166534}
.badge-div{background:#f0f9ff;color:#075985}
.badge-loc{background:#fdf4ff;color:#6b21a8}
.no-data{color:var(--muted);font-style:italic;font-size:.82rem}
.no-results-row td{text-align:center;padding:40px;color:var(--muted)}

/* TOAST */
.toast{position:fixed;bottom:2rem;right:2rem;padding:12px 20px;border-radius:10px;font-size:.87rem;font-weight:500;box-shadow:0 6px 24px rgba(0,0,0,.2);display:none;z-index:999;animation:slideIn .3s ease}
.toast-ok{background:#0d1b2a;color:#fff}
.toast-err{background:#fef2f2;border:1px solid #fca5a5;color:#991b1b}
.toast.show{display:block}

@media(max-width:900px){
  .form-grid-2,.form-grid-5{grid-template-columns:1fr 1fr}
  .topnav{padding:0 1rem}
  .page{padding:1.5rem 1rem 3rem}
}
@media(max-width:560px){
  .form-grid-2,.form-grid-5{grid-template-columns:1fr}
}
</style>
</head>
<body>

<nav class="topnav">
  <div class="topnav-brand">
    <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#0ea5a0" stroke-width="2.2"><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 3.6-7 8-7s8 3 8 7"/></svg>
    HRM Portal <span>Admin</span>
  </div>
  <a href="dashboard_admin.php" class="back-btn">
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M19 12H5M12 5l-7 7 7 7"/></svg>
    Dashboard
  </a>
</nav>

<div class="page">

  <div class="page-header">
    <h1>Employee Assignment</h1>
    <p>Assign roles, levels, divisions, locations and managers. Use the top form or edit cells directly in the table below.</p>
  </div>

  <?php if ($success): ?>
  <div class="alert alert-success"><span>✅</span> <?= htmlspecialchars($success) ?></div>
  <?php endif; ?>
  <?php if ($error): ?>
  <div class="alert alert-danger"><span>⚠️</span> <?= htmlspecialchars($error) ?></div>
  <?php endif; ?>

  <!-- ═══════════════ FORM CARD ═══════════════ -->
  <div class="card">
    <div class="card-head">
      <div class="card-head-icon icon-teal">
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75"/></svg>
      </div>
      <div>
        <h3>New / Edit Assignment</h3>
        <p>Select an employee or click any table row to auto-fill this form.</p>
      </div>
    </div>
    <div class="card-body">
      <form method="post" id="assignForm">

        <!-- Row 1: Employee + Manager -->
        <div class="form-grid-2">
          <div class="field">
            <label>Employee *</label>
            <select name="user_id" id="sel_user" required>
              <option value="">— Select Employee —</option>
              <?php foreach ($users_data as $u): ?>
              <option value="<?= htmlspecialchars($u['id']) ?>"
                data-role="<?= htmlspecialchars($u['role']??'') ?>"
                data-level="<?= htmlspecialchars($u['level']??'') ?>"
                data-mgr="<?= htmlspecialchars($u['reporting_manager_id']??'') ?>"
                data-div="<?= htmlspecialchars($u['division']??'') ?>"
                data-desig="<?= htmlspecialchars($u['designation']??'') ?>"
                data-loc="<?= htmlspecialchars($u['location']??'') ?>">
                <?= htmlspecialchars($u['first_name'].' '.$u['last_name']) ?> (ID <?= htmlspecialchars($u['id']) ?>)
              </option>
              <?php endforeach; ?>
            </select>
          </div>
          <div class="field">
            <label>Reporting Manager</label>
            <select name="manager" id="sel_manager">
              <option value="">— None —</option>
              <?php foreach ($managers_data as $m): ?>
              <option value="<?= htmlspecialchars($m['id']) ?>"><?= htmlspecialchars($m['first_name'].' '.$m['last_name']) ?> (ID <?= htmlspecialchars($m['id']) ?>)</option>
              <?php endforeach; ?>
            </select>
          </div>
        </div>

        <div class="form-divider"></div>

        <!-- Row 2: Role + Level + Division + Designation + Location -->
        <div class="form-grid-5">
          <div class="field">
            <label>Role</label>
            <select name="role" id="sel_role" required>
              <option value="">-- Role --</option>
              <option value="employee">Employee</option>
              <option value="manager">Manager</option>
              <option value="admin">Admin</option>
              <option value="superadmin">Super Admin</option>
              <option value="md">MD</option>
            </select>
          </div>
          <div class="field">
            <label>Level</label>
            <select name="level" id="sel_level" required>
              <option value="">-- Level --</option>
              <option>L1</option><option>L2</option><option>L3</option><option>L4</option><option>L5</option>
            </select>
          </div>

          <!-- DIVISION COMBO -->
          <div class="field">
            <label>Division</label>
            <div class="combo-wrap" id="divComboWrap">
              <input type="text" name="division" id="inp_division"
                placeholder="Type or select…" maxlength="100" autocomplete="off"
                oninput="comboInput('div')" onfocus="comboOpen('div')" onkeydown="comboKey(event,'div')">
              <span class="combo-arrow">
                <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="6 9 12 15 18 9"/></svg>
              </span>
              <div class="combo-dropdown" id="divComboDD"></div>
            </div>
          </div>

          <!-- DESIGNATION COMBO -->
          <div class="field">
            <label>Designation</label>
            <div class="combo-wrap" id="desigComboWrap">
              <input type="text" name="designation" id="inp_designation"
                placeholder="Type or select…" maxlength="150" autocomplete="off"
                oninput="comboInput('desig')" onfocus="comboOpen('desig')" onkeydown="comboKey(event,'desig')">
              <span class="combo-arrow">
                <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="6 9 12 15 18 9"/></svg>
              </span>
              <div class="combo-dropdown" id="desigComboDD"></div>
            </div>
          </div>

          <!-- LOCATION COMBO -->
          <div class="field">
            <label>Location</label>
            <div class="combo-wrap" id="locComboWrap">
              <input type="text" name="location" id="inp_location"
                placeholder="Type or select…" maxlength="100" autocomplete="off"
                oninput="comboInput('loc')" onfocus="comboOpen('loc')" onkeydown="comboKey(event,'loc')">
              <span class="combo-arrow">
                <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="6 9 12 15 18 9"/></svg>
              </span>
              <div class="combo-dropdown" id="locComboDD"></div>
            </div>
          </div>

        </div>

        <div class="form-actions">
          <button type="submit" name="save" class="btn-primary">
            <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg>
            Save Assignment
          </button>
          <button type="button" class="btn-reset" onclick="resetForm()">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/></svg>
            Reset
          </button>
        </div>
      </form>
    </div>
  </div>

  <!-- ═══════════════ TABLE CARD ═══════════════ -->
  <div class="card">

    <!-- TOOLBAR -->
    <div class="table-toolbar">
      <div style="display:flex;align-items:center;">
        <div class="card-head-icon icon-navy" style="margin-right:12px;">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 21V9"/></svg>
        </div>
        <div>
          <h4>Assigned Employees <span class="count-pill" id="rowCount">0</span></h4>
          <p style="font-size:.75rem;color:var(--muted);margin-top:1px;">
            Click pencil icon or row to edit inline &nbsp;•&nbsp; Check boxes to bulk-assign manager
          </p>
        </div>
      </div>
    </div>

    <!-- FILTER BAR -->
    <div class="filter-bar">
      <div class="ff ff-search">
        <label>Search</label>
        <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
        <input type="text" id="fSearch" placeholder="Name, division, location…" oninput="applyFilters()">
      </div>
      <div class="ff">
        <label>Role</label>
        <select id="fRole" onchange="applyFilters()">
          <option value="">All Roles</option>
          <?php foreach ($filter_roles as $r): ?>
          <option value="<?= htmlspecialchars(strtolower($r)) ?>"><?= ucfirst(htmlspecialchars($r)) ?></option>
          <?php endforeach; ?>
        </select>
      </div>
      <div class="ff">
        <label>Level</label>
        <select id="fLevel" onchange="applyFilters()">
          <option value="">All Levels</option>
          <?php foreach ($filter_levels as $l): ?>
          <option value="<?= htmlspecialchars($l) ?>"><?= htmlspecialchars($l) ?></option>
          <?php endforeach; ?>
        </select>
      </div>
      <div class="ff">
        <label>Division</label>
        <select id="fDiv" onchange="applyFilters()">
          <option value="">All Divisions</option>
          <?php foreach ($filter_divs as $d): ?>
          <option value="<?= htmlspecialchars(strtolower($d)) ?>"><?= htmlspecialchars($d) ?></option>
          <?php endforeach; ?>
        </select>
      </div>
      <div class="ff">
        <label>Location</label>
        <select id="fLoc" onchange="applyFilters()">
          <option value="">All Locations</option>
          <?php foreach ($filter_locs as $lc): ?>
          <option value="<?= htmlspecialchars(strtolower($lc)) ?>"><?= htmlspecialchars($lc) ?></option>
          <?php endforeach; ?>
        </select>
      </div>
      <div class="ff">
        <label>Manager</label>
        <select id="fMgr" onchange="applyFilters()">
          <option value="">All Managers</option>
          <?php foreach ($filter_mgrs as $mn): ?>
          <option value="<?= htmlspecialchars(strtolower($mn)) ?>"><?= htmlspecialchars($mn) ?></option>
          <?php endforeach; ?>
        </select>
      </div>
      <button class="btn-clear-f" onclick="clearFilters()" type="button">
        <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6"/></svg>
        Clear
      </button>
    </div>

    <!-- BULK ASSIGN PANEL -->
    <form method="post" id="bulkForm">
      <div class="bulk-panel" id="bulkPanel">
        <div class="bulk-count" id="bulkCount">0 selected</div>
        <div class="ff" style="min-width:230px;">
          <label style="color:#92400e;">Assign Reporting Manager</label>
          <select name="bulk_manager" id="bulk_manager_sel" style="border-color:#fcd34d;min-width:220px;" onchange="updateBulkBtn()">
            <option value="">— Select Manager —</option>
            <?php foreach ($managers_data as $m): ?>
            <option value="<?= htmlspecialchars($m['id']) ?>"><?= htmlspecialchars($m['first_name'].' '.$m['last_name']) ?></option>
            <?php endforeach; ?>
          </select>
        </div>
        <button type="submit" name="bulk_save" class="btn-amber" id="bulkSaveBtn" disabled>
          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75"/></svg>
          Apply to Selected
        </button>
        <button type="button" class="btn-reset" onclick="clearAllChecks()">Deselect All</button>
        <div id="hiddenIds"></div>
      </div>
    </form>

    <!-- TABLE -->
    <div class="table-wrap">
      <table id="assignTable">
        <thead>
          <tr>
            <th><div class="cb-wrap"><input type="checkbox" id="checkAll" onchange="toggleAll(this)" title="Select all"></div></th>
            <th>ID</th>
            <th>Employee</th>
            <th>Reporting Manager</th>
            <th>Role</th>
            <th>Level</th>
            <th>Division</th>
            <th>Designation</th>
            <th>Location</th>
            <th>Action</th>
          </tr>
        </thead>
        <tbody>
<?php if (empty($all_rows)): ?>
          <tr class="no-results-row"><td colspan="10">No assigned employees found.</td></tr>
<?php else: ?>
<?php foreach ($all_rows as $row):
    $id          = $row['id'];
    $firstName   = $row['first_name']    ?? '';
    $lastName    = $row['last_name']     ?? '';
    $role        = $row['role']          ?? '';
    $level       = $row['level']         ?? '';
    $division    = $row['division']      ?? '';
    $designation = $row['designation']   ?? '';
    $location    = $row['location']      ?? '';
    $mgrId       = $row['reporting_manager_id'] ?? '';
    $mgrFirst    = $row['manager_first'] ?? '';
    $mgrLast     = $row['manager_last']  ?? '';
    $mgrName     = trim($mgrFirst.' '.$mgrLast);
    $roleBadge   = 'badge-role-'.strtolower($role);
?>
          <tr
            data-id="<?= htmlspecialchars($id) ?>"
            data-name="<?= htmlspecialchars(strtolower($firstName.' '.$lastName)) ?>"
            data-role="<?= htmlspecialchars(strtolower($role)) ?>"
            data-level="<?= htmlspecialchars($level) ?>"
            data-mgr="<?= htmlspecialchars($mgrId) ?>"
            data-mgrname="<?= htmlspecialchars(strtolower($mgrName)) ?>"
            data-div="<?= htmlspecialchars(strtolower($division)) ?>"
            data-desig="<?= htmlspecialchars(strtolower($designation)) ?>"
            data-loc="<?= htmlspecialchars(strtolower($location)) ?>"
            onclick="rowClick(event,this)"
          >
            <!-- CHECKBOX -->
            <td onclick="event.stopPropagation()">
              <div class="cb-wrap">
                <input type="checkbox" class="row-cb" value="<?= htmlspecialchars($id) ?>"
                  onchange="checkboxChanged(this)" onclick="event.stopPropagation()">
              </div>
            </td>

            <!-- ID -->
            <td style="color:var(--muted);font-size:.78rem;font-weight:600;">#<?= htmlspecialchars($id) ?></td>

            <!-- NAME -->
            <td style="font-weight:500;"><?= htmlspecialchars($firstName.' '.$lastName) ?></td>

            <!-- MANAGER -->
            <td>
              <span class="cell-display">
                <?php if ($mgrName): ?>
                  <span style="display:flex;align-items:center;gap:5px;">
                    <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="var(--teal)" stroke-width="2.5"><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 3.6-7 8-7s8 3 8 7"/></svg>
                    <?= htmlspecialchars($mgrName) ?>
                  </span>
                <?php else: ?><span class="no-data">Not Assigned</span><?php endif; ?>
              </span>
              <span class="cell-edit">
                <select class="isel" data-field="manager" onclick="event.stopPropagation()">
                  <option value="">— None —</option>
                  <?php foreach ($managers_data as $m): ?>
                  <option value="<?= htmlspecialchars($m['id']) ?>" <?= ((string)$m['id']===(string)$mgrId)?'selected':'' ?>>
                    <?= htmlspecialchars($m['first_name'].' '.$m['last_name']) ?>
                  </option>
                  <?php endforeach; ?>
                </select>
              </span>
            </td>

            <!-- ROLE -->
            <td>
              <span class="cell-display"><span class="badge <?= htmlspecialchars($roleBadge) ?>"><?= ucfirst(htmlspecialchars($role)) ?></span></span>
              <span class="cell-edit">
                <select class="isel" data-field="role" onclick="event.stopPropagation()">
                  <?php foreach (['employee','manager','admin','superadmin','md'] as $rv): ?>
                  <option value="<?= $rv ?>" <?= ($rv===$role)?'selected':'' ?>><?= ucfirst($rv) ?></option>
                  <?php endforeach; ?>
                </select>
              </span>
            </td>

            <!-- LEVEL -->
            <td>
              <span class="cell-display"><span class="badge badge-level"><?= htmlspecialchars($level) ?></span></span>
              <span class="cell-edit">
                <select class="isel" data-field="level" onclick="event.stopPropagation()">
                  <?php foreach (['L1','L2','L3','L4','L5'] as $lv): ?>
                  <option value="<?= $lv ?>" <?= ($lv===$level)?'selected':'' ?>><?= $lv ?></option>
                  <?php endforeach; ?>
                </select>
              </span>
            </td>

            <!-- DIVISION — inline combobox -->
            <td>
              <span class="cell-display"><span class="badge badge-div"><?= htmlspecialchars($division ?: '—') ?></span></span>
              <span class="cell-edit">
                <div class="icombo-wrap" onclick="event.stopPropagation()">
                  <input class="iinput" type="text" data-field="division"
                    value="<?= htmlspecialchars($division) ?>" maxlength="100" autocomplete="off"
                    oninput="icomboInput(this,'div')" onfocus="icomboOpen(this,'div')" onkeydown="icomboKey(event,this,'div')">
                  <div class="icombo-dd" id="idd_div_<?= htmlspecialchars($id) ?>"></div>
                </div>
              </span>
            </td>

            <!-- DESIGNATION — inline combobox -->
            <td>
              <span class="cell-display" style="color:var(--muted);"><?= htmlspecialchars($designation ?: '—') ?></span>
              <span class="cell-edit">
                <div class="icombo-wrap" onclick="event.stopPropagation()">
                  <input class="iinput" type="text" data-field="designation"
                    value="<?= htmlspecialchars($designation) ?>" maxlength="150" autocomplete="off"
                    oninput="icomboInput(this,'desig')" onfocus="icomboOpen(this,'desig')" onkeydown="icomboKey(event,this,'desig')">
                  <div class="icombo-dd" id="idd_desig_<?= htmlspecialchars($id) ?>"></div>
                </div>
              </span>
            </td>

            <!-- LOCATION — inline combobox -->
            <td>
              <span class="cell-display">
                <?php if ($location): ?>
                  <span class="badge badge-loc" style="display:inline-flex;align-items:center;gap:4px;">
                    <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M21 10c0 7-9 13-9 13S3 17 3 10a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>
                    <?= htmlspecialchars($location) ?>
                  </span>
                <?php else: ?><span class="no-data">—</span><?php endif; ?>
              </span>
              <span class="cell-edit">
                <div class="icombo-wrap" onclick="event.stopPropagation()">
                  <input class="iinput" type="text" data-field="location"
                    value="<?= htmlspecialchars($location) ?>" maxlength="100" autocomplete="off"
                    oninput="icomboInput(this,'loc')" onfocus="icomboOpen(this,'loc')" onkeydown="icomboKey(event,this,'loc')">
                  <div class="icombo-dd" id="idd_loc_<?= htmlspecialchars($id) ?>"></div>
                </div>
              </span>
            </td>

            <!-- ACTION -->
            <td onclick="event.stopPropagation()">
              <span class="act-display">
                <button class="btn-icon btn-edit-row" title="Edit this row"
                  onclick="startEdit(event,this.closest('tr'))">
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4z"/></svg>
                </button>
              </span>
              <span class="act-edit">
                <button class="btn-icon btn-save-inline" title="Save changes"
                  onclick="saveInline(event,this.closest('tr'))">
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="20 6 9 17 4 12"/></svg>
                </button>
                <button class="btn-icon btn-cancel-inline" title="Cancel"
                  onclick="cancelEdit(event,this.closest('tr'))">
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
                </button>
              </span>
            </td>
          </tr>
<?php endforeach; ?>
<?php endif; ?>
        </tbody>
      </table>
    </div>

  </div><!-- /card -->
</div><!-- /page -->

<div class="toast" id="toast"></div>

<script>
/* ═══════════════════════════════
   DATA FROM PHP
═══════════════════════════════ */
const ALL_DIVISIONS    = <?= $divisions_json ?>;
const ALL_DESIGNATIONS = <?= $designations_json ?>;
const ALL_LOCATIONS    = <?= $locations_json ?>;

/* ═══════════════════════════════
   MAIN-FORM COMBOBOX
═══════════════════════════════ */
const comboCfg = {
  div:   { inputId:'inp_division',    ddId:'divComboDD',   list: ALL_DIVISIONS },
  desig: { inputId:'inp_designation', ddId:'desigComboDD', list: ALL_DESIGNATIONS },
  loc:   { inputId:'inp_location',    ddId:'locComboDD',   list: ALL_LOCATIONS }
};
let comboIdx = { div:-1, desig:-1, loc:-1 };

function comboRender(key, filter) {
  const cfg    = comboCfg[key];
  const dd     = document.getElementById(cfg.ddId);
  const term   = (filter ?? document.getElementById(cfg.inputId).value).trim().toLowerCase();
  const matches = cfg.list.filter(v => !term || v.toLowerCase().includes(term));
  const label  = key==='div'?'divisions':key==='desig'?'designations':'locations';
  dd.innerHTML = matches.length
    ? matches.map((v,i) => `<div class="combo-item" data-val="${escHtml(v)}" data-idx="${i}" onmousedown="comboPick('${key}','${escHtml(v)}')">${escHtml(v)}</div>`).join('')
    : `<div class="combo-item no-match">No saved ${label} — type to add new</div>`;
  comboIdx[key] = -1;
}
function comboOpen(key) { comboRender(key); document.getElementById(comboCfg[key].ddId).classList.add('open'); }
function comboClose(key) { document.getElementById(comboCfg[key].ddId).classList.remove('open'); comboIdx[key]=-1; }
function comboInput(key) { comboRender(key); document.getElementById(comboCfg[key].ddId).classList.add('open'); }
function comboPick(key, val) { document.getElementById(comboCfg[key].inputId).value = val; comboClose(key); }
function comboKey(e, key) {
  const dd    = document.getElementById(comboCfg[key].ddId);
  const items = dd.querySelectorAll('.combo-item:not(.no-match)');
  if (!items.length) return;
  if (e.key==='ArrowDown') { e.preventDefault(); comboIdx[key]=Math.min(comboIdx[key]+1,items.length-1); }
  else if (e.key==='ArrowUp') { e.preventDefault(); comboIdx[key]=Math.max(comboIdx[key]-1,0); }
  else if (e.key==='Enter' && comboIdx[key]>=0) { e.preventDefault(); comboPick(key,items[comboIdx[key]].dataset.val); return; }
  else if (e.key==='Escape') { comboClose(key); return; }
  else return;
  items.forEach((el,i) => el.classList.toggle('active', i===comboIdx[key]));
  if (comboIdx[key]>=0) items[comboIdx[key]].scrollIntoView({block:'nearest'});
}
document.addEventListener('mousedown', e => {
  const wrapMap = {div:'divComboWrap', desig:'desigComboWrap', loc:'locComboWrap'};
  Object.entries(wrapMap).forEach(([key,wid]) => {
    const w = document.getElementById(wid);
    if (w && !w.contains(e.target)) comboClose(key);
  });
});

/* ═══════════════════════════════
   INLINE-TABLE COMBOBOX
═══════════════════════════════ */
let icomboHi = { div:-1, desig:-1, loc:-1 };

function icomboListFor(key) {
  return key==='div' ? ALL_DIVISIONS : key==='desig' ? ALL_DESIGNATIONS : ALL_LOCATIONS;
}
function fieldToKey(fld) {
  return fld==='division' ? 'div' : fld==='designation' ? 'desig' : 'loc';
}
function icomboRender(inp, key) {
  const row = inp.closest('tr'); const id = row.dataset.id;
  const dd  = document.getElementById(`idd_${key}_${id}`); if (!dd) return;
  const list = icomboListFor(key);
  const term = inp.value.trim().toLowerCase();
  const matches = list.filter(v => !term || v.toLowerCase().includes(term));
  dd.innerHTML = matches.length
    ? matches.map((v,i) => `<div class="icombo-item" data-val="${escHtml(v)}" data-idx="${i}" onmousedown="icomboPickDirect(event,'${escHtml(v)}',this)">${escHtml(v)}</div>`).join('')
    : `<div class="icombo-item nm">No saved values — type to add new</div>`;
  icomboHi[key] = -1;
}
function icomboOpen(inp, key) {
  icomboRender(inp, key);
  const dd = document.getElementById(`idd_${key}_${inp.closest('tr').dataset.id}`);
  if (dd) dd.classList.add('open');
}
function icomboClose(inp, key) {
  const dd = document.getElementById(`idd_${key}_${inp.closest('tr').dataset.id}`);
  if (dd) dd.classList.remove('open');
  icomboHi[key] = -1;
}
function icomboInput(inp, key) {
  icomboRender(inp, key);
  const dd = document.getElementById(`idd_${key}_${inp.closest('tr').dataset.id}`);
  if (dd) dd.classList.add('open');
}
function icomboPickDirect(e, val, el) {
  e.preventDefault();
  const inp = el.closest('.icombo-wrap').querySelector('input');
  inp.value = val;
  icomboClose(inp, fieldToKey(inp.dataset.field));
}
function icomboKey(e, inp, key) {
  const dd    = document.getElementById(`idd_${key}_${inp.closest('tr').dataset.id}`); if (!dd) return;
  const items = dd.querySelectorAll('.icombo-item:not(.nm)');
  if (e.key==='ArrowDown') { e.preventDefault(); icomboHi[key]=Math.min(icomboHi[key]+1,items.length-1); }
  else if (e.key==='ArrowUp') { e.preventDefault(); icomboHi[key]=Math.max(icomboHi[key]-1,0); }
  else if (e.key==='Enter' && icomboHi[key]>=0) { e.preventDefault(); inp.value=items[icomboHi[key]].dataset.val; icomboClose(inp,key); return; }
  else if (e.key==='Escape') { icomboClose(inp,key); return; }
  else return;
  items.forEach((el,i) => el.classList.toggle('hi', i===icomboHi[key]));
  if (icomboHi[key]>=0) items[icomboHi[key]].scrollIntoView({block:'nearest'});
}
document.addEventListener('mousedown', e => {
  document.querySelectorAll('.icombo-wrap').forEach(wrap => {
    if (!wrap.contains(e.target)) {
      const inp = wrap.querySelector('input'); if (!inp) return;
      const row = wrap.closest('tr'); if (!row) return;
      const key = fieldToKey(inp.dataset.field);
      const dd  = document.getElementById(`idd_${key}_${row.dataset.id}`);
      if (dd) dd.classList.remove('open');
    }
  });
});

/* ═══════════════════════════════
   INLINE ROW EDITING
═══════════════════════════════ */
let currentEditRow = null;
let originalVals   = {};

function startEdit(e, row) {
  if (e) e.stopPropagation();
  if (currentEditRow && currentEditRow !== row) cancelEdit(null, currentEditRow);
  currentEditRow = row;
  originalVals = {};
  row.querySelectorAll('[data-field]').forEach(el => { originalVals[el.dataset.field] = el.value; });
  row.classList.add('editing-row');
}
function cancelEdit(e, row) {
  if (e) e.stopPropagation();
  row.querySelectorAll('[data-field]').forEach(el => {
    if (originalVals[el.dataset.field] !== undefined) el.value = originalVals[el.dataset.field];
  });
  row.classList.remove('editing-row');
  if (currentEditRow === row) currentEditRow = null;
}
function saveInline(e, row) {
  e.stopPropagation();
  const id  = row.dataset.id;
  const get = f => { const el = row.querySelector(`[data-field="${f}"]`); return el ? el.value : ''; };

  const body = new URLSearchParams({
    inline_save:1, id,
    role:        get('role'),
    level:       get('level'),
    manager:     get('manager'),
    division:    get('division'),
    designation: get('designation'),
    location:    get('location'),
  });

  fetch(window.location.pathname, {method:'POST', body, credentials:'same-origin'})
    .then(r => {
      if (!r.ok) throw new Error('HTTP ' + r.status);
      return r.json();
    })
    .then(data => {
      if (data.ok) {
        const nDiv=get('division').trim(), nDesig=get('designation').trim(), nLoc=get('location').trim();
        if (nDiv   && !ALL_DIVISIONS.includes(nDiv))      ALL_DIVISIONS.push(nDiv);
        if (nDesig && !ALL_DESIGNATIONS.includes(nDesig)) ALL_DESIGNATIONS.push(nDesig);
        if (nLoc   && !ALL_LOCATIONS.includes(nLoc))      ALL_LOCATIONS.push(nLoc);

        refreshDisplayCells(row, get);
        row.dataset.role    = get('role').toLowerCase();
        row.dataset.level   = get('level');
        row.dataset.div     = get('division').toLowerCase();
        row.dataset.desig   = get('designation').toLowerCase();
        row.dataset.loc     = get('location').toLowerCase();
        const mgrSel = row.querySelector('[data-field="manager"]');
        const mgrOpt = mgrSel ? mgrSel.options[mgrSel.selectedIndex] : null;
        row.dataset.mgrname = mgrOpt && get('manager') ? mgrOpt.text.toLowerCase() : '';
        row.dataset.mgr     = get('manager');
        row.classList.remove('editing-row');
        currentEditRow = null;
        showToast('✅ ' + (data.msg || 'Row saved successfully.'), 'ok');
      } else {
        showToast('❌ Save failed: ' + (data.msg||'Unknown error'), 'err');
      }
    })
    .catch(() => showToast('❌ Network error — you may have been logged out.', 'err'));
}

function refreshDisplayCells(row, get) {
  const tds = row.querySelectorAll('td');
  // Manager (td 3)
  const mgrSel  = row.querySelector('[data-field="manager"]');
  const mgrOpt  = mgrSel ? mgrSel.options[mgrSel.selectedIndex] : null;
  const mgrName = (mgrOpt && get('manager')) ? mgrOpt.text : '';
  tds[3].querySelector('.cell-display').innerHTML = mgrName
    ? `<span style="display:flex;align-items:center;gap:5px;"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="var(--teal)" stroke-width="2.5"><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 3.6-7 8-7s8 3 8 7"/></svg>${escHtml(mgrName)}</span>`
    : '<span class="no-data">Not Assigned</span>';
  // Role (td 4)
  const rv = get('role');
  tds[4].querySelector('.cell-display').innerHTML = `<span class="badge badge-role-${rv.toLowerCase()}">${rv.charAt(0).toUpperCase()+rv.slice(1)}</span>`;
  // Level (td 5)
  tds[5].querySelector('.cell-display').innerHTML = `<span class="badge badge-level">${escHtml(get('level'))}</span>`;
  // Division (td 6)
  tds[6].querySelector('.cell-display').innerHTML = `<span class="badge badge-div">${escHtml(get('division')||'—')}</span>`;
  // Designation (td 7)
  const dd7 = tds[7].querySelector('.cell-display');
  dd7.textContent = get('designation') || '—'; dd7.style.color='var(--muted)';
  // Location (td 8)
  const lv = get('location');
  tds[8].querySelector('.cell-display').innerHTML = lv
    ? `<span class="badge badge-loc" style="display:inline-flex;align-items:center;gap:4px;"><svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M21 10c0 7-9 13-9 13S3 17 3 10a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>${escHtml(lv)}</span>`
    : '<span class="no-data">—</span>';
}

/* ═══════════════════════════════
   ROW CLICK → LOAD FORM
═══════════════════════════════ */
function rowClick(e, row) {
  if (row.classList.contains('editing-row')) return;
  const get = f => { const el = row.querySelector(`[data-field="${f}"]`); return el ? el.value : ''; };
  setSelVal('sel_user',    row.dataset.id);
  setSelVal('sel_role',    row.dataset.role);
  setSelVal('sel_level',   row.dataset.level);
  setSelVal('sel_manager', row.dataset.mgr);
  document.getElementById('inp_division').value    = get('division');
  document.getElementById('inp_designation').value = get('designation');
  document.getElementById('inp_location').value    = get('location');
  window.scrollTo({top:0,behavior:'smooth'});
  showToast('✏️ Row loaded into form above.', 'ok');
}

/* ═══════════════════════════════
   FILTERS
═══════════════════════════════ */
function applyFilters() {
  const search = document.getElementById('fSearch').value.toLowerCase().trim();
  const role   = document.getElementById('fRole').value;
  const level  = document.getElementById('fLevel').value;
  const div    = document.getElementById('fDiv').value;
  const loc    = document.getElementById('fLoc').value;
  const mgr    = document.getElementById('fMgr').value;
  let count    = 0;
  document.querySelectorAll('#assignTable tbody tr').forEach(row => {
    if (row.classList.contains('no-results-row')) return;
    const n  = row.dataset.name    || '';
    const rl = row.dataset.role    || '';
    const lv = row.dataset.level   || '';
    const mn = row.dataset.mgrname || '';
    const dv = row.dataset.div     || '';
    const ds = row.dataset.desig   || '';
    const lc = row.dataset.loc     || '';
    const ok = (!search || n.includes(search)||dv.includes(search)||ds.includes(search)||mn.includes(search)||lc.includes(search))
            && (!role   || rl===role)
            && (!level  || lv===level)
            && (!div    || dv===div)
            && (!loc    || lc===loc)
            && (!mgr    || mn===mgr);
    row.style.display = ok ? '' : 'none';
    if (ok) count++;
  });
  document.getElementById('rowCount').textContent = count;
}
function clearFilters() {
  ['fSearch','fRole','fLevel','fDiv','fLoc','fMgr'].forEach(id => {
    const el = document.getElementById(id);
    if (el.tagName==='SELECT') el.selectedIndex=0; else el.value='';
  });
  applyFilters();
}

/* ═══════════════════════════════
   CHECKBOXES / BULK
═══════════════════════════════ */
function checkboxChanged(cb) {
  cb.closest('tr').classList.toggle('row-selected', cb.checked);
  syncBulkPanel();
}
function toggleAll(master) {
  document.querySelectorAll('.row-cb').forEach(cb => {
    if (cb.closest('tr').style.display !== 'none') {
      cb.checked = master.checked;
      cb.closest('tr').classList.toggle('row-selected', master.checked);
    }
  });
  syncBulkPanel();
}
function clearAllChecks() {
  document.querySelectorAll('.row-cb').forEach(cb => {
    cb.checked=false; cb.closest('tr').classList.remove('row-selected');
  });
  document.getElementById('checkAll').checked = false;
  syncBulkPanel();
}
function syncBulkPanel() {
  const checked = document.querySelectorAll('.row-cb:checked');
  const hd      = document.getElementById('hiddenIds');
  document.getElementById('bulkCount').textContent = checked.length + ' selected';
  document.getElementById('bulkPanel').classList.toggle('active', checked.length > 0);
  hd.innerHTML = '';
  checked.forEach(cb => {
    const inp = document.createElement('input');
    inp.type='hidden'; inp.name='selected_ids[]'; inp.value=cb.value;
    hd.appendChild(inp);
  });
  updateBulkBtn();
}
function updateBulkBtn() {
  const checked = document.querySelectorAll('.row-cb:checked');
  const mgrVal  = document.getElementById('bulk_manager_sel').value;
  document.getElementById('bulkSaveBtn').disabled = (checked.length===0 || mgrVal==='');
}

/* ═══════════════════════════════
   FORM HELPERS
═══════════════════════════════ */
document.getElementById('sel_user').addEventListener('change', function() {
  const opt = this.options[this.selectedIndex];
  if (!opt.value) return;
  setSelVal('sel_role',    opt.dataset.role);
  setSelVal('sel_level',   opt.dataset.level);
  setSelVal('sel_manager', opt.dataset.mgr);
  document.getElementById('inp_division').value    = opt.dataset.div   || '';
  document.getElementById('inp_designation').value = opt.dataset.desig || '';
  document.getElementById('inp_location').value    = opt.dataset.loc   || '';
});
function setSelVal(id, val) {
  const sel = document.getElementById(id); if (!sel) return;
  for (const o of sel.options) { if (String(o.value)===String(val)) { o.selected=true; return; } }
  sel.selectedIndex = 0;
}
function resetForm() {
  setTimeout(() => {
    ['sel_user','sel_role','sel_level','sel_manager'].forEach(id => {
      const el=document.getElementById(id); if(el) el.selectedIndex=0;
    });
    document.getElementById('inp_division').value    = '';
    document.getElementById('inp_designation').value = '';
    document.getElementById('inp_location').value    = '';
  }, 10);
}

/* ═══════════════════════════════
   UTILS
═══════════════════════════════ */
function escHtml(s) {
  return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
}
let _tt;
function showToast(msg, type='ok') {
  const t = document.getElementById('toast');
  t.textContent = msg;
  t.className = `toast show toast-${type}`;
  clearTimeout(_tt);
  _tt = setTimeout(() => t.classList.remove('show'), 2800);
}

document.addEventListener('DOMContentLoaded', applyFilters);
</script>
</body>
</html>