<?php
/**
 * CPT ↔ Specialty map (AR / Collections).  ar-specialty-v1
 *
 * A "specialty" groups a set of CPT / charge codes (e.g. "Office Visit" = 99202…99215). The AR collection
 * dashboard (admin/collection.php) uses this map to power its Specialty filter across every tab — a picked
 * specialty scopes the dashboard to that specialty's charge codes. This page is where AR supervisors / managers
 * maintain the map: add / edit / delete single rows, bulk-import from an Excel workbook, or rename a whole
 * specialty at once.
 *
 * Storage: ar_cpt_specialty (cpt_code UNIQUE, specialty). Seeded once by the ar_cpt_specialty_v1 migration from
 * the client's "CPT and Specialty" workbook; edits here are authoritative thereafter (the seed is INSERT IGNORE
 * so it never overwrites a later edit).
 *
 * Access: SysAdmin + AR supervisor/manager (ar.supervise / ar.allocate). Route-gated in includes/auth.php; the
 * in-page check below is belt-and-suspenders.
 */
require_once __DIR__ . '/../includes/config.php';
require_once __DIR__ . '/../includes/xlsx-reader.php';
$user = require_login('internal');
$pdo  = db();
$uid  = (int) $user['id'];

$canManage = is_sysadmin() || user_has_permission($uid, 'ar.supervise') || user_has_permission($uid, 'ar.allocate');
if (!$canManage) { http_response_code(403); exit('You do not have access to manage the CPT ↔ Specialty map.'); }

/* The table is created by the ar_cpt_specialty_v1 migration; guard in case migrations haven't run yet. */
function arsp_table_ok(PDO $pdo): bool {
    static $ok = null;
    if ($ok !== null) return $ok;
    try { $pdo->query("SELECT 1 FROM ar_cpt_specialty LIMIT 1"); $ok = true; }
    catch (Throwable $t) { $ok = false; }
    return $ok;
}
/* Normalise a CPT/charge code: trim + uppercase (HCPCS codes like G0506 are alphanumeric).
   IMPORTANT COUPLING: the collection dashboard matches specialties with
   `charge_code IN (SELECT cpt_code FROM ar_cpt_specialty WHERE specialty=?)`. That match only
   works because collection_raw.charge_code is ALSO stored uppercase (upcased on ingest in
   includes/collection-engine.php). Keep all three in sync — if the ingest normalizer changes,
   every specialty filter silently returns zero rows. */
function arsp_norm_cpt(string $c): string { return strtoupper(trim($c)); }

/* ───────────────────────── POST handlers (PRG) ───────────────────────── */
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    csrf_check_or_die();
    $action = (string) ($_POST['action'] ?? '');

    if (!arsp_table_ok($pdo)) {
        flash('error', 'The CPT ↔ Specialty table is not ready yet — load any authenticated page once to run migrations, then retry.');
        redirect('/admin/ar-specialty.php');
    }

    if ($action === 'add') {
        $cpt  = arsp_norm_cpt((string) ($_POST['cpt_code'] ?? ''));
        $spec = trim((string) ($_POST['specialty'] ?? ''));
        if ($cpt === '' || $spec === '') {
            flash('error', 'Both a CPT/charge code and a specialty are required.');
        } else {
            // Upsert: a CPT belongs to exactly one specialty, so re-adding an existing code re-points it.
            $st = $pdo->prepare("INSERT INTO ar_cpt_specialty (cpt_code, specialty, created_at, updated_at)
                                 VALUES (?,?,NOW(),NOW())
                                 ON DUPLICATE KEY UPDATE specialty=VALUES(specialty), updated_at=NOW()");
            $st->execute([$cpt, $spec]);
            audit_log('ar.specialty.add', 'ar_cpt_specialty', 0, null, ['cpt' => $cpt, 'specialty' => $spec]);
            flash('success', "Mapped {$cpt} → {$spec}.");
        }
        redirect('/admin/ar-specialty.php?' . http_build_query(['specialty' => $spec]));
    }

    if ($action === 'edit') {
        $id   = (int) ($_POST['id'] ?? 0);
        $cpt  = arsp_norm_cpt((string) ($_POST['cpt_code'] ?? ''));
        $spec = trim((string) ($_POST['specialty'] ?? ''));
        if ($id <= 0 || $cpt === '' || $spec === '') {
            flash('error', 'A CPT/charge code and a specialty are required.');
        } else {
            // Guard the UNIQUE(cpt_code): block renaming a code onto one that already exists on a different row.
            $chk = $pdo->prepare("SELECT id FROM ar_cpt_specialty WHERE cpt_code=? AND id<>?");
            $chk->execute([$cpt, $id]);
            if ($chk->fetchColumn()) {
                flash('error', "CPT {$cpt} already exists — edit that row instead of creating a duplicate.");
            } else {
                $st = $pdo->prepare("UPDATE ar_cpt_specialty SET cpt_code=?, specialty=?, updated_at=NOW() WHERE id=?");
                $st->execute([$cpt, $spec, $id]);
                audit_log('ar.specialty.edit', 'ar_cpt_specialty', $id, null, ['cpt' => $cpt, 'specialty' => $spec]);
                flash('success', "Updated {$cpt} → {$spec}.");
            }
        }
        redirect('/admin/ar-specialty.php?' . http_build_query(['specialty' => $spec]));
    }

    if ($action === 'delete') {
        $id = (int) ($_POST['id'] ?? 0);
        if ($id > 0) {
            $row = $pdo->prepare("SELECT cpt_code, specialty FROM ar_cpt_specialty WHERE id=?");
            $row->execute([$id]); $row = $row->fetch();
            $pdo->prepare("DELETE FROM ar_cpt_specialty WHERE id=?")->execute([$id]);
            if ($row) audit_log('ar.specialty.delete', 'ar_cpt_specialty', $id, $row, null);
            flash('success', 'Mapping removed.');
        }
        redirect('/admin/ar-specialty.php');
    }

    if ($action === 'rename_specialty') {
        $from = trim((string) ($_POST['from'] ?? ''));
        $to   = trim((string) ($_POST['to'] ?? ''));
        if ($from === '' || $to === '') {
            flash('error', 'Both the current and new specialty names are required.');
        } elseif ($from === $to) {
            flash('error', 'The new name is the same as the current one.');
        } else {
            // If the target name already exists AS A DIFFERENT GROUP, this is a MERGE, not a rename —
            // folding one specialty's codes into another. That's destructive to the grouping, so require
            // explicit confirmation (fail-closed: without merge_confirmed we stop and explain, even if JS
            // was bypassed). The `specialty <> ?` on $from excludes the source group itself so a case-only
            // or accent-only rename (the column collation is case/accent-insensitive) is NOT seen as a merge.
            $ex = $pdo->prepare("SELECT COUNT(*) FROM ar_cpt_specialty WHERE specialty = ? AND specialty <> ?");
            $ex->execute([$to, $from]);
            $isMerge = ((int) $ex->fetchColumn()) > 0;
            $confirmed = (($_POST['merge_confirmed'] ?? '') === '1');
            if ($isMerge && !$confirmed) {
                flash('error', "\"{$to}\" already exists — renaming \"{$from}\" to it would MERGE both groups into one. Re-submit to confirm the merge.");
                redirect('/admin/ar-specialty.php?' . http_build_query(['specialty' => $from]));
            }
            $st = $pdo->prepare("UPDATE ar_cpt_specialty SET specialty=?, updated_at=NOW() WHERE specialty=?");
            $st->execute([$to, $from]);
            $n = $st->rowCount();
            audit_log('ar.specialty.rename', 'ar_cpt_specialty', 0, ['from' => $from], ['to' => $to, 'rows' => $n, 'merge' => $isMerge]);
            $verb = $isMerge ? 'Merged' : 'Renamed';
            flash('success', "{$verb} \"{$from}\" → \"{$to}\" ({$n} code" . ($n === 1 ? '' : 's') . ").");
        }
        redirect('/admin/ar-specialty.php?' . http_build_query(['specialty' => $to]));
    }

    if ($action === 'delete_specialty') {
        $spec = trim((string) ($_POST['specialty'] ?? ''));
        if ($spec !== '') {
            $st = $pdo->prepare("DELETE FROM ar_cpt_specialty WHERE specialty=?");
            $st->execute([$spec]);
            $n = $st->rowCount();
            audit_log('ar.specialty.delete_group', 'ar_cpt_specialty', 0, ['specialty' => $spec], ['rows' => $n]);
            flash('success', "Deleted specialty \"{$spec}\" and its {$n} code" . ($n === 1 ? '' : 's') . '.');
        }
        redirect('/admin/ar-specialty.php');
    }

    if ($action === 'import') {
        if (empty($_FILES['file']['tmp_name']) || !is_uploaded_file($_FILES['file']['tmp_name'])) {
            flash('error', 'Choose an .xlsx file to upload.');
            redirect('/admin/ar-specialty.php');
        }
        // Column order is flexible: we detect which column holds the specialty vs the CPT by inspecting the
        // header row, and fall back to (Speciality, Charge Code) — the client's workbook layout.
        $ROW_CAP = 50000;   // a CPT map is hundreds of rows; cap bounds a hostile/huge upload's memory + time
        try {
            $rd = new XlsxReader($_FILES['file']['tmp_name']);
            $specCol = 0; $cptCol = 1; $i = 0; $pairs = []; $capped = false;
            foreach ($rd->rows(0) as $r) {
                $i++;
                if ($i === 1) {
                    // Header sniff (two-pass): prefer an EXACT header name, else fall back to a substring
                    // match, else the (Speciality, Charge Code) default. Two passes so a stray "…Code…"
                    // column can't beat an actual "CPT"/"Charge Code" column just by appearing first.
                    $specExact = $cptExact = null; $specSub = $cptSub = null;
                    foreach ($r as $ci => $h) {
                        $h = strtolower(trim((string) $h)); $ci = (int) $ci;
                        if ($h === '') continue;
                        if (in_array($h, ['speciality', 'specialty'], true)) { if ($specExact === null) $specExact = $ci; }
                        elseif (in_array($h, ['cpt', 'cpt code', 'charge code', 'charge_code', 'code'], true)) { if ($cptExact === null) $cptExact = $ci; }
                        elseif (strpos($h, 'special') !== false) { if ($specSub === null) $specSub = $ci; }
                        elseif (strpos($h, 'cpt') !== false || strpos($h, 'charge') !== false || strpos($h, 'code') !== false) { if ($cptSub === null) $cptSub = $ci; }
                    }
                    $specCol = $specExact ?? $specSub ?? $specCol;
                    $cptCol  = $cptExact  ?? $cptSub  ?? $cptCol;
                    continue;
                }
                if (count($pairs) >= $ROW_CAP) { $capped = true; break; }
                $spec = trim((string) ($r[$specCol] ?? ''));
                $cpt  = arsp_norm_cpt((string) ($r[$cptCol] ?? ''));
                if ($cpt === '' || $spec === '') continue;
                $pairs[$cpt] = $spec;   // last one wins for a duplicate code within the file
            }
            $rd->close();
            if (!$pairs) {
                flash('error', 'No usable rows found. Expected a specialty column and a CPT/charge-code column.');
                redirect('/admin/ar-specialty.php');
            }
            $ins = $pdo->prepare("INSERT INTO ar_cpt_specialty (cpt_code, specialty, created_at, updated_at)
                                  VALUES (?,?,NOW(),NOW())
                                  ON DUPLICATE KEY UPDATE specialty=VALUES(specialty), updated_at=NOW()");
            $added = 0; $updated = 0;
            $pdo->beginTransaction();
            // Read the current map INSIDE the transaction so the added/updated tallies are consistent
            // with what we then write (the upsert itself is authoritative regardless).
            $existing = $pdo->query("SELECT cpt_code, specialty FROM ar_cpt_specialty")->fetchAll(PDO::FETCH_KEY_PAIR);
            foreach ($pairs as $cpt => $spec) {
                if (isset($existing[$cpt])) { if ($existing[$cpt] !== $spec) $updated++; }
                else $added++;
                $ins->execute([$cpt, $spec]);
            }
            $pdo->commit();
            audit_log('ar.specialty.import', 'ar_cpt_specialty', 0, null, ['added' => $added, 'updated' => $updated, 'total' => count($pairs), 'capped' => $capped]);
            flash('success', "Import complete — {$added} new, {$updated} changed (" . count($pairs) . ' rows processed).'
                . ($capped ? " Note: only the first {$ROW_CAP} codes were processed (row cap reached)." : ''));
        } catch (Throwable $e) {
            if ($pdo->inTransaction()) $pdo->rollBack();
            flash('error', 'Could not read the workbook: ' . (defined('APP_DEBUG') && APP_DEBUG ? $e->getMessage() : 'invalid file'));
        }
        redirect('/admin/ar-specialty.php');
    }

    redirect('/admin/ar-specialty.php');
}

/* ───────────────────────── Read state for the view ───────────────────────── */
$tableOk = arsp_table_ok($pdo);
$fSpec   = trim((string) ($_GET['specialty'] ?? ''));   // filter the list to one specialty
$q       = trim((string) ($_GET['q'] ?? ''));            // search a CPT code

$specList = [];   // specialty => count
$rows     = [];
$totalCpts = 0;
if ($tableOk) {
    foreach ($pdo->query("SELECT specialty, COUNT(*) c FROM ar_cpt_specialty GROUP BY specialty ORDER BY specialty") as $r)
        $specList[$r['specialty']] = (int) $r['c'];
    $totalCpts = (int) $pdo->query("SELECT COUNT(*) FROM ar_cpt_specialty")->fetchColumn();

    $w = []; $p = [];
    if ($fSpec !== '' && isset($specList[$fSpec])) { $w[] = 'specialty = ?'; $p[] = $fSpec; }
    if ($q !== '') { $w[] = 'cpt_code LIKE ?'; $p[] = '%' . arsp_norm_cpt($q) . '%'; }
    $wsql = $w ? ('WHERE ' . implode(' AND ', $w)) : '';
    $st = $pdo->prepare("SELECT id, cpt_code, specialty, updated_at FROM ar_cpt_specialty $wsql ORDER BY specialty, cpt_code");
    $st->execute($p);
    $rows = $st->fetchAll();
}

$pageTitle = 'CPT ↔ Specialty';
require __DIR__ . '/../includes/header.php';
?>
<style>
  .sp-chip{ display:inline-flex; align-items:center; gap:.35rem; padding:.15rem .55rem; border:1px solid var(--tblr-border-color,#dbe0e5);
            border-radius:999px; font-size:.8rem; text-decoration:none; color:inherit; background:var(--tblr-bg-surface,#fff); }
  .sp-chip.active{ background:#dbeafe; border-color:#3b82f6; color:#1e40af; font-weight:600; }
  .sp-chip .n{ font-size:.7rem; opacity:.7; }
  .sp-list{ display:flex; flex-wrap:wrap; gap:.4rem; }
  .sp-editform input{ min-width:0; }
</style>

<div class="page-header"><div class="container-xl"><div class="row align-items-center">
    <div class="col">
        <h2 class="page-title"><i class="ti ti-stethoscope me-2 text-primary"></i>CPT &harr; Specialty map</h2>
        <div class="text-secondary">Groups CPT / charge codes into specialties. Powers the <strong>Specialty filter</strong> on the AR collection dashboard.</div>
    </div>
    <div class="col-auto d-flex gap-2">
        <button class="btn btn-outline-primary" type="button" data-bs-toggle="collapse" data-bs-target="#importForm"><i class="ti ti-file-spreadsheet me-1"></i>Import Excel</button>
        <a href="<?= e(url('/admin/ar-allocation.php')) ?>" class="btn btn-outline-secondary"><i class="ti ti-cash me-1"></i>AR allocation</a>
    </div>
</div></div></div>

<div class="page-body"><div class="container-xl">

    <?php if (!$tableOk): ?>
        <div class="alert alert-warning"><i class="ti ti-alert-triangle me-1"></i>The CPT&harr;Specialty table hasn't been created yet. Load any authenticated page once so migrations run, then reload this page.</div>
    <?php else: ?>

    <!-- Summary -->
    <div class="row row-cards mb-3">
        <div class="col-sm-4"><div class="card"><div class="card-body py-2">
            <div class="text-secondary small">Specialties</div><div class="h2 mb-0"><?= number_format(count($specList)) ?></div>
        </div></div></div>
        <div class="col-sm-4"><div class="card"><div class="card-body py-2">
            <div class="text-secondary small">Mapped CPT codes</div><div class="h2 mb-0"><?= number_format($totalCpts) ?></div>
        </div></div></div>
        <div class="col-sm-4"><div class="card"><div class="card-body py-2">
            <div class="text-secondary small">Showing</div><div class="h2 mb-0"><?= number_format(count($rows)) ?><span class="text-secondary fs-4"> rows</span></div>
        </div></div></div>
    </div>

    <!-- Import (collapsed) -->
    <div class="collapse mb-3" id="importForm">
        <form method="POST" action="<?= e(url('/admin/ar-specialty.php')) ?>" enctype="multipart/form-data" class="card">
            <?= csrf_field() ?>
            <input type="hidden" name="action" value="import">
            <div class="card-header"><h3 class="card-title"><i class="ti ti-file-spreadsheet me-2"></i>Import from Excel</h3></div>
            <div class="card-body">
                <p class="text-secondary small mb-2">Upload an <code>.xlsx</code> with a <strong>Speciality</strong> column and a <strong>Charge Code</strong> (CPT) column. Existing codes are re-pointed to the specialty in the file (upsert); nothing is deleted.</p>
                <div class="d-flex gap-2 align-items-center flex-wrap">
                    <input type="file" name="file" accept=".xlsx" class="form-control" style="max-width:360px" required>
                    <button type="submit" class="btn btn-primary"><i class="ti ti-upload me-1"></i>Import</button>
                </div>
            </div>
        </form>
    </div>

    <!-- Add a single mapping -->
    <form method="POST" action="<?= e(url('/admin/ar-specialty.php')) ?>" class="card mb-3">
        <?= csrf_field() ?>
        <input type="hidden" name="action" value="add">
        <div class="card-body">
            <div class="row g-2 align-items-end">
                <div class="col-md-3">
                    <label class="form-label required">CPT / charge code</label>
                    <input type="text" name="cpt_code" class="form-control" required maxlength="20" placeholder="e.g. 99213 or G0506">
                </div>
                <div class="col-md-5">
                    <label class="form-label required">Specialty</label>
                    <input type="text" name="specialty" class="form-control" required maxlength="100" list="specialtyOptions" placeholder="type an existing or new specialty">
                </div>
                <div class="col-md-auto">
                    <button type="submit" class="btn btn-primary"><i class="ti ti-plus me-1"></i>Add / update</button>
                </div>
            </div>
            <div class="form-hint mt-1">Adding a code that already exists re-points it to the specialty you enter.</div>
        </div>
    </form>

    <datalist id="specialtyOptions">
        <?php foreach ($specList as $sp => $c): ?><option value="<?= e($sp) ?>"></option><?php endforeach; ?>
    </datalist>

    <!-- Specialty filter chips -->
    <div class="card mb-3"><div class="card-body py-2">
        <div class="d-flex align-items-center gap-2 mb-2 flex-wrap">
            <span class="text-secondary small me-1"><i class="ti ti-filter me-1"></i>Specialty:</span>
            <div class="sp-list">
                <a class="sp-chip <?= $fSpec === '' ? 'active' : '' ?>" href="<?= e(url('/admin/ar-specialty.php')) ?>">All <span class="n"><?= $totalCpts ?></span></a>
                <?php foreach ($specList as $sp => $c): ?>
                    <a class="sp-chip <?= $fSpec === $sp ? 'active' : '' ?>" href="<?= e(url('/admin/ar-specialty.php?' . http_build_query(['specialty' => $sp]))) ?>"><?= e($sp) ?> <span class="n"><?= $c ?></span></a>
                <?php endforeach; ?>
            </div>
        </div>
        <form method="GET" action="<?= e(url('/admin/ar-specialty.php')) ?>" class="d-flex gap-2 align-items-center">
            <?php if ($fSpec !== ''): ?><input type="hidden" name="specialty" value="<?= e($fSpec) ?>"><?php endif; ?>
            <input type="text" name="q" value="<?= e($q) ?>" class="form-control form-control-sm" style="max-width:240px" placeholder="Search a CPT code…">
            <button type="submit" class="btn btn-sm btn-outline-primary"><i class="ti ti-search"></i></button>
            <?php if ($q !== ''): ?><a href="<?= e(url('/admin/ar-specialty.php?' . http_build_query($fSpec !== '' ? ['specialty' => $fSpec] : []))) ?>" class="btn btn-sm btn-ghost-secondary">Clear</a><?php endif; ?>
        </form>
    </div></div>

    <!-- Whole-specialty actions (only when one specialty is selected) -->
    <?php if ($fSpec !== '' && isset($specList[$fSpec])): ?>
    <div class="card mb-3 border-primary-subtle"><div class="card-body py-2">
        <div class="row g-2 align-items-center">
            <div class="col-md-6">
                <form method="POST" action="<?= e(url('/admin/ar-specialty.php')) ?>" class="d-flex gap-2 align-items-center" id="renameSpecForm">
                    <?= csrf_field() ?>
                    <input type="hidden" name="action" value="rename_specialty">
                    <input type="hidden" name="from" value="<?= e($fSpec) ?>">
                    <input type="hidden" name="merge_confirmed" value="" id="renameMergeConfirmed">
                    <span class="text-secondary small text-nowrap">Rename this specialty:</span>
                    <input type="text" name="to" class="form-control form-control-sm" value="<?= e($fSpec) ?>" maxlength="100" required id="renameSpecTo">
                    <button type="submit" class="btn btn-sm btn-primary text-nowrap"><i class="ti ti-edit me-1"></i>Rename</button>
                </form>
            </div>
            <div class="col-md-6 text-md-end">
                <form method="POST" action="<?= e(url('/admin/ar-specialty.php')) ?>" onsubmit="return confirm('Delete the specialty \'<?= e($fSpec) ?>\' and all <?= (int)($specList[$fSpec] ?? 0) ?> of its CPT codes?');">
                    <?= csrf_field() ?>
                    <input type="hidden" name="action" value="delete_specialty">
                    <input type="hidden" name="specialty" value="<?= e($fSpec) ?>">
                    <button type="submit" class="btn btn-sm btn-outline-danger"><i class="ti ti-trash me-1"></i>Delete specialty (<?= (int)($specList[$fSpec] ?? 0) ?> codes)</button>
                </form>
            </div>
        </div>
    </div></div>
    <?php endif; ?>

    <!-- Mappings table. Each row's controls use the HTML5 form= attribute to bind to a
         <form> rendered after the table (a <form> cannot legally span <td>s inside a <tr>). -->
    <div class="card">
        <div class="table-responsive">
            <table class="table table-vcenter table-hover card-table">
                <thead><tr>
                    <th style="width:180px">CPT / charge code</th>
                    <th>Specialty</th>
                    <th style="width:150px" class="text-secondary">Updated</th>
                    <th style="width:200px" class="text-end">Actions</th>
                </tr></thead>
                <tbody>
                <?php if (!$rows): ?>
                    <tr><td colspan="4" class="text-secondary text-center py-4">No mappings<?= ($fSpec !== '' || $q !== '') ? ' match this filter' : ' yet' ?>.</td></tr>
                <?php else: foreach ($rows as $r): $ef = 'ef' . (int) $r['id']; $df = 'df' . (int) $r['id']; ?>
                    <tr>
                        <td><input type="text" form="<?= $ef ?>" name="cpt_code" value="<?= e($r['cpt_code']) ?>" class="form-control form-control-sm" maxlength="20" required></td>
                        <td><input type="text" form="<?= $ef ?>" name="specialty" value="<?= e($r['specialty']) ?>" class="form-control form-control-sm" maxlength="100" list="specialtyOptions" required></td>
                        <td class="text-secondary small"><?= e($r['updated_at'] ? date('Y-m-d', strtotime($r['updated_at'])) : '') ?></td>
                        <td class="text-end text-nowrap">
                            <button type="submit" form="<?= $ef ?>" class="btn btn-sm btn-outline-primary"><i class="ti ti-device-floppy"></i> Save</button>
                            <button type="submit" form="<?= $df ?>" class="btn btn-sm btn-ghost-danger" onclick="return confirm('Remove <?= e($r['cpt_code']) ?>?');"><i class="ti ti-trash"></i></button>
                        </td>
                    </tr>
                <?php endforeach; endif; ?>
                </tbody>
            </table>
        </div>
    </div>

    <!-- One edit + one delete <form> per row, referenced by the controls above via form=. -->
    <?php foreach ($rows as $r): $ef = 'ef' . (int) $r['id']; $df = 'df' . (int) $r['id']; ?>
        <form id="<?= $ef ?>" method="POST" action="<?= e(url('/admin/ar-specialty.php')) ?>" class="d-none">
            <?= csrf_field() ?><input type="hidden" name="action" value="edit"><input type="hidden" name="id" value="<?= (int) $r['id'] ?>">
        </form>
        <form id="<?= $df ?>" method="POST" action="<?= e(url('/admin/ar-specialty.php')) ?>" class="d-none">
            <?= csrf_field() ?><input type="hidden" name="action" value="delete"><input type="hidden" name="id" value="<?= (int) $r['id'] ?>">
        </form>
    <?php endforeach; ?>

    <?php endif; /* tableOk */ ?>
</div></div>

<?php if ($tableOk): ?>
<script>
/* Warn before a rename silently MERGES into an existing specialty. Server-side is the real guard
   (it rejects an unconfirmed merge); this just gives the supervisor an upfront prompt + sets the
   confirm flag so a genuine merge doesn't bounce back with an error. */
(function () {
    var existing = <?= json_encode(array_map('strval', array_keys($specList)), JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP) ?>;
    var lc = {}; existing.forEach(function (s) { lc[s.toLowerCase()] = s; });
    var form = document.getElementById('renameSpecForm');
    if (!form) return;
    form.addEventListener('submit', function (e) {
        var from = (form.querySelector('input[name=from]') || {}).value || '';
        var to   = (document.getElementById('renameSpecTo') || {}).value || '';
        to = to.trim();
        var hidden = document.getElementById('renameMergeConfirmed');
        if (hidden) hidden.value = '';
        var hit = lc[to.toLowerCase()];
        if (hit && hit !== from) {
            if (!confirm('"' + hit + '" already exists. Renaming "' + from + '" to it will MERGE both specialties into one — this cannot be undone. Continue?')) {
                e.preventDefault();
                return false;
            }
            if (hidden) hidden.value = '1';
        }
    });
})();
</script>
<?php endif; ?>

<?php require __DIR__ . '/../includes/footer.php'; ?>
