<?php
/**
 * My billing queue (billing.work) — the BILLER's console.
 *
 * A biller works ONLY the charts allocated to THEM (billing_allocation.allocated_biller = me). Allocation
 * and reallocation live in the supervisor console (admin/billing-allocation.php). Here the biller opens
 * charts ONE BY ONE ("Work next") and tags each: Carrier (searchable, from the managed list) + Billing
 * status (Billed / Billed-On-Hold-Deductible / Unbilled); a secondary reason is required only for Unbilled,
 * plus an optional comment. Every save is mirrored to billing_allocation_event. Logic lives in includes/billing.php.
 */
require_once __DIR__ . '/../includes/config.php';
$user = require_login('internal');
$pdo  = db();
$uid  = (int) $user['id'];

/* Team-inventory mode (supervisor/manager): a read-only view of the WHOLE team's billing inventory.
   The default 'personal' mode is the biller's own work queue (unchanged). */
$isTeamViewer = can('billing.supervise') || can('billing.allocate');
$fMode = (($_GET['mode'] ?? '') === 'team' && $isTeamViewer) ? 'team' : 'personal';

$fStatus = in_array($_GET['status'] ?? 'to_work', ['to_work','worked','all'], true) ? ($_GET['status'] ?? 'to_work') : 'to_work';
/* optional narrowing filters within MY queue */
$fClient   = (int) ($_GET['client_id'] ?? 0);
$fFacility = (int) ($_GET['facility_id'] ?? 0);
$fProvider = (int) ($_GET['provider_id'] ?? 0);
$fCarrier  = trim((string) ($_GET['carrier'] ?? ''));
$fBilStat  = in_array($_GET['bstatus'] ?? '', ['pending','billed','hold_deductible','unbilled'], true) ? (string) $_GET['bstatus'] : '';
/* Worked-date window (Worked tab): defaults to TODAY's completions; a from/to filter (or "all dates")
   reveals backdated records. Dates validated with checkdate so a garbage value can't reach the query. */
$validWDate = function ($s): string { $s = trim((string) $s);
    return (preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $s, $m) && checkdate((int) $m[2], (int) $m[3], (int) $m[1])) ? $s : ''; };
$fwFrom = $validWDate($_GET['wfrom'] ?? '');
$fwTo   = $validWDate($_GET['wto'] ?? '');
$fwAll  = (($_GET['wall'] ?? '') === '1');
$selfUrl = fn(array $o = []) => '/admin/my-billing.php' . (($q = array_filter(array_merge(['status'=>$fStatus,'client_id'=>$fClient,'facility_id'=>$fFacility,'provider_id'=>$fProvider,'carrier'=>$fCarrier,'bstatus'=>$fBilStat,'wfrom'=>$fwFrom,'wto'=>$fwTo,'wall'=>$fwAll?'1':''], $o), fn($v)=>$v!==null&&$v!==''&&$v!==0))?'?'.http_build_query($q):'');

/* ============================================================================ POST — save work (PRG) */
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    csrf_check_or_die();
    if (($_POST['action'] ?? '') === 'work') {
        $invId   = (int) ($_POST['inventory_id'] ?? 0);
        $carrier = trim((string) input('carrier'));
        $status  = (string) ($_POST['billing_status'] ?? '');
        $reason  = trim((string) input('secondary_reason'));
        $comment = trim((string) input('comment'));
        // Per coded line, WHICH code the biller finalized & billed: billed_code[<line_key>] = 'cpt' | 'alf' | '' (none).
        $billed = [];
        foreach ((array) ($_POST['billed_code'] ?? []) as $lk => $ct) {
            $ct = is_string($ct) ? $ct : '';
            if ($ct === 'cpt' || $ct === 'alf') $billed[(string) $lk] = $ct;
        }

        // Server-side membership checks (don't trust the <select>/<datalist>) for every managed-list field.
        if (!isset(BILLING_WORK_STATUSES[$status])) {
            flash('error', 'Pick a billing status.');
        } elseif ($carrier !== '' && !in_array($carrier, billing_dropdowns($pdo, 'carrier'), true)) {
            flash('error', 'Pick a carrier (insurance) from the list.');
        } elseif ($status !== 'unbilled' && $carrier === '') {
            flash('error', 'Pick a carrier (insurance) from the list — required unless the chart is Unbilled.');
        } elseif ($status === 'unbilled' && ($reason === '' || !in_array($reason, billing_dropdowns($pdo, 'secondary_reason'), true))) {
            flash('error', 'Pick a valid Unbilled secondary reason from the list.');
        } elseif ($comment !== '' && !in_array($comment, billing_dropdowns($pdo, 'comment'), true)) {
            flash('error', 'Pick a comment from the list, or leave it blank.');
        } elseif (in_array($status, ['billed', 'hold_deductible'], true) && !billing_billable_selection_ok($pdo, $invId, $billed, $carrier)) {
            // Billed / On-hold-deductible must record which code was billed: CPT on every line, OR an ALF on any line
            // (ALF is a single per-visit code that bills the whole encounter).
            flash('error', 'For a Billed / On-hold-deductible chart, pick CPT on every line — or an ALF on any line — before saving.');
        } else {
            $ok = billing_save_work($pdo, $invId, $uid, $carrier, $status, $reason, $comment, $billed);
            if ($ok) {
                // Save & next → the SAME patient's next visit (oldest DOS). When the patient has no more
                // visits, stop and let the biller pull the next patient with "Get next patient".
                $pkey = billing_patient_key_of($pdo, $invId);
                $next = $pkey ? billing_next_visit_for_patient($pdo, $uid, $pkey, $invId) : null;
                if ($next) {
                    flash('success', 'Saved. Loaded the next visit for this patient.');
                    redirect($selfUrl(['work' => $next]));
                }
                flash('success', 'Saved — all visits for this patient are done. Click “Get next patient” for the next one.');
                redirect($selfUrl(['status' => 'to_work']));
            } else flash('error', 'That chart is not allocated to you.');
        }
        redirect($selfUrl(['work' => $invId]));   // any validation/save failure → reopen the same chart, keep context
    } elseif (($_POST['action'] ?? '') === 'rebut') {
        // Biller disputes an audit ERROR on one of their own charts → sent to the auditor's Rebuttals queue.
        $invId = (int) ($_POST['inventory_id'] ?? 0);
        $note  = trim((string) input('note'));
        if ($note === '') { flash('error', 'Add a reason for your rebuttal.'); redirect($selfUrl(['status'=>'worked'])); }
        $ok = billing_raise_rebuttal($pdo, $invId, $uid, $note);
        flash($ok ? 'success' : 'error', $ok ? 'Rebuttal sent to the auditor.' : 'That chart cannot be rebutted.');
        redirect($selfUrl(['status'=>'worked']));
    }
    redirect($selfUrl());
}

/* ============================================================================ GET — KPI + work card + list */
$kpi = ['total'=>0,'to_work'=>0,'worked'=>0,'billed'=>0,'hold_deductible'=>0,'unbilled'=>0];
// JOIN coding_inventory so the counts cover the SAME set the list shows (an allocation whose chart was deleted
// is not counted — otherwise the KPI over-counts vs the list, which can't render a non-existent chart).
$k = $pdo->prepare("SELECT COUNT(*) total,
        SUM(ba.inventory_status='allocated') to_work,
        SUM(ba.inventory_status='worked') worked,
        SUM(ba.billing_status='billed') billed,
        SUM(ba.billing_status='hold_deductible') hold_deductible,
        SUM(ba.billing_status='unbilled') unbilled
    FROM billing_allocation ba JOIN coding_inventory ci ON ci.id=ba.inventory_id WHERE ba.allocated_biller=?");
$k->execute([$uid]);
if ($r = $k->fetch()) foreach ($kpi as $kk=>$_) $kpi[$kk] = (int) ($r[$kk] ?? 0);

/* Which chart (if any) is open in the focused work card.
   ?work=next        → the oldest to-work chart (first patient's first visit).
   ?work=nextpatient → the NEXT patient's first visit, skipping the current patient (&cur=<inv>) if one is open. */
$workReq = (string) ($_GET['work'] ?? '');
if ($workReq === 'next') {
    $workId = (int) billing_next_chart_for_biller($pdo, $uid);
} elseif ($workReq === 'nextpatient') {
    $curInv  = (int) ($_GET['cur'] ?? 0);
    $exclKey = $curInv ? billing_patient_key_of($pdo, $curInv) : null;
    $workId  = (int) (billing_next_chart_for_biller($pdo, $uid, $curInv ?: null, $exclKey) ?? 0);
} else {
    $workId = (int) $workReq;
}
$workChart = null;
if ($workId) {
    $st = $pdo->prepare("SELECT a.*, ci.patient_name, ci.patient_mrn, ci.patient_dob, ci.dos,
            c.name cn, p.name pn, f.name fn, pr.name prn, cp.name coded_prov
        FROM billing_allocation a
        JOIN coding_inventory ci ON ci.id=a.inventory_id
        LEFT JOIN clients c ON c.id=ci.client_id LEFT JOIN processes p ON p.id=ci.process_id
        LEFT JOIN coding_facilities f ON f.id=ci.facility_id LEFT JOIN coding_providers pr ON pr.id=ci.provider_id
        LEFT JOIN coding_providers cp ON cp.id=ci.coded_provider_id
        WHERE a.inventory_id=? AND a.allocated_biller=?");
    $st->execute([$workId, $uid]);
    $workChart = $st->fetch() ?: null;
}

/* The biller's queue table. When a chart is OPEN in the work card, the list below is FOCUSED on that
   patient's remaining OPEN visits (a per-patient worklist); otherwise it's the full queue (status tab + filters). */
$patientFocus = (bool) $workChart;
$where = ['a.allocated_biller=?']; $params = [$uid];
if ($patientFocus) {
    $where[]  = "a.inventory_status='allocated'";                          // open (to-work) visits only
    $where[]  = billing_patient_key_sql('ci') . " = ?";
    $params[] = (string) (billing_patient_key_of($pdo, (int) $workChart['inventory_id']) ?? '');
    $orderBy  = "ci.dos ASC, a.id ASC";
} else {
    if ($fStatus === 'to_work')  $where[] = "a.inventory_status='allocated'";
    elseif ($fStatus === 'worked') {
        $where[] = "a.inventory_status='worked'";
        // Default to TODAY's completions; a worked-date filter (or "all dates") reveals backdated records.
        if ($fwFrom !== '' || $fwTo !== '') {
            if ($fwFrom !== '') { $where[] = "a.last_worked_date >= ?"; $params[] = $fwFrom; }
            if ($fwTo   !== '') { $where[] = "a.last_worked_date <= ?"; $params[] = $fwTo; }
        } elseif (!$fwAll) {
            $where[] = "a.last_worked_date = CURDATE()";
        }
    }
    if ($fClient)        { $where[] = "ci.client_id=?";      $params[] = $fClient; }
    if ($fFacility)      { $where[] = "ci.facility_id=?";    $params[] = $fFacility; }
    if ($fProvider)      { $where[] = "COALESCE(ci.coded_provider_id, ci.provider_id)=?"; $params[] = $fProvider; }
    if ($fCarrier !== '') { $where[] = "a.carrier=?";        $params[] = $fCarrier; }
    if ($fBilStat !== '') { $where[] = "COALESCE(a.billing_status,'pending')=?"; $params[] = $fBilStat; }
    if ($fStatus === 'worked') {
        // Worked tab: most-recently-completed on top (worked_at is stamped NOW() on every save).
        $orderBy = "a.worked_at DESC, a.last_worked_date DESC, a.id DESC";
    } else {
        // To-work / Sent back / All: to-work first, then oldest-allocated (FIFO work order).
        $orderBy = "(a.inventory_status='allocated') DESC, a.allocated_at ASC, a.id ASC";
    }
}
$rows = $pdo->prepare("SELECT a.*, ci.patient_name, ci.patient_mrn, ci.patient_dob, ci.dos,
        c.name cn, f.name fn, pr.name prn, cp.name coded_prov, fw.name first_worked_name, wb.name worked_name
    FROM billing_allocation a
    JOIN coding_inventory ci ON ci.id=a.inventory_id
    LEFT JOIN clients c ON c.id=ci.client_id
    LEFT JOIN coding_facilities f ON f.id=ci.facility_id LEFT JOIN coding_providers pr ON pr.id=ci.provider_id
    LEFT JOIN coding_providers cp ON cp.id=ci.coded_provider_id
    LEFT JOIN users fw ON fw.id=a.first_worked_by LEFT JOIN users wb ON wb.id=a.worked_by
    WHERE " . implode(' AND ', $where) . "
    ORDER BY $orderBy
    LIMIT 1000");
$rows->execute($params);
$rows = $rows->fetchAll();

/* filter option lists — only what the biller actually has allocated to them */
$myClients = $pdo->prepare("SELECT DISTINCT c.id,c.name FROM billing_allocation a JOIN coding_inventory ci ON ci.id=a.inventory_id JOIN clients c ON c.id=ci.client_id WHERE a.allocated_biller=? ORDER BY c.name");
$myClients->execute([$uid]); $myClients = $myClients->fetchAll();
$myFacils = $pdo->prepare("SELECT DISTINCT f.id,f.name FROM billing_allocation a JOIN coding_inventory ci ON ci.id=a.inventory_id JOIN coding_facilities f ON f.id=ci.facility_id WHERE a.allocated_biller=? ORDER BY f.name");
$myFacils->execute([$uid]); $myFacils = $myFacils->fetchAll();
$myProvs = $pdo->prepare("SELECT DISTINCT pr.id,pr.name FROM billing_allocation a JOIN coding_inventory ci ON ci.id=a.inventory_id JOIN coding_providers pr ON pr.id=COALESCE(ci.coded_provider_id, ci.provider_id) WHERE a.allocated_biller=? ORDER BY pr.name");
$myProvs->execute([$uid]); $myProvs = $myProvs->fetchAll();
$myCarriers = $pdo->prepare("SELECT DISTINCT carrier FROM billing_allocation WHERE allocated_biller=? AND COALESCE(carrier,'')<>'' ORDER BY carrier");
$myCarriers->execute([$uid]); $myCarriers = $myCarriers->fetchAll(PDO::FETCH_COLUMN);

// FULL coded lines (DOS · CPT/ALF · Units · Modifier · ICD) for the visible charts + the open work chart,
// so the biller sees everything needed to bill — not just the CPT. (CPT shows paired with its ALF code.)
$cptIds = array_column($rows, 'inventory_id'); if ($workChart) $cptIds[] = (int) $workChart['inventory_id'];
$cptIds = $cptIds ? array_values(array_unique(array_map('intval', $cptIds))) : [];
$linesByChart  = $cptIds ? coding_effective_lines_bulk($pdo, $cptIds) : [];
$billedByChart = $cptIds ? billing_billed_lines_bulk($pdo, $cptIds) : [];   // which CPT line(s) are marked billed

/** One flat-table cell stacking a single field across a chart's coded lines (CPT paired with ALF). */
$codeCell = function (int $invId, string $field) use ($pdo, $linesByChart) {
    $lines = $linesByChart[$invId] ?? [];
    if (!$lines) return '<span class="text-secondary">—</span>';
    $out = [];
    foreach ($lines as $ln) {
        if     ($field === 'dos')   $out[] = e(fmt_date($ln['dos'] ?? null)) ?: '—';
        elseif ($field === 'cpt')   $out[] = '<strong>' . e(coding_alf_label($pdo, $ln['cpt'])) . '</strong>';
        elseif ($field === 'units') $out[] = (int) ($ln['units'] ?? 1);
        elseif ($field === 'mods')  $out[] = e(implode(', ', $ln['mods'] ?? [])) ?: '<span class="text-secondary">—</span>';
        elseif ($field === 'icds')  $out[] = e(implode(', ', $ln['icds'] ?? [])) ?: '<span class="text-secondary">—</span>';
    }
    return implode('<div class="border-top my-1" style="opacity:.4"></div>', $out);
};
/** The work card's coded-lines table (one row per line). Per line the biller picks WHICH code of the CPT/ALF
 *  pair was finalized & billed via a SEGMENTED CONTROL — CPT <value> · ALF <value> (no "Not billed"; a line with
 *  no ALF mapping offers only CPT). The radios use form="workform" so they post with the work form even though
 *  this table sits above it; the saved choice is pre-selected (.is-on, mirrored to the radio by JS). When the
 *  billing status is Billed / On-hold-deductible, a selection on EVERY line is required (validated both sides). */
$linesTable = function (int $invId) use ($pdo, $linesByChart, $billedByChart) {
    $lines = $linesByChart[$invId] ?? [];
    if (!$lines) return '<div class="wc-empty"><i class="ti ti-file-off me-1"></i>No coded lines on this chart.</div>';
    $billed = $billedByChart[$invId]['keys'] ?? [];
    $alfMap = coding_alf_map($pdo);   // [cpt => alf]

    $h  = '<div class="wc-lines">';
    $h .= '<div class="wc-lines-bar">'
        . '<span class="wc-lines-hint"><i class="ti ti-bulb me-1"></i>Per line, pick the code finalized &amp; billed on the claim</span>'
        . '<span id="wc-medicaid-hint" class="wc-medicaid-hint" style="display:none"><i class="ti ti-shield-check me-1"></i>Medicaid — defaulted to the first numeric CPT (G/M codes aren’t billable here). Tick any line to add.</span>'
        . '<span class="wc-quick btn-group btn-group-sm" role="group" aria-label="Set all lines">'
        . '<button type="button" class="btn btn-outline-primary bill-all" data-v="cpt">All CPT</button>'
        . '<button type="button" class="btn btn-outline-secondary bill-all" data-v="alf">All ALF</button>'
        . '<button type="button" class="btn btn-ghost-secondary bill-all" data-v="">Clear</button>'
        . '</span></div>';

    $h .= '<div class="table-responsive"><table class="table table-sm wc-lines-tbl mb-0">'
        . '<thead><tr>'
        . '<th class="text-nowrap">DOS</th>'
        . '<th>Billed code <span class="th-sub">CPT or ALF</span></th>'
        . '<th class="text-center">Units</th>'
        . '<th>Modifier(s)</th>'
        . '<th>ICD(s)</th>'
        . '</tr></thead><tbody>';

    foreach ($lines as $i => $ln) {
        $key = billing_line_key($ln, (int) $i);
        $cpt = (string) ($ln['cpt'] ?? '');
        $alf = (string) ($alfMap[$cpt] ?? '');
        $sel = $billed[$key]['type'] ?? '';
        $nm  = 'billed_code[' . e($key) . ']';

        // One segment = a <label> wrapping a visually-hidden native radio (keyboard + AT for free).
        $seg = function (string $val, string $cls, string $html, bool $on, string $data = '') use ($nm) {
            return '<label class="seg-opt ' . $cls . ($on ? ' is-on' : '') . '">'
                 . '<input type="radio" class="billsel" form="workform" name="' . $nm . '" value="' . $val . '"' . $data . ($on ? ' checked' : '') . '>'
                 . '<span class="seg-txt">' . $html . '</span></label>';
        };

        // data-cpt lets the client-side Medicaid rule find the first purely-NUMERIC CPT (G/M HCPCS codes carry a letter).
        $segs  = $seg('cpt', 'seg-cpt',  'CPT <b>' . (e($cpt) ?: '—') . '</b>', $sel === 'cpt', ' data-cpt="' . e($cpt) . '"');
        if ($alf !== '') $segs .= $seg('alf', 'seg-alf', 'ALF <b>' . e($alf) . '</b>', $sel === 'alf');

        $h .= '<tr>'
            . '<td class="wc-dos text-nowrap">' . (e(fmt_date($ln['dos'] ?? null)) ?: '—') . '</td>'
            . '<td><div class="seg" role="radiogroup" aria-label="Billed code for line ' . ($i + 1) . '">' . $segs . '</div></td>'
            . '<td class="text-center wc-num">' . (int) ($ln['units'] ?? 1) . '</td>'
            . '<td class="wc-meta">' . (e(implode(', ', $ln['mods'] ?? [])) ?: '<span class="text-secondary">—</span>') . '</td>'
            . '<td class="wc-meta">' . (e(implode(', ', $ln['icds'] ?? [])) ?: '<span class="text-secondary">—</span>') . '</td>'
            . '</tr>';
    }
    return $h . '</tbody></table></div></div>';
};

$carriers = billing_dropdowns($pdo, 'carrier');
$reasons  = billing_dropdowns($pdo, 'secondary_reason');
$comments = billing_dropdowns($pdo, 'comment');
$bsBadge  = ['billed'=>'green','hold_deductible'=>'orange','unbilled'=>'red'];

$pageTitle = $fMode === 'team' ? 'Team billing inventory' : 'My billing queue';
require __DIR__ . '/../includes/header.php';

/* ========================= TEAM INVENTORY (supervisor/manager, read-only) ========================= */
if ($fMode === 'team') {
    $tBiller = (int) ($_GET['biller_id'] ?? 0);
    $tInv    = in_array($_GET['inv'] ?? '', ['allocated','worked'], true) ? (string) $_GET['inv'] : '';
    $team = billing_team_inventory($pdo, $uid, [
        'biller_id'=>$tBiller, 'inventory_status'=>$tInv, 'billing_status'=>$fBilStat,
        'client_id'=>$fClient, 'facility_id'=>$fFacility, 'carrier'=>$fCarrier,
    ]);
    $teamUrl = fn(array $o = []) => '/admin/my-billing.php?' . http_build_query(array_filter(array_merge(
        ['mode'=>'team','biller_id'=>$tBiller,'inv'=>$tInv,'bstatus'=>$fBilStat,'client_id'=>$fClient,'facility_id'=>$fFacility,'carrier'=>$fCarrier], $o),
        fn($v)=>$v!==null&&$v!==''&&$v!==0));
    $bsBadge = ['billed'=>'green','hold_deductible'=>'orange','unbilled'=>'red'];
    $invBadge = ['allocated'=>'azure','worked'=>'green'];
    $hasFilter = ($tBiller||$tInv||$fBilStat!==''||$fClient||$fFacility||$fCarrier!=='');
    ?>
    <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-users-group me-2 text-primary"></i>Team billing inventory</h2>
            <div class="text-secondary small">Every chart allocated to <strong>your team</strong> (managers see the whole sub-tree; supervisors see their own reports). Read-only — allocate &amp; reassign from <a href="<?= e(url('/admin/billing-allocation.php')) ?>">Allocate billing</a>.</div>
        </div>
        <div class="col-auto">
            <?php if (can('billing.work')): ?><a href="<?= e(url('/admin/my-billing.php')) ?>" class="btn btn-outline-secondary"><i class="ti ti-inbox me-1"></i>My queue</a><?php endif; ?>
        </div>
    </div></div></div>
    <div class="page-body"><div class="container-xl">

        <!-- Per-biller summary -->
        <div class="row row-cards mb-3">
        <?php if (!$team['kpi']): ?>
            <div class="col-12"><div class="alert alert-info mb-0"><i class="ti ti-info-circle me-1"></i>No billers in your team have any allocated inventory yet.</div></div>
        <?php else: foreach ($team['kpi'] as $bid => $k): ?>
            <div class="col-sm-6 col-lg-4 col-xl-3"><div class="card"><div class="card-body p-2">
                <div class="d-flex justify-content-between align-items-center mb-1">
                    <a href="<?= e(url($teamUrl(['biller_id'=>$bid]))) ?>" class="fw-bold text-reset text-truncate" title="Filter to this biller"><?= e($k['biller'] ?: 'Unassigned') ?></a>
                    <span class="badge bg-secondary-lt"><?= (int)$k['total'] ?></span>
                </div>
                <div class="d-flex flex-wrap gap-1 small">
                    <span class="badge bg-azure-lt"><?= (int)$k['to_work'] ?> to-work</span>
                    <span class="badge bg-green-lt"><?= (int)$k['worked'] ?> worked</span>
                    <span class="badge bg-green-lt"><?= (int)$k['billed'] ?> billed</span>
                    <span class="badge bg-orange-lt"><?= (int)$k['hold_deductible'] ?> hold</span>
                    <span class="badge bg-red-lt"><?= (int)$k['unbilled'] ?> unbilled</span>
                </div>
            </div></div></div>
        <?php endforeach; endif; ?>
        </div>

        <!-- Filters -->
        <form method="GET" class="card mb-3"><div class="card-body py-2">
            <input type="hidden" name="mode" value="team">
            <div class="row g-2 align-items-end">
                <div class="col-md-3"><label class="form-label small mb-1">Biller</label>
                    <select name="biller_id" class="form-select form-select-sm">
                        <option value="">All team billers</option>
                        <?php foreach ($team['billers'] as $b): ?><option value="<?= (int)$b['id'] ?>" <?= $tBiller===(int)$b['id']?'selected':'' ?>><?= e($b['name']) ?></option><?php endforeach; ?>
                    </select></div>
                <div class="col-md-2"><label class="form-label small mb-1">Work status</label>
                    <select name="inv" class="form-select form-select-sm">
                        <option value="">All</option>
                        <option value="allocated" <?= $tInv==='allocated'?'selected':'' ?>>Allocated – to work</option>
                        <option value="worked" <?= $tInv==='worked'?'selected':'' ?>>Worked</option>
                    </select></div>
                <div class="col-md-2"><label class="form-label small mb-1">Billing status</label>
                    <select name="bstatus" class="form-select form-select-sm">
                        <option value="">Any</option>
                        <option value="billed" <?= $fBilStat==='billed'?'selected':'' ?>>Billed</option>
                        <option value="hold_deductible" <?= $fBilStat==='hold_deductible'?'selected':'' ?>>Hold – deductible</option>
                        <option value="unbilled" <?= $fBilStat==='unbilled'?'selected':'' ?>>Unbilled</option>
                    </select></div>
                <div class="col-md-2"><label class="form-label small mb-1">Client</label>
                    <select name="client_id" class="form-select form-select-sm">
                        <option value="">All</option>
                        <?php foreach ($team['clients'] as $cid=>$cn): ?><option value="<?= (int)$cid ?>" <?= $fClient===(int)$cid?'selected':'' ?>><?= e($cn) ?></option><?php endforeach; ?>
                    </select></div>
                <div class="col-md-3"><label class="form-label small mb-1">Facility</label>
                    <select name="facility_id" class="form-select form-select-sm">
                        <option value="">All</option>
                        <?php foreach ($team['facilities'] as $fid=>$fn): ?><option value="<?= (int)$fid ?>" <?= $fFacility===(int)$fid?'selected':'' ?>><?= e($fn) ?></option><?php endforeach; ?>
                    </select></div>
                <div class="col-md-3"><label class="form-label small mb-1">Carrier</label>
                    <select name="carrier" class="form-select form-select-sm">
                        <option value="">All</option>
                        <?php foreach ($team['carriers'] as $cr): ?><option value="<?= e($cr) ?>" <?= $fCarrier===$cr?'selected':'' ?>><?= e($cr) ?></option><?php endforeach; ?>
                    </select></div>
                <div class="col-auto"><button class="btn btn-sm btn-primary"><i class="ti ti-filter me-1"></i>Apply</button>
                    <?php if ($hasFilter): ?><a href="<?= e(url('/admin/my-billing.php?mode=team')) ?>" class="btn btn-sm btn-ghost-secondary">Clear</a><?php endif; ?></div>
            </div>
        </div></form>

        <!-- Inventory table -->
        <div class="card">
            <div class="card-header py-2"><h3 class="card-title mb-0">Charts</h3>
                <div class="card-actions text-secondary small"><?= number_format(count($team['rows'])) ?> chart(s)<?= count($team['rows'])>=5000 ? ' (showing first 5000 — narrow with filters)' : '' ?></div></div>
            <div class="table-responsive">
                <table class="table table-sm table-vcenter card-table">
                    <thead><tr><th>Biller</th><th>Patient</th><th>Client » Process » Facility</th><th class="text-nowrap">DOS</th><th>Work status</th><th>Billing status</th><th>Carrier</th><th>Reason</th><th class="text-nowrap">Allocated</th><th class="text-nowrap">Last worked</th></tr></thead>
                    <tbody>
                    <?php foreach ($team['rows'] as $r): ?>
                        <tr>
                            <td class="text-nowrap"><?= e($r['biller'] ?: '—') ?></td>
                            <td><?= e($r['patient_name'] ?: '—') ?><?php if ($r['patient_mrn']): ?><div class="text-secondary small">MRN <?= e($r['patient_mrn']) ?></div><?php endif; ?></td>
                            <td class="small"><?= e(trim(($r['cn'] ?? '') . ' » ' . ($r['pn'] ?? '') . ' » ' . ($r['fn'] ?? ''), ' »')) ?></td>
                            <td class="text-nowrap"><?= e($r['dos'] ? fmt_date($r['dos']) : '—') ?></td>
                            <td><span class="badge bg-<?= $invBadge[$r['inventory_status']] ?? 'secondary' ?>-lt"><?= e($r['inventory_status'] ?: '—') ?></span></td>
                            <td><?php $bs=$r['billing_status']; ?><?= $bs ? '<span class="badge bg-'.($bsBadge[$bs]??'secondary').'-lt">'.e($bs).'</span>' : '<span class="text-secondary">—</span>' ?></td>
                            <td class="small"><?= e($r['carrier'] ?: '—') ?></td>
                            <td class="small text-secondary"><?= e($r['secondary_reason'] ?: '') ?></td>
                            <td class="text-nowrap small text-secondary"><?= e($r['allocated_at'] ? date('Y-m-d', strtotime($r['allocated_at'])) : '') ?></td>
                            <td class="text-nowrap small text-secondary"><?= e($r['last_worked_date'] ? date('Y-m-d', strtotime($r['last_worked_date'])) : '') ?></td>
                        </tr>
                    <?php endforeach; ?>
                    <?php if (!$team['rows']): ?><tr><td colspan="10" class="text-center text-secondary py-4">No charts match these filters.</td></tr><?php endif; ?>
                    </tbody>
                </table>
            </div>
        </div>
    </div></div>
    <?php
    require __DIR__ . '/../includes/footer.php';
    return;
}
?>
<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-inbox me-2 text-primary"></i>My billing queue</h2>
        <div class="text-secondary small">The charts <strong>allocated to you</strong>. Use <strong>Work next</strong> to open them one by one, pick the <strong>carrier</strong> and a <strong>billing status</strong> (an Unbilled chart needs a secondary reason), then save.</div>
    </div>
    <div class="col-auto d-flex gap-2">
        <?php if ($isTeamViewer): ?><a href="<?= e(url('/admin/my-billing.php?mode=team')) ?>" class="btn btn-outline-secondary"><i class="ti ti-users-group me-1"></i>Team inventory</a><?php endif; ?>
        <a href="<?= e(url($selfUrl(['work'=>'nextpatient','cur'=>$workChart?(int)$workChart['inventory_id']:null]))) ?>" class="btn btn-primary <?= $kpi['to_work']?'':'disabled' ?>"><i class="ti ti-user-plus me-1"></i>Get next patient</a>
    </div>
</div></div></div>

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

    <div class="row row-cards mb-3">
        <?php
        $chips = [
            ['Allocated to me', $kpi['total'],           'list-check',   'primary', 'all'],
            ['To work',         $kpi['to_work'],         'clock',        'azure',   'to_work'],
            ['Worked',          $kpi['worked'],          'circle-check', 'green',   'worked'],
            ['Billed',          $kpi['billed'],          'receipt',      'green',   null],
            ['On Hold / Deduct',$kpi['hold_deductible'], 'pause',        'orange',  null],
            ['Unbilled',        $kpi['unbilled'],        'alert-circle', 'red',     null],
        ];
        foreach ($chips as [$lbl,$val,$icon,$col,$st]): ?>
        <div class="col"><?php $tag = $st!==null?'a':'div'; ?>
            <<?= $tag ?> <?= $st!==null?'href="'.e(url($selfUrl(['status'=>$st,'work'=>null]))).'"':'' ?> class="text-decoration-none">
            <div class="card card-sm <?= $st!==null&&$fStatus===$st?'border-primary':'' ?>"><div class="card-body py-2 text-center">
                <div class="stat-label"><i class="ti ti-<?= $icon ?> me-1"></i><?= e($lbl) ?></div>
                <div class="h3 mb-0 text-<?= $col ?>"><?= number_format($val) ?></div>
            </div></div></<?= $tag ?>>
        </div>
        <?php endforeach; ?>
    </div>

    <?php if ($workChart): $wId = (int)$workChart['inventory_id']; $cur = (string)($workChart['billing_status'] ?? '');
        // Patient-visit progress: how many MORE unworked visits this patient has after this one.
        $wPkey = billing_patient_key_of($pdo, $wId);
        $wMore = $wPkey ? billing_patient_remaining_visits($pdo, $uid, $wPkey, $wId) : 0; ?>
    <!-- ============================================================= FOCUSED WORK CARD (one chart at a time) -->
    <div class="card mb-3 border-primary wc-card">
        <div class="card-header wc-head">
            <h3 class="card-title mb-0"><i class="ti ti-file-pencil me-2"></i>Work this chart
                <span class="badge bg-<?= $wMore>0?'azure':'green' ?>-lt ms-2"><?= $wMore>0 ? ((int)$wMore.' more visit'.($wMore==1?'':'s').' for this patient') : 'last visit for this patient' ?></span>
            </h3>
            <div class="card-actions"><a href="<?= e(url($selfUrl(['work'=>null]))) ?>" class="btn btn-sm btn-ghost-secondary"><i class="ti ti-x me-1"></i>Close</a></div>
        </div>
        <div class="card-body wc-body">

            <!-- Read-only context strip: one labelled cell per field (Patient Name · MRN · DOB · Provider · DOS / Client · Facility) -->
            <dl class="wc-ctx">
                <div class="wc-ctx-item"><dt>Patient Name</dt><dd class="wc-strong"><?= e($workChart['patient_name']) ?: '—' ?></dd></div>
                <div class="wc-ctx-item"><dt>MRN</dt><dd class="wc-strong"><?php $mrn = $workChart['patient_mrn'] ?? ''; ?><?= $mrn !== '' ? e($mrn) : '—' ?></dd></div>
                <div class="wc-ctx-item"><dt>DOB</dt><dd class="wc-strong"><?= e(fmt_date($workChart['patient_dob'])) ?: '—' ?></dd></div>
                <div class="wc-ctx-item"><dt>Provider</dt><dd class="wc-strong"><?= e($workChart['coded_prov'] ?: $workChart['prn']) ?: '—' ?></dd></div>
                <div class="wc-ctx-item"><dt>DOS</dt><dd class="wc-strong"><?= e(fmt_date($workChart['dos'])) ?: '—' ?></dd></div>
                <div class="wc-ctx-item"><dt>Client</dt><dd class="wc-strong"><?= e($workChart['cn']) ?: '—' ?></dd></div>
                <div class="wc-ctx-item"><dt>Facility</dt><dd class="wc-strong"><?= e($workChart['fn']) ?: '—' ?></dd></div>
            </dl>

            <!-- Coded lines + per-line billed choice (radios post via form="workform") -->
            <div class="wc-section">
                <?= $linesTable($wId) ?>
                <div id="wc-billwarn" class="wc-billwarn" style="display:none"><i class="ti ti-alert-triangle me-1"></i>Pick a <strong>CPT</strong> on every line, or an <strong>ALF</strong> on any line (ALF bills the whole encounter), before saving a <strong>Billed</strong> / <strong>On-hold-deductible</strong> chart.</div>
            </div>

            <!-- Disposition form -->
            <form method="POST" action="<?= e(url($selfUrl())) ?>" id="workform" class="wc-form">
                <?= csrf_field() ?>
                <input type="hidden" name="action" value="work">
                <input type="hidden" name="inventory_id" value="<?= $wId ?>">

                <div class="row g-3">
                    <div class="col-12 col-md-6 col-lg-3">
                        <label class="form-label req" for="carrierfld">Carrier (insurance)</label>
                        <input list="carrier-list" id="carrierfld" name="carrier" class="form-control" autocomplete="off" required
                               placeholder="Search carrier…" value="<?= e($workChart['carrier'] ?? '') ?>">
                        <datalist id="carrier-list"><?php foreach ($carriers as $c): ?><option value="<?= e($c) ?>"><?php endforeach; ?></datalist>
                        <?php if (!$carriers): ?><div class="form-hint text-danger">No carriers configured yet — ask your supervisor to add them.</div><?php endif; ?>
                    </div>

                    <div class="col-12 col-md-6 col-lg-3">
                        <label class="form-label req" for="bstatus">Billing status</label>
                        <select name="billing_status" class="form-select" id="bstatus" required>
                            <option value="">— Select —</option>
                            <?php foreach (BILLING_WORK_STATUSES as $k=>$lbl): ?>
                                <option value="<?= e($k) ?>" <?= $cur===$k?'selected':'' ?>><?= e($lbl) ?></option>
                            <?php endforeach; ?>
                        </select>
                    </div>

                    <div class="col-12 col-md-6 col-lg-3" id="reasonwrap" style="<?= $cur==='unbilled'?'':'display:none' ?>">
                        <label class="form-label req" for="reasonsel">Unbilled secondary reason</label>
                        <select name="secondary_reason" class="form-select" id="reasonsel">
                            <option value="">— Select —</option>
                            <?php foreach ($reasons as $rs): ?><option value="<?= e($rs) ?>" <?= ((string)($workChart['secondary_reason']??''))===$rs?'selected':'' ?>><?= e($rs) ?></option><?php endforeach; ?>
                        </select>
                        <?php if (!$reasons): ?><div class="form-hint text-warning">No Unbilled reasons configured — ask your supervisor.</div><?php endif; ?>
                    </div>

                    <div class="col-12 col-md-6 col-lg-3">
                        <label class="form-label" for="commentsel">Comment <span class="wc-opt">optional</span></label>
                        <select name="comment" id="commentsel" class="form-select">
                            <option value="">— None —</option>
                            <?php foreach ($comments as $cm): ?><option value="<?= e($cm) ?>" <?= ((string)($workChart['comment']??''))===$cm?'selected':'' ?>><?= e($cm) ?></option><?php endforeach; ?>
                        </select>
                    </div>
                </div>

                <div class="wc-actions">
                    <button class="btn btn-primary"><i class="ti ti-device-floppy me-1"></i>Save &amp; next visit</button>
                    <a href="<?= e(url($selfUrl(['work'=>null]))) ?>" class="btn btn-ghost-secondary">Cancel</a>
                    <span class="wc-actions-hint ms-auto"><span class="text-danger">*</span> required · <strong>Save &amp; next visit</strong> moves through this patient; <strong>Get next patient</strong> (top right) pulls the next one</span>
                </div>
            </form>
        </div>
    </div>
    <script>
    (function(){
        // 1) Billing status -> Unbilled secondary-reason toggle (unchanged contract).
        var s=document.getElementById('bstatus'), w=document.getElementById('reasonwrap'), r=document.getElementById('reasonsel');
        var cf=document.getElementById('carrierfld'), cl=document.querySelector('label[for="carrierfld"]');
        function t(){ var u=s.value==='unbilled'; w.style.display=u?'':'none'; if(r){ r.required=u; if(!u) r.value=''; }
            if(cf) cf.required=!u; if(cl) cl.classList.toggle('req', !u); }   // carrier not required when Unbilled
        if(s){ s.addEventListener('change',t); t(); }

        // Mirror each radio's checked state onto its .seg-opt label (.is-on) — the label WRAPS the radio,
        // so a +sibling CSS selector can't reach it. Drives the segmented-control colors in every browser.
        function paint(group){
            group.querySelectorAll('.seg-opt').forEach(function(opt){
                var rb = opt.querySelector('input.billsel');
                opt.classList.toggle('is-on', !!(rb && rb.checked));
            });
        }
        function paintAll(){ document.querySelectorAll('.wc-card .seg').forEach(paint); }

        // 2) Billed-code requirement: when status is Billed / On-hold-deductible, EVERY line needs a CPT/ALF pick.
        var warn = document.getElementById('wc-billwarn');
        function needsCode(){ return s && (s.value==='billed' || s.value==='hold_deductible'); }
        function isMedicaid(){ return !!(cf && /medicaid/i.test(cf.value||'')); }
        function allPicked(){   // ALF bills the whole encounter → one ALF pick is enough; otherwise every line needs a CPT/ALF pick
            var anyAlf=false, allHave=true, anyCode=false;
            document.querySelectorAll('.wc-card .seg').forEach(function(g){
                var c=g.querySelector('.billsel:checked');
                if(c){ anyCode=true; if(c.value==='alf') anyAlf=true; }
                else allHave=false;
            });
            if(isMedicaid()) return anyCode;   // Medicaid: billing only the eligible (numeric) CPTs is valid — a subset is enough
            return anyAlf || allHave;
        }
        function clearWarn(){
            if(warn) warn.style.display='none';
            document.querySelectorAll('.wc-card .seg.seg-missing').forEach(function(g){ g.classList.remove('seg-missing'); });
        }

        document.querySelectorAll('.billsel').forEach(function(rb){
            rb.addEventListener('change', function(){
                var g=rb.closest('.seg'); if(g){ paint(g); g.classList.remove('seg-missing'); }
                if(allPicked()) clearWarn();
            });
        });

        // "All CPT" / "All ALF" set every line; "Clear" (data-v="") unchecks every line (no "Not billed" option now).
        document.querySelectorAll('.bill-all').forEach(function(btn){
            btn.addEventListener('click', function(){
                var v = btn.getAttribute('data-v');
                if(v===''){ document.querySelectorAll('.billsel').forEach(function(rb){ rb.checked=false; }); }
                else { document.querySelectorAll('.billsel[value="'+v+'"]').forEach(function(rb){ rb.checked=true; }); }
                paintAll();
                if(allPicked()) clearWarn();
            });
        });

        // 3) MEDICAID default: G/M (HCPCS) codes aren't billable on some Medicaid plans, so when the carrier contains
        //    "Medicaid" default the billed selection to ONLY the first purely-numeric CPT and clear the rest. Fires when
        //    the carrier is (re)selected — NOT on load, so a previously-saved selection is preserved. Fully overridable:
        //    the biller can tick any line afterward (allPicked() then only needs at least one code for Medicaid).
        var medHint = document.getElementById('wc-medicaid-hint');
        function medicaidDefault(){
            var firstNumeric = null;
            document.querySelectorAll('.billsel[value="cpt"]').forEach(function(rb){
                if(!firstNumeric && /^\d+$/.test((rb.getAttribute('data-cpt')||'').trim())) firstNumeric = rb;
            });
            document.querySelectorAll('.billsel').forEach(function(rb){ rb.checked=false; });
            if(firstNumeric) firstNumeric.checked = true;
            paintAll();
            if(allPicked()) clearWarn();
        }
        function syncMedHint(){ if(medHint) medHint.style.display = isMedicaid() ? '' : 'none'; }
        // Apply the default only when the carrier TRANSITIONS into Medicaid (from empty / a non-Medicaid carrier), so
        // re-editing the carrier text while it stays Medicaid preserves the biller's manual picks. Not applied on load.
        var wasMedicaid = isMedicaid();
        if(cf){ cf.addEventListener('change', function(){ var now=isMedicaid(); if(now && !wasMedicaid) medicaidDefault(); wasMedicaid=now; syncMedHint(); }); syncMedHint(); }

        // Switching to a non-billed status drops the requirement → clear any warning/highlight.
        if(s) s.addEventListener('change', function(){ if(!needsCode()) clearWarn(); });

        // Hard gate: block submit (and highlight the offending lines) if a billed chart has any line uncoded.
        var form = document.getElementById('workform');
        if(form) form.addEventListener('submit', function(e){
            if(needsCode() && !allPicked()){
                e.preventDefault();
                document.querySelectorAll('.wc-card .seg').forEach(function(g){ g.classList.toggle('seg-missing', !g.querySelector('.billsel:checked')); });
                if(warn) warn.style.display='';
                var first = document.querySelector('.wc-card .seg.seg-missing');
                if(first) first.scrollIntoView({block:'center', behavior:'smooth'});
            }
        });

        paintAll();   // match server pre-selected radios on load
    })();
    </script>
    <style>
    /* Work-card UI: scoped wc- and seg- classes; colors from the m- and tblr- tokens plus one wc-alf accent. */
    .wc-card{ --wc-alf:#2fa36b; overflow:hidden; }
    html[data-bs-theme="dark"] .wc-card{ --wc-alf:#2ec27e; }
    .wc-head{ background:var(--tblr-primary-lt, rgba(32,107,196,.10)); display:flex; align-items:center; justify-content:space-between; }
    .wc-body{ padding:1rem 1.25rem 1.1rem; }
    /* Patient context strip: a bordered grid — one labelled cell per field (5 across, wraps to a 2nd row). The
       cell outlines overlap into single 1px gridlines; the container box-shadow draws the rounded outer frame. */
    .wc-ctx{ display:grid; grid-template-columns:repeat(5,minmax(0,1fr)); margin:0 0 .9rem; border-radius:8px; overflow:hidden; box-shadow:0 0 0 1px var(--m-border); background:var(--m-surface-2); }
    .wc-ctx-item{ padding:.5rem .85rem; outline:1px solid var(--m-border); background:var(--m-surface-2); min-width:0; }
    .wc-ctx dt{ font-size:.66rem; font-weight:600; letter-spacing:.05em; text-transform:uppercase; color:var(--m-text-soft); margin:0 0 .15rem; }
    .wc-ctx dd{ margin:0; line-height:1.3; }
    .wc-ctx .wc-strong{ font-weight:600; color:var(--m-text); word-break:break-word; }
    @media (max-width:991.98px){ .wc-ctx{ grid-template-columns:repeat(3,minmax(0,1fr)); } }
    .wc-section{ margin-bottom:1rem; }
    .wc-empty{ color:var(--m-text-soft); font-size:.9rem; padding:.75rem 0; }
    .wc-lines-bar{ display:flex; align-items:center; flex-wrap:wrap; gap:.5rem; margin-bottom:.45rem; }
    .wc-lines-hint{ font-size:.78rem; font-weight:500; color:var(--m-text-soft); }
    .wc-medicaid-hint{ font-size:.76rem; font-weight:600; color:#0f7b4f; background:color-mix(in srgb,#16a34a 12%,transparent); border:1px solid color-mix(in srgb,#16a34a 30%,transparent); border-radius:6px; padding:2px 8px; }
    .wc-quick{ margin-left:auto; }
    .wc-lines-tbl{ font-size:.84rem; width:auto; max-width:100%; }   /* width:auto → columns hug content (no big gap before Units) */
    .wc-lines-tbl thead th{ font-size:.66rem; text-transform:uppercase; letter-spacing:.04em; color:var(--m-text-soft); font-weight:600; border:1px solid var(--m-border); background:var(--m-surface-2); padding:.35rem .7rem; white-space:nowrap; }
    .wc-lines-tbl thead .th-sub{ text-transform:none; letter-spacing:0; font-weight:400; opacity:.75; }
    .wc-lines-tbl tbody td{ padding:.45rem .7rem; vertical-align:middle; border:1px solid var(--m-border); }
    .wc-dos{ color:var(--m-text-soft); }
    .wc-num{ font-variant-numeric:tabular-nums; color:var(--m-text); }
    .wc-meta{ color:var(--m-text); }
    .seg{ display:inline-flex; flex-wrap:wrap; gap:0; border:1px solid var(--m-border-strong); border-radius:7px; overflow:hidden; background:var(--m-surface); }
    .seg-opt{ position:relative; margin:0; cursor:pointer; user-select:none; padding:.3rem .7rem; font-size:.8rem; line-height:1.1; color:var(--m-text-soft); border-left:1px solid var(--m-border); display:inline-flex; align-items:center; transition:background .12s,color .12s; }
    .seg-opt:first-child{ border-left:0; }
    .seg-opt b{ font-weight:700; }
    .seg-opt input{ position:absolute; opacity:0; width:1px; height:1px; margin:0; pointer-events:none; }
    .seg-opt:hover{ background:var(--m-surface-2); color:var(--m-text); }
    .seg-opt.seg-cpt.is-on,  .seg-opt.seg-cpt:has(input:checked){ background:var(--tblr-primary,#206bc4); color:#fff; }
    .seg-opt.seg-alf.is-on,  .seg-opt.seg-alf:has(input:checked){ background:var(--wc-alf,#2fa36b); color:#fff; }
    .seg-opt.seg-cpt.is-on b, .seg-opt.seg-alf.is-on b, .seg-opt.seg-cpt:has(input:checked) b, .seg-opt.seg-alf:has(input:checked) b{ color:#fff; }
    .seg-opt:focus-within{ outline:2px solid var(--tblr-primary); outline-offset:-2px; z-index:1; }
    .seg.seg-missing{ outline:2px solid var(--tblr-danger,#d63939); outline-offset:1px; }
    .wc-billwarn{ margin-top:.5rem; font-size:.82rem; font-weight:500; color:var(--tblr-danger,#d63939); }
    .wc-form{ margin:0; }
    .wc-form .form-label{ font-weight:600; font-size:.82rem; color:var(--m-text); margin-bottom:.3rem; }
    .wc-form .form-label.req::after{ content:"*"; color:var(--tblr-danger,#d63939); font-weight:700; margin-left:.2rem; }
    .wc-opt{ font-weight:400; font-size:.72rem; color:var(--m-text-soft); text-transform:none; margin-left:.25rem; }
    .wc-actions{ display:flex; align-items:center; flex-wrap:wrap; gap:.6rem; margin-top:1rem; padding-top:.85rem; border-top:1px solid var(--m-border); }
    .wc-actions .btn-primary{ font-weight:600; padding-inline:1.1rem; }
    .wc-actions-hint{ font-size:.8rem; color:var(--m-text-soft); }
    @media (max-width:575.98px){
        .wc-body{ padding:.85rem .9rem 1rem; }
        .wc-quick{ margin-left:0; }
        .wc-ctx{ grid-template-columns:repeat(2,minmax(0,1fr)); }
    }
    </style>
    <?php endif; ?>

    <!-- ============================================================= FILTERS (full queue only; hidden while a patient is open) -->
    <?php if (!$patientFocus): ?>
    <form method="GET" class="card mb-3"><div class="card-body py-2">
        <input type="hidden" name="status" value="<?= e($fStatus) ?>">
        <div class="row g-2 align-items-end">
            <div class="col-auto"><label class="form-label small mb-1">Client</label>
                <select name="client_id" class="form-select form-select-sm" onchange="this.form.submit()"><option value="0">All clients</option>
                    <?php foreach ($myClients as $o): ?><option value="<?= (int)$o['id'] ?>" <?= $fClient===(int)$o['id']?'selected':'' ?>><?= e($o['name']) ?></option><?php endforeach; ?></select></div>
            <div class="col-auto"><label class="form-label small mb-1">Facility</label>
                <select name="facility_id" class="form-select form-select-sm" onchange="this.form.submit()"><option value="0">All facilities</option>
                    <?php foreach ($myFacils as $o): ?><option value="<?= (int)$o['id'] ?>" <?= $fFacility===(int)$o['id']?'selected':'' ?>><?= e($o['name']) ?></option><?php endforeach; ?></select></div>
            <div class="col-auto"><label class="form-label small mb-1">Provider</label>
                <select name="provider_id" class="form-select form-select-sm" onchange="this.form.submit()"><option value="0">All providers</option>
                    <?php foreach ($myProvs as $o): ?><option value="<?= (int)$o['id'] ?>" <?= $fProvider===(int)$o['id']?'selected':'' ?>><?= e($o['name']) ?></option><?php endforeach; ?></select></div>
            <div class="col-auto"><label class="form-label small mb-1">Carrier</label>
                <select name="carrier" class="form-select form-select-sm" onchange="this.form.submit()"><option value="">All carriers</option>
                    <?php foreach ($myCarriers as $cn): ?><option value="<?= e($cn) ?>" <?= $fCarrier===(string)$cn?'selected':'' ?>><?= e($cn) ?></option><?php endforeach; ?></select></div>
            <div class="col-auto"><label class="form-label small mb-1">Billing status</label>
                <select name="bstatus" class="form-select form-select-sm" onchange="this.form.submit()"><option value="">Any</option>
                    <?php foreach (['pending'=>'Pending','billed'=>'Billed','hold_deductible'=>'On hold/deduct','unbilled'=>'Unbilled'] as $k=>$v): ?><option value="<?= e($k) ?>" <?= $fBilStat===$k?'selected':'' ?>><?= e($v) ?></option><?php endforeach; ?></select></div>
            <?php if ($fStatus === 'worked'): ?>
            <input type="hidden" name="wall" value="<?= $fwAll?'1':'' ?>">
            <div class="col-auto"><label class="form-label small mb-1" title="Completed on / after this date">Worked from</label>
                <input type="date" name="wfrom" value="<?= e($fwFrom) ?>" max="<?= e(date('Y-m-d')) ?>" class="form-control form-control-sm" onchange="this.form.submit()"></div>
            <div class="col-auto"><label class="form-label small mb-1" title="Completed on / before this date">Worked to</label>
                <input type="date" name="wto" value="<?= e($fwTo) ?>" max="<?= e(date('Y-m-d')) ?>" class="form-control form-control-sm" onchange="this.form.submit()"></div>
            <?php endif; ?>
            <div class="col"><label class="form-label small mb-1">Search</label>
                <input type="search" id="mb_search" class="form-control form-control-sm" placeholder="Patient, MRN, carrier…" oninput="mbSearch()" autocomplete="off"></div>
            <?php if ($fClient||$fFacility||$fProvider||$fCarrier!==''||$fBilStat!==''||$fwFrom!==''||$fwTo!==''||$fwAll): ?><div class="col-auto"><a href="<?= e(url($selfUrl(['client_id'=>null,'facility_id'=>null,'provider_id'=>null,'carrier'=>null,'bstatus'=>null,'wfrom'=>null,'wto'=>null,'wall'=>null]))) ?>" class="btn btn-sm btn-link text-secondary">Clear</a></div><?php endif; ?>
        </div>
    </div></form>
    <?php endif; ?>

    <!-- ============================================================= QUEUE TABLE -->
    <?php
    // Column model: label + sortable flag. Each column maps 1:1 to a body cell (same order) so the per-column
    // filter inputs (data-col = cell index) line up. The trailing action column is not sortable/filterable.
    $cols = [
        ['Patient', true], ['DOB', true], ['Client', true], ['Facility', true], ['Provider', true],
        ['DOS', true], ['CPT/ALF', true], ['Units', true], ['Modifier(s)', true], ['ICD(s)', true],
        ['Billed', true], ['Carrier', true], ['Billing status', true], ['Reason / comment', true],
        ['Worked', true], ['Worked by', true], ['Audit', true],
    ];
    $colspan = count($cols) + 1;
    ?>
    <div class="card">
        <div class="card-header">
            <h3 class="card-title"><span id="mb_count"><?= number_format(count($rows)) ?></span>
                <?php if ($patientFocus): ?>open visit(s) · <?= e($workChart['patient_name']) ?>
                <?php elseif ($fStatus === 'worked'): ?>chart(s) ·
                    <?php if ($fwFrom !== '' || $fwTo !== ''): ?>Worked <?= e($fwFrom ?: 'earliest') ?> &rarr; <?= e($fwTo ?: 'today') ?>
                        <a class="small fw-normal ms-2" href="<?= e(url($selfUrl(['wfrom'=>null,'wto'=>null,'wall'=>null]))) ?>">Today only</a>
                    <?php elseif ($fwAll): ?>Worked <span class="text-secondary">· all dates</span>
                        <a class="small fw-normal ms-2" href="<?= e(url($selfUrl(['wall'=>null]))) ?>">Today only</a>
                    <?php else: ?>Completed today <span class="text-secondary small">(<?= e(date('M j')) ?>)</span>
                        <a class="small fw-normal ms-2" href="<?= e(url($selfUrl(['wall'=>'1']))) ?>">Show all dates</a>
                    <?php endif; ?>
                <?php else: ?>chart(s) · <?= e(['to_work'=>'To work','worked'=>'Worked','all'=>'All'][$fStatus] ?? ucfirst($fStatus)) ?><?php endif; ?></h3>
            <div class="card-actions text-secondary small"><?php if ($patientFocus): ?><a href="<?= e(url($selfUrl(['work'=>null]))) ?>"><i class="ti ti-arrow-left me-1"></i>Back to full queue</a><?php else: ?>Click a header to sort · type under a header to filter<?php endif; ?></div>
        </div>
        <div class="table-responsive"><table class="table table-vcenter card-table" id="mb_table">
            <thead>
                <tr>
                    <?php foreach ($cols as $i => [$lbl, $sortable]): ?>
                        <th data-col="<?= $i ?>"<?= $sortable ? ' class="mb-th" onclick="mbSort(this)" style="cursor:pointer"' : '' ?>><?= e($lbl) ?><?php if ($sortable): ?> <span class="mb-arrow text-secondary"></span><?php endif; ?></th>
                    <?php endforeach; ?>
                    <th class="w-1"></th>
                </tr>
                <tr class="mb-filterrow">
                    <?php foreach ($cols as $i => $_): ?>
                        <th class="p-1"><input type="text" class="form-control form-control-sm mb-filter" data-col="<?= $i ?>" placeholder="filter" autocomplete="off"></th>
                    <?php endforeach; ?>
                    <th class="w-1"></th>
                </tr>
            </thead>
            <tbody>
            <?php if (!$rows): ?><tr><td colspan="<?= $colspan ?>" class="text-center text-secondary py-4">No charts in this view. 🎉</td></tr>
            <?php else: foreach ($rows as $r): $iid=(int)$r['inventory_id']; $bs=(string)($r['billing_status']??''); $todo=$r['inventory_status']==='allocated';
                $billedCodes = $billedByChart[$iid]['codes'] ?? [];   // [['code'=>..,'type'=>'cpt'|'alf'], ...]
                $wc = (int)($r['work_count'] ?? 0); $fwn = (string)($r['first_worked_name'] ?? ''); $lwn = (string)($r['worked_name'] ?? ''); ?>
                <tr<?= $workId===$iid?' class="table-active"':'' ?>>
                    <td><strong><?= e($r['patient_name']) ?></strong><div class="small text-secondary"><?= e($r['patient_mrn'] ?? '') ?></div></td>
                    <td class="small text-nowrap" data-v="<?= e((string)($r['patient_dob'] ?? '')) ?>"><?= e(fmt_date($r['patient_dob'])) ?: '—' ?></td>
                    <td class="small text-secondary"><?= e($r['cn']) ?></td>
                    <td class="small"><?= e($r['fn']) ?></td>
                    <td class="small"><?= e($r['coded_prov'] ?: $r['prn']) ?></td>
                    <td class="small text-nowrap"><?= $codeCell($iid,'dos') ?></td>
                    <td class="small"><?= $codeCell($iid,'cpt') ?></td>
                    <td class="small text-center"><?= $codeCell($iid,'units') ?></td>
                    <td class="small"><?= $codeCell($iid,'mods') ?></td>
                    <td class="small"><?= $codeCell($iid,'icds') ?></td>
                    <td class="small"><?= $billedCodes ? implode(' ', array_map(fn($c)=>'<span class="badge bg-green-lt" title="'.e(strtoupper((string)$c['type'])).' billed">'.e((string)$c['code']).' <span class="text-secondary" style="font-size:.85em">'.e(strtoupper((string)$c['type'])).'</span></span>', $billedCodes)) : '<span class="text-secondary">—</span>' ?></td>
                    <td class="small"><?= e($r['carrier'] ?: '—') ?></td>
                    <td><?= $bs!=='' ? '<span class="badge bg-'.($bsBadge[$bs]??'secondary').'-lt">'.e(BILLING_WORK_STATUSES[$bs]??$bs).'</span>' : '<span class="text-secondary">—</span>' ?></td>
                    <td class="small text-secondary"><?= e($r['secondary_reason'] ?: '') ?><?php if ($r['comment']): ?><div><?= e($r['comment']) ?></div><?php endif; ?></td>
                    <td class="small text-nowrap text-secondary" data-v="<?= e((string)($r['last_worked_date'] ?? '')) ?>"><?= e(fmt_date($r['last_worked_date'])) ?></td>
                    <td class="small"><?php if ($lwn==='' && $fwn===''): ?><span class="text-secondary">—</span>
                        <?php else: ?><?= e($lwn ?: $fwn) ?>
                            <?php if ($wc>1): ?> <span class="badge bg-azure-lt" title="Worked <?= $wc ?> time(s)">rework ×<?= $wc-1 ?></span>
                                <?php if ($fwn!=='' && $fwn!==$lwn): ?><div class="text-secondary" style="font-size:.7rem">first: <?= e($fwn) ?></div><?php endif; ?>
                            <?php endif; ?>
                        <?php endif; ?>
                    </td>
                    <td class="small"><?php $ar=(string)($r['audit_result']??''); $rs=(string)($r['rebuttal_status']??'none');
                        if ($ar==='') echo $r['in_sample']?'<span class="badge bg-purple-lt" title="In the audit sample">Sample</span>':'<span class="text-secondary">—</span>';
                        elseif ($ar==='pass') echo '<span class="badge bg-green-lt">Pass</span>';
                        else { echo '<span class="badge bg-red-lt">Error</span>';
                            if ($r['audit_error_category']) echo ' <span class="badge bg-red-lt">'.e((string)$r['audit_error_category']).'</span>';
                            if ($rs==='raised') echo ' <span class="badge bg-purple-lt">rebuttal sent</span>';
                            elseif ($rs==='accepted') echo ' <span class="badge bg-green-lt">overturned</span>';
                            elseif ($rs==='rejected') echo ' <span class="badge bg-secondary-lt">rejected</span>';
                            if (($rs==='none' || $rs==='rejected') && $r['inventory_status']==='worked') { ?>
                                <button class="btn btn-sm btn-ghost-danger py-0 px-1 ms-1" type="button" data-bs-toggle="collapse" data-bs-target="#reb<?= $iid ?>" title="Dispute this error"><i class="ti ti-message-2"></i> Rebut</button>
                            <?php }
                        } ?>
                        <?php if ($r['audit_comment']): ?><div class="text-secondary small" title="Auditor's note"><i class="ti ti-message-2 me-1"></i><?= e($r['audit_comment']) ?></div><?php endif; ?>
                    </td>
                    <td class="text-end"><a href="<?= e(url($selfUrl(['work'=>$iid]))) ?>" class="btn btn-sm <?= $todo?'btn-primary':'btn-outline-primary' ?>"><i class="ti ti-<?= $todo?'pencil':'refresh' ?> me-1"></i><?= $todo?'Work':'Rework' ?></a></td>
                </tr>
                <?php if (($r['audit_result']??'')==='error' && $r['inventory_status']==='worked' && in_array((string)($r['rebuttal_status']??'none'),['none','rejected'],true)): ?>
                <tr class="collapse mb-sub" id="reb<?= $iid ?>"><td colspan="<?= $colspan ?>" class="bg-body-tertiary">
                    <form method="POST" action="<?= e(url($selfUrl())) ?>" class="d-flex gap-2 align-items-center py-1">
                        <?= csrf_field() ?><input type="hidden" name="action" value="rebut"><input type="hidden" name="inventory_id" value="<?= $iid ?>">
                        <span class="small text-secondary">Rebut audit error:</span>
                        <input name="note" class="form-control form-control-sm" placeholder="Why you disagree…" maxlength="1000" required style="max-width:480px">
                        <button class="btn btn-sm btn-danger">Send rebuttal</button>
                    </form>
                </td></tr>
                <?php endif; ?>
            <?php endforeach; endif; ?>
            </tbody>
        </table></div>
        <?php if (count($rows) >= 1000): ?><div class="card-footer text-secondary small">Showing first 1000.</div><?php endif; ?>
    </div>
</div></div>
<script>
// Combined per-column filter + click-to-sort over the queue. Rebuttal sub-rows (.mb-sub) follow their parent.
(function(){
    var table=document.getElementById('mb_table'); if(!table) return;
    var tb=table.tBodies[0];
    function apply(){
        var gsEl=document.getElementById('mb_search'); var gs=gsEl?(gsEl.value||'').toLowerCase().trim():'';
        var filters=Array.prototype.map.call(document.querySelectorAll('.mb-filter'), function(inp){ return {col:+inp.getAttribute('data-col'), q:(inp.value||'').toLowerCase().trim()}; });
        var n=0, prevShown=true;
        Array.prototype.forEach.call(tb.rows, function(r){
            if(r.classList.contains('mb-sub')){ if(!prevShown) r.style.display='none'; return; }  // hide sub-row if parent hidden
            var show=true;
            if(gs && r.textContent.toLowerCase().indexOf(gs)===-1) show=false;
            if(show){ for(var i=0;i<filters.length;i++){ var f=filters[i]; if(!f.q) continue; var c=r.cells[f.col]; if(!c || c.textContent.toLowerCase().indexOf(f.q)===-1){ show=false; break; } } }
            r.style.display=show?'':'none'; prevShown=show; if(show)n++;
        });
        var cc=document.getElementById('mb_count'); if(cc) cc.textContent=n.toLocaleString();
    }
    document.querySelectorAll('.mb-filter').forEach(function(inp){ inp.addEventListener('input',apply); inp.addEventListener('click',function(e){ e.stopPropagation(); }); });
    window.mbApply=apply; window.mbSearch=apply;   // alias: the toolbar search box calls mbSearch()
    window.mbSort=function(th){
        var idx=+th.getAttribute('data-col'); if(isNaN(idx)) return;
        var asc=th.getAttribute('data-asc')!=='1';
        table.querySelectorAll('thead th').forEach(function(h){ h.removeAttribute('data-asc'); var a=h.querySelector('.mb-arrow'); if(a)a.textContent=''; });
        th.setAttribute('data-asc',asc?'1':'0'); var ar=th.querySelector('.mb-arrow'); if(ar)ar.textContent=asc?'▲':'▼';
        var groups=[], cur=null;
        Array.prototype.forEach.call(tb.rows,function(r){ if(r.classList.contains('mb-sub')){ if(cur)cur.sub=r; } else { cur={row:r,sub:null}; groups.push(cur); } });
        function key(g){ var c=g.row.cells[idx]; if(!c) return ''; var v=c.getAttribute('data-v'); return (v!==null?v:c.textContent).trim().toLowerCase(); }
        groups.sort(function(a,b){ var x=key(a),y=key(b); var nx=parseFloat(x),ny=parseFloat(y);
            if(!isNaN(nx)&&!isNaN(ny)&&/^[\d.\-]+$/.test(x)&&/^[\d.\-]+$/.test(y)) return asc?nx-ny:ny-nx;
            return asc?x.localeCompare(y):y.localeCompare(x); });
        groups.forEach(function(g){ tb.appendChild(g.row); if(g.sub) tb.appendChild(g.sub); });
    };
})();
</script>
<?php require __DIR__ . '/../includes/footer.php'; ?>
