<?php
/**
 * AR / Collections — AUDIT (ar.audit). The auditor scores each SAMPLED worked visit against the 5 AR audit
 * parameters (pass/fail; no code correction). A finalized audit locks the visit until the AR user raises a
 * rebuttal; the auditor then accepts/rejects the disputed parameters and the quality % recomputes.
 * Queues: To audit (in-sample, unaudited) · Audited · Rebuttals (worker disputes).
 */
require_once __DIR__ . '/../includes/config.php';
$user = require_login('internal');
$pdo  = db();
$uid  = (int) $user['id'];

/* ───────────────────────── POST ───────────────────────── */
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    csrf_check_or_die();
    if (!can('ar.audit')) { http_response_code(403); exit('Forbidden'); }
    $act = (string) ($_POST['action'] ?? '');

    if ($act === 'save_audit') {
        $vwid = (int) input('visit_work_id');
        $src  = in_array((string) input('src'), ['toaudit', 'allworked'], true) ? (string) input('src') : 'toaudit';
        // any WORKED visit is auditable — the sample only decides the default "To audit" queue; auditors may also pull
        // an off-sample worked visit from the "All worked" tab (quality is scored over audited rows, not in_sample).
        $vw = $pdo->prepare("SELECT * FROM ar_visit_work WHERE id=? AND inventory_status='worked'"); $vw->execute([$vwid]); $vw = $vw->fetch();
        if (!$vw) { flash('error', 'That visit has not been worked yet, so it cannot be audited.'); redirect('/admin/ar-audit.php'); }
        // a finalized audit is READ-ONLY — the auditor can only act again via the rebuttal-resolve flow (raised by the AR user)
        $exists = $pdo->prepare("SELECT 1 FROM ar_visit_audit WHERE visit_work_id=?"); $exists->execute([$vwid]);
        if ($exists->fetchColumn()) { flash('error', 'This visit is already audited and is read-only. You can only act once the AR user raises a rebuttal.'); redirect('/admin/ar-audit.php?visit=' . $vwid . '&src=' . $src); }
        $params = []; $missingReason = false;
        foreach (AR_AUDIT_PARAMS as $k => $_) {
            $isFail = (($_POST['p'][$k] ?? 'pass') === 'fail');
            $note   = trim((string) ($_POST['note'][$k] ?? ''));
            if ($isFail && $note === '') $missingReason = true;             // a failed parameter MUST carry a reason
            $params[$k] = ['result' => $isFail ? 'fail' : 'pass', 'note' => $note];
        }
        if ($missingReason) { flash('error', 'Add a reason for every parameter you marked Fail.'); redirect('/admin/ar-audit.php?visit=' . $vwid . '&src=' . $src); }
        if (!ar_save_audit($pdo, $vwid, $uid, $params, trim((string) input('comment')))) {
            flash('error', 'Cannot score — the worker has an open rebuttal on this visit. Resolve it first.');
            redirect('/admin/ar-audit.php?visit=' . $vwid . '&src=' . $src);
        }
        flash('success', 'Audit saved.');
        // two ways to leave: "Finalize & back to queue" exits now; "Finalize & next visit" (default) auto-advances
        // within the SAME queue the auditor is working (sampled-only vs all-worked).
        if ((string) input('after') === 'queue') redirect('/admin/ar-audit.php?q=' . $src);
        $sampleGate = $src === 'allworked' ? '' : ' AND v.in_sample=1';   // $src whitelisted above — safe to inline
        $advOrder   = $src === 'allworked' ? 'DESC' : 'ASC';               // mirror the list order (all-worked = newest-first)
        $nx = $pdo->query("SELECT v.id FROM ar_visit_work v WHERE v.inventory_status='worked'$sampleGate
            AND NOT EXISTS (SELECT 1 FROM ar_visit_audit a WHERE a.visit_work_id=v.id) ORDER BY v.worked_at $advOrder, v.id $advOrder LIMIT 1")->fetchColumn();
        if ($nx) { flash('info', 'Loaded the next visit to audit.'); redirect('/admin/ar-audit.php?visit=' . (int) $nx . '&src=' . $src); }
        flash('info', 'No more visits to audit in this queue. 🎉');
        redirect('/admin/ar-audit.php?q=' . $src);
    }

    if ($act === 'rebuttal_resolve') {
        $aid = (int) input('audit_id');
        $a = $pdo->prepare("SELECT * FROM ar_visit_audit WHERE id=?"); $a->execute([$aid]); $a = $a->fetch();
        if ($a && $a['rebuttal_status'] === 'raised') {
            $decisions = (array) ($_POST['rb'] ?? []);
            $pdo->beginTransaction();
            $acc = $pdo->prepare("UPDATE ar_audit_param SET result='pass', rebuttal_result='accepted' WHERE audit_id=? AND param_key=? AND disputed=1");
            $rej = $pdo->prepare("UPDATE ar_audit_param SET rebuttal_result='rejected' WHERE audit_id=? AND param_key=? AND disputed=1");
            foreach ($decisions as $pk => $d) { ((string) $d === 'accept') ? $acc->execute([$aid, $pk]) : $rej->execute([$aid, $pk]); }
            $pdo->prepare("UPDATE ar_audit_param SET rebuttal_result='rejected' WHERE audit_id=? AND disputed=1 AND COALESCE(rebuttal_result,'pending')='pending'")->execute([$aid]);
            ar_recompute_audit($pdo, $aid);
            $cn = $pdo->prepare("SELECT COALESCE(SUM(rebuttal_result='accepted'),0) a, COALESCE(SUM(rebuttal_result='rejected'),0) r FROM ar_audit_param WHERE audit_id=? AND disputed=1");
            $cn->execute([$aid]); $cn = $cn->fetch();
            $decision = (int) $cn['a'] > 0 ? 'accepted' : 'rejected';
            $pdo->prepare("UPDATE ar_visit_audit SET rebuttal_status=?, rebuttal_resolved_at=NOW(),
                            comment=CONCAT(COALESCE(comment,''), ?) WHERE id=?")
                ->execute([$decision, "\n[rebuttal resolved · {$cn['a']} accepted / {$cn['r']} kept] " . trim((string) input('resolve_note')), $aid]);
            $pdo->commit();
            flash('success', "Rebuttal resolved — {$cn['a']} accepted, {$cn['r']} kept. Quality recomputed.");
            $nx = $pdo->query("SELECT id FROM ar_visit_audit WHERE rebuttal_status='raised' ORDER BY rebuttal_at ASC LIMIT 1")->fetchColumn();
            redirect($nx ? ('/admin/ar-audit.php?audit=' . (int) $nx) : '/admin/ar-audit.php?q=rebuttals');
        }
        redirect('/admin/ar-audit.php?q=rebuttals');
    }
    redirect('/admin/ar-audit.php');
}

/* ───────────────────────── DETAIL: audit one visit ───────────────────────── */
$visitId = (int) ($_GET['visit'] ?? 0);
$auditId = (int) ($_GET['audit'] ?? 0);
$src     = in_array($_GET['src'] ?? '', ['toaudit', 'allworked'], true) ? (string) $_GET['src'] : 'toaudit';   // which queue the auditor came from
if ($visitId || $auditId) {
    if ($auditId) {
        $a = $pdo->prepare("SELECT * FROM ar_visit_audit WHERE id=?"); $a->execute([$auditId]); $a = $a->fetch();
        $visitId = $a ? (int) $a['visit_work_id'] : 0;
    }
    // resolve the WORKER (worked_by), not the current owner — a visit pulled back from a follow-up hold is still
    // worked + auditable but has allocated_user NULL, and this is the screen the audit is actually scored on.
    $vw = $pdo->prepare("SELECT v.*, u.name worker_name FROM ar_visit_work v LEFT JOIN users u ON u.id=COALESCE(v.worked_by, v.allocated_user) WHERE v.id=?");
    $vw->execute([$visitId]); $vw = $vw->fetch();
    if (!$vw) { flash('error', 'Visit not found.'); redirect('/admin/ar-audit.php'); }
    $demo  = ar_account_demographics($pdo, (int) $vw['process_id'], $vw['chart_number']);
    $audit = $pdo->prepare("SELECT * FROM ar_visit_audit WHERE visit_work_id=?"); $audit->execute([$visitId]); $audit = $audit->fetch() ?: null;
    $paramRows = [];
    if ($audit) { $pr = $pdo->prepare("SELECT * FROM ar_audit_param WHERE audit_id=?"); $pr->execute([(int) $audit['id']]);
        foreach ($pr->fetchAll() as $r) $paramRows[$r['param_key']] = $r; }
    $isRebuttal = $audit && $audit['rebuttal_status'] === 'raised';
    // the SAME rich claim detail + work history the worker saw — so the auditor scores against real data
    $detail  = ar_visit_detail($pdo, (int) $vw['process_id'], $vw['chart_number'], (string) $vw['visit_id']);
    $history = ar_visit_work_history($pdo, (int) $vw['process_id'], $vw['chart_number'], (string) $vw['visit_id']);

    $pageTitle = 'AR audit';
    require __DIR__ . '/../includes/header.php';
    ?>
    <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-clipboard-check me-2 text-primary"></i>Audit visit</h2>
            <div class="text-secondary small">Patient Account <span class="font-mono"><?= e($vw['chart_number']) ?></span> · Visit <span class="font-mono"><?= e($vw['visit_id']) ?></span> · worker <strong><?= e($vw['worker_name'] ?? '—') ?></strong></div></div>
        <div class="col-auto"><a href="<?= e(url('/admin/ar-audit.php?q=' . $src)) ?>" class="btn btn-outline-secondary"><i class="ti ti-arrow-left me-1"></i>Queue</a></div>
    </div></div></div>
    <style>
    /* ultra-compact audit layout */
    .ar-audit-compact .card{ margin-bottom:.6rem !important; }
    .ar-audit-compact .card-body{ padding:.55rem .75rem; }
    .ar-audit-compact .card-header{ padding:.3rem .75rem; min-height:0; }
    .ar-audit-compact .table-sm td, .ar-audit-compact .table-sm th{ padding:.2rem .4rem; }
    .ar-audit-compact .gap-4{ gap:.9rem !important; }
    .ar-audit-compact .row.g-2{ --bs-gutter-y:.15rem; }
    .ar-audit-compact h2.page-title{ font-size:1.1rem; }
    .ar-audit-compact .alert{ margin-bottom:.5rem; }
    </style>
    <div class="page-body ar-audit-compact"><div class="container-xl">
        <!-- claim context + what the worker recorded -->
        <div class="card mb-2"><div class="card-body d-flex flex-wrap gap-4">
            <div><div class="text-secondary small">Patient</div><?= e(trim(($demo['first_name'] ?? '') . ' ' . ($demo['last_name'] ?? '')) ?: '—') ?></div>
            <div><div class="text-secondary small">DOS</div><?= e(fmt_date($detail['dos'] ?? $vw['dos'])) ?></div>
            <div><div class="text-secondary small">Provider</div><?= e($detail['provider'] ?? '—') ?></div>
            <div><div class="text-secondary small">Primary carrier</div><?= e($detail['carrier1'] ?? $vw['carrier_name'] ?? '—') ?></div>
            <?php if (!empty($detail['carrier2'])): ?><div><div class="text-secondary small">Secondary</div><?= e($detail['carrier2']) ?></div><?php endif; ?>
            <?php if (!empty($detail['carrier3'])): ?><div><div class="text-secondary small">Tertiary</div><?= e($detail['carrier3']) ?></div><?php endif; ?>
            <div class="ms-auto text-end"><div class="text-secondary small">Ins. balance</div><strong><?= number_format((float)$detail['ins_bal'], 2) ?></strong> <span class="text-secondary small">· Pat. <?= number_format((float)$detail['pat_bal'], 2) ?></span></div>
        </div>
        <div class="card-body border-top py-2 d-flex flex-wrap gap-4 bg-muted-lt">
            <div><div class="text-secondary small">Worker</div><strong><?= e($vw['worker_name'] ?? '—') ?></strong></div>
            <div><div class="text-secondary small">Claim status</div><?= e($vw['claim_status'] ?? '—') ?></div>
            <div><div class="text-secondary small">Action taken</div><?= e($vw['action_taken'] ?? '—') ?></div>
            <div><div class="text-secondary small">Follow-up</div><?= e(fmt_date($vw['next_follow_up_date'])) ?></div>
            <div style="max-width:320px"><div class="text-secondary small">Worker notes</div><?= e($vw['notes'] ?? '') ?: '<span class="text-secondary">—</span>' ?></div>
        </div></div>

        <div class="row">
            <div class="col-lg-7"><!-- CPT charges -->
                <div class="card mb-3"><div class="card-header py-2"><h3 class="card-title small"><i class="ti ti-receipt me-1"></i>CPT charges</h3></div>
                    <div class="table-responsive"><table class="table table-vcenter card-table table-sm">
                        <thead><tr><th>CPT</th><th class="text-end">Units</th><th class="text-end">Charge</th><th class="text-end">Pri</th><th class="text-end">Sec</th><th class="text-end">Ter</th><th class="text-end">W/O</th><th class="text-end">Ins. paid</th><th class="text-end">Ins. bal</th></tr></thead>
                        <tbody>
                        <?php if (!$detail['lines']): ?><tr><td colspan="9" class="text-center text-secondary py-3">No charge lines in the current inventory.</td></tr>
                        <?php else: foreach ($detail['lines'] as $l): $ip=(float)($l['primary_ins_paid']??0)+(float)($l['secondary_ins_paid']??0)+(float)($l['tertiary_ins_paid']??0); ?>
                            <tr><td class="font-mono"><?= e($l['charge_code'] ?? '—') ?><?php if (!empty($l['charge_code_desc'])): ?> <i class="ti ti-info-circle text-secondary" title="<?= e($l['charge_code_desc']) ?>"></i><?php endif; ?></td>
                                <td class="text-end small"><?= e(rtrim(rtrim(number_format((float)($l['units']??0),2),'0'),'.')) ?: '—' ?></td>
                                <td class="text-end font-mono"><?= number_format((float)($l['charge_amount']??0),2) ?></td>
                                <td class="text-end font-mono small"><?= number_format((float)($l['primary_ins_paid']??0),2) ?></td>
                                <td class="text-end font-mono small"><?= number_format((float)($l['secondary_ins_paid']??0),2) ?></td>
                                <td class="text-end font-mono small"><?= number_format((float)($l['tertiary_ins_paid']??0),2) ?></td>
                                <td class="text-end font-mono small"><?= number_format((float)($l['wo_amount']??0),2) ?></td>
                                <td class="text-end font-mono"><?= number_format($ip,2) ?></td>
                                <td class="text-end font-mono fw-medium"><?= number_format((float)($l['insurance_balance']??0),2) ?></td></tr>
                        <?php endforeach; endif; ?>
                        </tbody>
                        <?php if ($detail['lines']): ?><tfoot><tr class="fw-bold"><td colspan="2">Total</td>
                            <td class="text-end font-mono"><?= number_format((float)$detail['charges'],2) ?></td>
                            <td class="text-end font-mono small"><?= number_format((float)$detail['ppaid'],2) ?></td>
                            <td class="text-end font-mono small"><?= number_format((float)$detail['spaid'],2) ?></td>
                            <td class="text-end font-mono small"><?= number_format((float)$detail['tpaid'],2) ?></td>
                            <td class="text-end font-mono small"><?= number_format((float)$detail['wo'],2) ?></td>
                            <td class="text-end font-mono"><?= number_format((float)$detail['paid'],2) ?></td>
                            <td class="text-end font-mono"><?= number_format((float)$detail['ins_bal'],2) ?></td></tr></tfoot><?php endif; ?>
                    </table></div>
                </div>
            </div>
            <div class="col-lg-5"><!-- worked history -->
                <div class="card mb-3"><div class="card-header py-2"><h3 class="card-title small"><i class="ti ti-history me-1"></i>Worked history</h3><div class="card-actions"><span class="badge bg-secondary-lt"><?= count($history) ?></span></div></div>
                    <div class="table-responsive" style="max-height:260px"><table class="table table-vcenter card-table table-sm">
                        <thead><tr><th>When</th><th>By</th><th>Claim status</th><th>Action</th><th>Notes</th></tr></thead>
                        <tbody>
                        <?php if (!$history): ?><tr><td colspan="5" class="text-center text-secondary py-3">No prior work logged.</td></tr>
                        <?php else: foreach ($history as $h): ?>
                            <tr><td class="small text-nowrap"><?= e(fmt_date($h['created_at'])) ?></td>
                                <td class="small"><?= e($h['worker_name'] ?? '—') ?></td>
                                <td class="small"><?= e($h['claim_status'] ?? '—') ?></td>
                                <td class="small"><?= e($h['action_taken'] ?? '—') ?></td>
                                <td class="small text-secondary"><?= e($h['notes'] ?? '') ?: '—' ?></td></tr>
                        <?php endforeach; endif; ?>
                        </tbody>
                    </table></div>
                </div>
            </div>
        </div>

        <?php if ($isRebuttal): ?>
        <!-- rebuttal resolve -->
        <div class="card mb-3 border-warning">
            <div class="card-header py-2"><h3 class="card-title small"><i class="ti ti-message-report me-1 text-warning"></i>Worker rebuttal — resolve each disputed parameter</h3></div>
            <div class="card-body">
                <?php if (trim((string)($audit['rebuttal_comment'] ?? '')) !== ''): ?><div class="cw-codernote mb-2 small"><strong>Worker:</strong> <?= nl2br(e($audit['rebuttal_comment'])) ?></div><?php endif; ?>
                <form method="POST" action="<?= e(url('/admin/ar-audit.php')) ?>">
                    <?= csrf_field() ?><input type="hidden" name="action" value="rebuttal_resolve"><input type="hidden" name="audit_id" value="<?= (int)$audit['id'] ?>">
                    <?php foreach (AR_AUDIT_PARAMS as $k => $lbl): $p = $paramRows[$k] ?? null; if (!$p || (int)$p['disputed'] !== 1) continue; ?>
                        <div class="border rounded p-2 mb-2">
                            <div><strong><?= e($lbl) ?></strong> <span class="badge bg-red-lt">failed</span>
                                <?php if ($p['note']): ?><span class="text-secondary small">· <?= e($p['note']) ?></span><?php endif; ?></div>
                            <?php if ($p['dispute_reason']): ?><div class="text-secondary small mt-1"><i class="ti ti-message-report text-warning me-1"></i><?= e($p['dispute_reason']) ?></div><?php endif; ?>
                            <div class="btn-group btn-group-sm w-100 mt-1" role="group">
                                <input type="radio" class="btn-check" name="rb[<?= e($k) ?>]" value="reject" id="rb_r<?= e($k) ?>" checked>
                                <label class="btn btn-outline-danger" for="rb_r<?= e($k) ?>">Keep fail</label>
                                <input type="radio" class="btn-check" name="rb[<?= e($k) ?>]" value="accept" id="rb_a<?= e($k) ?>">
                                <label class="btn btn-outline-success" for="rb_a<?= e($k) ?>">Accept (pass)</label>
                            </div>
                        </div>
                    <?php endforeach; ?>
                    <label class="form-label">Resolution note</label>
                    <textarea name="resolve_note" class="form-control mb-2" rows="2" placeholder="Optional"></textarea>
                    <button class="btn btn-primary"><i class="ti ti-gavel me-1"></i>Resolve rebuttal</button>
                </form>
            </div>
        </div>
        <?php endif; ?>

        <!-- audit scoring -->
        <div class="card">
            <div class="card-header py-2"><h3 class="card-title small"><i class="ti ti-list-check me-1"></i>Audit parameters (5)</h3>
                <?php if ($audit): ?><div class="card-actions"><span class="badge bg-<?= $audit['result']==='pass'?'green':'red' ?>-lt"><?= (int)$audit['opportunities'] - (int)$audit['defects'] ?>/<?= (int)$audit['opportunities'] ?> · <?= $audit['result']==='pass'?'pass':'error' ?></span></div><?php endif; ?></div>
            <div class="card-body py-2">
                <?php if ($audit): /* finalized → READ-ONLY; the auditor may only act via the rebuttal-resolve flow above */ ?>
                    <div class="alert alert-azure py-1 px-2 small mb-2"><i class="ti ti-lock me-1"></i>Audit finalized — <strong>read-only</strong>. Changes are possible only after the AR user raises a rebuttal.</div>
                    <?php foreach (AR_AUDIT_PARAMS as $k => $lbl): $p = $paramRows[$k] ?? null; $fail = $p && $p['result']==='fail'; ?>
                        <div class="row g-2 align-items-center border-bottom py-1">
                            <div class="col-md-5 small"><strong><?= e($lbl) ?></strong></div>
                            <div class="col-md-2"><span class="badge bg-<?= $fail?'red':'green' ?>-lt"><?= $fail?'Fail':'Pass' ?></span></div>
                            <div class="col-md-5 small text-secondary"><?= e($p['note'] ?? '') ?></div>
                        </div>
                    <?php endforeach; ?>
                    <?php if (trim((string)($audit['comment'] ?? '')) !== ''): ?><div class="small text-secondary mt-2"><strong>Auditor comment:</strong> <?= nl2br(e($audit['comment'])) ?></div><?php endif; ?>
                <?php else: /* editable scoring — finalize is FINAL (read-only afterwards) */ ?>
                <form method="POST" action="<?= e(url('/admin/ar-audit.php')) ?>" id="ar_audit_form">
                    <?= csrf_field() ?><input type="hidden" name="action" value="save_audit"><input type="hidden" name="visit_work_id" value="<?= (int)$vw['id'] ?>"><input type="hidden" name="src" value="<?= e($src) ?>">
                    <?php foreach (AR_AUDIT_PARAMS as $k => $lbl): ?>
                        <div class="row g-2 align-items-center border-bottom py-1 ar-param">
                            <div class="col-md-4 small"><strong><?= e($lbl) ?></strong></div>
                            <div class="col-md-3"><div class="btn-group btn-group-sm w-100" role="group">
                                <input type="radio" class="btn-check ar-pf" name="p[<?= e($k) ?>]" value="pass" id="p_p<?= e($k) ?>" checked>
                                <label class="btn btn-outline-success" for="p_p<?= e($k) ?>">Pass</label>
                                <input type="radio" class="btn-check ar-pf" name="p[<?= e($k) ?>]" value="fail" id="p_f<?= e($k) ?>">
                                <label class="btn btn-outline-danger" for="p_f<?= e($k) ?>">Fail</label>
                            </div></div>
                            <div class="col-md-5"><input type="text" name="note[<?= e($k) ?>]" class="form-control form-control-sm ar-note" placeholder="note (optional)"></div>
                        </div>
                    <?php endforeach; ?>
                    <label class="form-label mt-2 mb-1 small">Auditor comment</label>
                    <textarea name="comment" class="form-control form-control-sm mb-2" rows="2"></textarea>
                    <div class="d-flex flex-wrap gap-2">
                        <button class="btn btn-sm btn-primary" name="after" value="next"><i class="ti ti-player-track-next me-1"></i>Finalize &amp; next visit</button>
                        <button class="btn btn-sm btn-outline-secondary" name="after" value="queue"><i class="ti ti-logout me-1"></i>Finalize &amp; back to queue</button>
                    </div>
                    <div class="text-secondary small mt-1">A failed parameter is a defect &amp; <strong>needs a reason</strong>; the AR user has <?= AR_REBUTTAL_TAT_DAYS ?> days to dispute. Finalizing is <strong>final</strong> — the audit becomes read-only.</div>
                    <script>
                    (function(){
                        var form=document.getElementById('ar_audit_form');
                        function sync(){ form.querySelectorAll('.ar-param').forEach(function(row){
                            var fail=row.querySelector('.ar-pf[value="fail"]').checked, note=row.querySelector('.ar-note');
                            note.required=fail; note.placeholder=fail?'reason (required)':'note (optional)';
                            note.classList.toggle('is-invalid', fail && !note.value.trim());
                        }); }
                        form.querySelectorAll('.ar-pf, .ar-note').forEach(function(el){ el.addEventListener('change',sync); el.addEventListener('input',sync); });
                        form.addEventListener('submit',function(e){ var bad=false;
                            form.querySelectorAll('.ar-param').forEach(function(row){ if(row.querySelector('.ar-pf[value="fail"]').checked && !row.querySelector('.ar-note').value.trim()) bad=true; });
                            if(bad){ e.preventDefault(); sync(); alert('Please add a reason for every parameter marked Fail.'); } });
                        sync();
                    })();
                    </script>
                </form>
                <?php endif; ?>
            </div>
        </div>
    </div></div>
    <?php require __DIR__ . '/../includes/footer.php'; exit;
}

/* ───────────────────────── LIST: queues ───────────────────────── */
$q = in_array($_GET['q'] ?? '', ['toaudit', 'allworked', 'audited', 'rebuttals'], true) ? $_GET['q'] : 'toaudit';
$cnt = [
    'toaudit'   => (int) $pdo->query("SELECT COUNT(*) FROM ar_visit_work v WHERE v.inventory_status='worked' AND v.in_sample=1 AND NOT EXISTS (SELECT 1 FROM ar_visit_audit a WHERE a.visit_work_id=v.id)")->fetchColumn(),
    'allworked' => (int) $pdo->query("SELECT COUNT(*) FROM ar_visit_work v WHERE v.inventory_status='worked' AND NOT EXISTS (SELECT 1 FROM ar_visit_audit a WHERE a.visit_work_id=v.id)")->fetchColumn(),
    'audited'   => (int) $pdo->query("SELECT COUNT(*) FROM ar_visit_audit")->fetchColumn(),
    'rebuttals' => (int) $pdo->query("SELECT COUNT(*) FROM ar_visit_audit WHERE rebuttal_status='raised'")->fetchColumn(),
];
/* pagination — a queue can exceed one page; page server-side so EVERY record is reachable (the client-side column
   filters only see the CURRENT page — use the server-side Worker/Worked-date filters to narrow across pages). */
$per = 500; $page = max(1, (int) ($_GET['p'] ?? 1));
/* worked-queue server-side filters (must run BEFORE the LIMIT/OFFSET, else a low-sampled worker's OLDER accounts —
   the whole point of "All worked" — get truncated and can't be reached by the client-side column filters). */
$workerOpts = []; $fWorker = 0; $fWFrom = ''; $fWTo = '';
if ($q === 'toaudit' || $q === 'allworked') {
    // join on the WORKER (worked_by snapshot) falling back to the current owner — a visit pulled back from a
    // follow-up hold has allocated_user NULL but is still worked + auditable, and an INNER JOIN on the owner
    // would drop it from this dropdown while leaving it in the queue count (the KPI/list join-drift bug class).
    $workerOpts = $pdo->query("SELECT DISTINCT u.id, u.name FROM ar_visit_work v JOIN users u ON u.id=COALESCE(v.worked_by, v.allocated_user)
        WHERE v.inventory_status='worked' AND NOT EXISTS (SELECT 1 FROM ar_visit_audit a WHERE a.visit_work_id=v.id)
        ORDER BY u.name")->fetchAll();
    $fWorker = (int) ($_GET['w'] ?? 0);
    $dOk     = fn($v) => is_string($v) && preg_match('/^\d{4}-\d{2}-\d{2}$/', $v) ? $v : '';
    $fWFrom  = $dOk($_GET['wf'] ?? '');
    $fWTo    = $dOk($_GET['wt'] ?? '');
}
if ($q === 'toaudit' || $q === 'allworked') {
    // "To audit" = the sampled subset (respect each worker's Sample %); "All worked" = every worked, un-audited visit
    // so an auditor can pull an off-sample account (e.g. a worker whose sample drew low) on demand.
    $sampleGate = $q === 'toaudit' ? ' AND v.in_sample=1' : '';                 // $q whitelisted above — safe to inline
    $order      = $q === 'toaudit' ? 'v.worked_at ASC, v.id ASC' : 'v.worked_at DESC, v.id DESC';   // v.id tiebreaker = stable paging (worked_at ties on bulk work)
    $fsql = ''; $fp = [];
    if ($fWorker) { $fsql .= ' AND COALESCE(v.worked_by, v.allocated_user)=?'; $fp[] = $fWorker; }   // match the dropdown (worker, not current owner)
    if ($fWFrom)  { $fsql .= ' AND DATE(v.worked_at)>=?'; $fp[] = $fWFrom; }
    if ($fWTo)    { $fsql .= ' AND DATE(v.worked_at)<=?'; $fp[] = $fWTo; }
    $where = "v.inventory_status='worked'$sampleGate$fsql AND NOT EXISTS (SELECT 1 FROM ar_visit_audit a WHERE a.visit_work_id=v.id)";
    $tc = $pdo->prepare("SELECT COUNT(*) FROM ar_visit_work v WHERE $where"); $tc->execute($fp); $total = (int) $tc->fetchColumn();
    $pages = max(1, (int) ceil($total / $per)); if ($page > $pages) $page = $pages; $off = ($page - 1) * $per;   // ints — safe to inline
    $lst = $pdo->prepare("SELECT v.id, v.chart_number, v.visit_id, v.carrier_name, v.dos, v.claim_status, v.action_taken,
            v.insurance_balance, v.next_follow_up_date, v.worked_at, u.name worker_name
        FROM ar_visit_work v LEFT JOIN users u ON u.id=COALESCE(v.worked_by, v.allocated_user)
        WHERE $where ORDER BY $order LIMIT $per OFFSET $off");
    $lst->execute($fp);
    $rows = $lst->fetchAll();
} else {
    $total = $q === 'rebuttals' ? (int) $cnt['rebuttals'] : (int) $cnt['audited'];
    $pages = max(1, (int) ceil($total / $per)); if ($page > $pages) $page = $pages; $off = ($page - 1) * $per;   // ints — safe to inline
    $w = $q === 'rebuttals' ? "a.rebuttal_status='raised'" : '1=1';
    // join ar_visit_work for the visit's live fields (carrier/DOS/claim/action/balance) — ar_visit_audit alone lacks them
    $rows = $pdo->query("SELECT a.id audit_id, a.visit_work_id, a.chart_number, a.visit_id, a.result, a.opportunities, a.defects,
            a.rebuttal_status, a.audited_at, a.comment,
            vw.carrier_name, vw.dos, vw.claim_status, vw.action_taken, vw.insurance_balance,
            u.name worker_name, au.name auditor_name
        FROM ar_visit_audit a
        LEFT JOIN ar_visit_work vw ON vw.id=a.visit_work_id
        LEFT JOIN users u  ON u.id=a.worker_id
        LEFT JOIN users au ON au.id=a.auditor_id
        WHERE $w ORDER BY a.audited_at DESC, a.id DESC LIMIT $per OFFSET $off")->fetchAll();
}

$pageTitle = 'AR audit';
require __DIR__ . '/../includes/header.php';
?>
<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-clipboard-check me-2 text-primary"></i>AR audit</h2>
        <div class="text-secondary small">Score each sampled worked visit against the 5 AR parameters. A finalized audit locks the visit until the worker disputes.</div></div>
</div></div></div>
<div class="page-body"><div class="container-xl">
    <ul class="nav nav-tabs mb-3">
        <?php foreach (['toaudit'=>'To audit', 'allworked'=>'All worked', 'audited'=>'Audited', 'rebuttals'=>'Rebuttals'] as $k => $lbl): ?>
            <li class="nav-item"><a class="nav-link <?= $q===$k?'active':'' ?>" href="<?= e(url('/admin/ar-audit.php?q=' . $k)) ?>"><?= e($lbl) ?>
                <?php if ($cnt[$k]): ?><span class="badge bg-<?= $k==='rebuttals'?'yellow':($k==='allworked'?'blue':'secondary') ?> ms-1"><?= $cnt[$k] ?></span><?php endif; ?></a></li>
        <?php endforeach; ?>
    </ul>
    <?php $audView = !in_array($q, ['toaudit', 'allworked'], true); $reb = ['none'=>'secondary','agreed'=>'green','raised'=>'yellow','accepted'=>'green','rejected'=>'red'];
        $dv = fn($d) => preg_replace('/\D/', '', substr((string) $d, 0, 19));   // digit-only sort key so dates/times sort chronologically
        $sortTh = fn(int $col, string $lbl, string $cls = '') => '<th class="aa-sort ' . $cls . '" data-col="' . $col . '" onclick="aaSort(this)" style="cursor:pointer" title="Sort">' . $lbl . ' <span class="aa-arrow text-secondary"></span></th>';
        $filtTh = fn(int $col) => '<th class="p-1"><input class="form-control form-control-sm aa-filter" data-col="' . $col . '" placeholder="Filter…" aria-label="Filter column"></th>';
    ?>
    <?php if (!$audView): $fActive = ($fWorker || $fWFrom !== '' || $fWTo !== ''); ?>
    <!-- server-side filters run BEFORE the 500 cap, so a specific worker's older accounts are reachable even past 500 rows -->
    <form method="GET" class="card mb-2"><div class="card-body py-2">
        <input type="hidden" name="q" value="<?= e($q) ?>">
        <div class="row g-2 align-items-end">
            <div class="col-auto"><label class="form-label small mb-1">Worker</label>
                <select name="w" class="form-select form-select-sm" style="min-width:180px">
                    <option value="0">All workers</option>
                    <?php foreach ($workerOpts as $wo): ?>
                        <option value="<?= (int)$wo['id'] ?>" <?= $fWorker===(int)$wo['id']?'selected':'' ?>><?= e($wo['name']) ?></option>
                    <?php endforeach; ?>
                </select></div>
            <div class="col-auto"><label class="form-label small mb-1">Worked from</label>
                <input type="date" name="wf" value="<?= e($fWFrom) ?>" class="form-control form-control-sm"></div>
            <div class="col-auto"><label class="form-label small mb-1">Worked to</label>
                <input type="date" name="wt" value="<?= e($fWTo) ?>" class="form-control form-control-sm"></div>
            <div class="col-auto"><button class="btn btn-sm btn-primary"><i class="ti ti-filter me-1"></i>Find</button></div>
            <?php if ($fActive): ?><div class="col-auto"><a href="<?= e(url('/admin/ar-audit.php?q=' . $q)) ?>" class="btn btn-sm btn-link text-secondary">Clear</a></div><?php endif; ?>
        </div>
    </div></form>
    <?php endif; ?>
    <?php if ($q === 'allworked'): ?>
    <div class="alert alert-azure py-2 px-3 small mb-2"><i class="ti ti-info-circle me-1"></i><strong>All worked</strong> lists every worked, un-audited visit — including accounts that fell outside the random audit sample. Audit any of them here; the score counts toward that worker's quality exactly like a sampled audit. Pick a <strong>Worker</strong> (or a <strong>Worked</strong> date range) above to find a specific person's accounts — that filter runs on the server, so it reaches accounts beyond the first 500 too.</div>
    <?php endif; ?>
    <?php $rowFrom = $total ? ($off + 1) : 0; $rowTo = $off + count($rows); ?>
    <div class="text-secondary small mb-2"><i class="ti ti-filter me-1"></i>Click a header to sort; type under a header to filter <em>this page</em>. Rows <strong><?= number_format($rowFrom) ?>–<?= number_format($rowTo) ?></strong> of <strong><?= number_format($total) ?></strong><?= $pages > 1 ? ' · page ' . $page . '/' . $pages : '' ?> · <span id="aaCount"><?= count($rows) ?></span> shown.</div>
    <div class="card"><div class="table-responsive"><table class="table table-vcenter card-table table-sm" id="aaTable">
        <thead>
        <tr>
            <?= $sortTh(0, 'Patient Account #') ?><?= $sortTh(1, 'Visit ID') ?><?= $sortTh(2, 'Worker') ?><?= $sortTh(3, 'Carrier') ?><?= $sortTh(4, 'DOS') ?>
            <?php if ($audView): ?><?= $sortTh(5, 'Claim status') ?><?= $sortTh(6, 'Action taken') ?><?= $sortTh(7, 'Ins. bal', 'text-end') ?><?= $sortTh(8, 'Auditor') ?><?= $sortTh(9, 'Audited') ?><?= $sortTh(10, 'Score', 'text-end') ?><?= $sortTh(11, 'Rebuttal') ?>
            <?php else: ?><?= $sortTh(5, 'Worked') ?><?= $sortTh(6, 'Claim status') ?><?= $sortTh(7, 'Action taken') ?><?= $sortTh(8, 'Ins. bal', 'text-end') ?><?php endif; ?>
            <th class="w-1"></th>
        </tr>
        <tr class="aa-filterrow">
            <?= $filtTh(0) ?><?= $filtTh(1) ?><?= $filtTh(2) ?><?= $filtTh(3) ?><?= $filtTh(4) ?>
            <?php if ($audView): ?><?= $filtTh(5) ?><?= $filtTh(6) ?><th></th><?= $filtTh(8) ?><th></th><th></th><?= $filtTh(11) ?>
            <?php else: ?><?= $filtTh(5) ?><?= $filtTh(6) ?><?= $filtTh(7) ?><th></th><?php endif; ?>
            <th></th>
        </tr>
        </thead>
        <tbody>
        <?php $cols = $audView ? 13 : 10; if (!$rows): ?><tr class="aa-empty"><td colspan="<?= $cols ?>" class="text-center text-secondary py-4">Nothing here. 🎉</td></tr>
        <?php else: foreach ($rows as $r): ?>
            <tr>
                <td class="font-mono"><?= e($r['chart_number']) ?></td>
                <td class="font-mono small"><?= e($r['visit_id']) ?></td>
                <td class="small"><?= e($r['worker_name'] ?? '—') ?></td>
                <td class="small"><?= e($r['carrier_name'] ?? '—') ?></td>
                <td class="small text-nowrap" data-v="<?= e($dv($r['dos'])) ?>"><?= e(fmt_date($r['dos'])) ?></td>
                <?php if ($audView): $rs = (string)($r['rebuttal_status'] ?? 'none'); ?>
                    <td class="small text-secondary"><?= e($r['claim_status'] ?? '—') ?></td>
                    <td class="small text-secondary"><?= e($r['action_taken'] ?? '—') ?></td>
                    <td class="text-end font-mono small" data-v="<?= $r['insurance_balance'] !== null ? (float)$r['insurance_balance'] : '' ?>"><?= $r['insurance_balance'] !== null ? number_format((float)$r['insurance_balance'], 2) : '—' ?></td>
                    <td class="small"><?= e($r['auditor_name'] ?? '—') ?></td>
                    <td class="small text-nowrap" data-v="<?= e($dv($r['audited_at'])) ?>"><?= e(fmt_date($r['audited_at'])) ?></td>
                    <td class="text-end" data-v="<?= (int)$r['opportunities']-(int)$r['defects'] ?>"><span class="badge bg-<?= ($r['result']??'')==='pass'?'green':'red' ?>-lt"><?= (int)$r['opportunities']-(int)$r['defects'] ?>/<?= (int)$r['opportunities'] ?></span></td>
                    <td><span class="badge bg-<?= $reb[$rs] ?? 'secondary' ?>-lt"><?= e(str_replace('_',' ', $rs)) ?></span></td>
                    <td class="text-end"><a href="<?= e(url('/admin/ar-audit.php?audit=' . (int)$r['audit_id'])) ?>" class="btn btn-sm btn-<?= $rs==='raised'?'warning':'outline-secondary' ?>"><?= $rs==='raised'?'Resolve':'View' ?></a></td>
                <?php else: ?>
                    <td class="small text-nowrap" data-v="<?= e($dv($r['worked_at'])) ?>"><?= e(fmt_dt($r['worked_at'])) ?></td>
                    <td class="small text-secondary"><?= e($r['claim_status'] ?? '—') ?></td>
                    <td class="small text-secondary"><?= e($r['action_taken'] ?? '—') ?></td>
                    <td class="text-end font-mono small" data-v="<?= $r['insurance_balance'] !== null ? (float)$r['insurance_balance'] : '' ?>"><?= $r['insurance_balance'] !== null ? number_format((float)$r['insurance_balance'], 2) : '—' ?></td>
                    <td class="text-end"><a href="<?= e(url('/admin/ar-audit.php?visit=' . (int)$r['id'] . '&src=' . $q)) ?>" class="btn btn-sm btn-primary"><i class="ti ti-clipboard-check me-1"></i>Audit</a></td>
                <?php endif; ?>
            </tr>
        <?php endforeach; endif; ?>
        </tbody>
    </table></div></div>
    <?php if ($pages > 1): $pgUrl = function (int $p) use ($q, $fWorker, $fWFrom, $fWTo) {
            $qs = ['q' => $q];
            if ($fWorker)      $qs['w']  = $fWorker;
            if ($fWFrom !== '') $qs['wf'] = $fWFrom;
            if ($fWTo   !== '') $qs['wt'] = $fWTo;
            $qs['p'] = $p;
            return url('/admin/ar-audit.php?' . http_build_query($qs));
        }; ?>
    <div class="d-flex align-items-center justify-content-between mt-2 flex-wrap gap-2">
        <div class="text-secondary small">Page <?= $page ?> of <?= $pages ?> · <?= number_format($total) ?> total</div>
        <ul class="pagination pagination-sm m-0">
            <li class="page-item <?= $page <= 1 ? 'disabled' : '' ?>"><a class="page-link" href="<?= e($pgUrl(1)) ?>">« First</a></li>
            <li class="page-item <?= $page <= 1 ? 'disabled' : '' ?>"><a class="page-link" href="<?= e($pgUrl(max(1, $page - 1))) ?>">‹ Prev</a></li>
            <li class="page-item disabled"><span class="page-link"><?= $page ?> / <?= $pages ?></span></li>
            <li class="page-item <?= $page >= $pages ? 'disabled' : '' ?>"><a class="page-link" href="<?= e($pgUrl(min($pages, $page + 1))) ?>">Next ›</a></li>
            <li class="page-item <?= $page >= $pages ? 'disabled' : '' ?>"><a class="page-link" href="<?= e($pgUrl($pages)) ?>">Last »</a></li>
        </ul>
    </div>
    <?php endif; ?>
</div></div>
<script>
(function(){
    var table=document.getElementById('aaTable'); if(!table) return;
    var tb=table.tBodies[0];
    function apply(){
        var filters=Array.prototype.map.call(document.querySelectorAll('.aa-filter'),function(inp){return {col:+inp.getAttribute('data-col'),q:(inp.value||'').toLowerCase().trim()};});
        var n=0;
        Array.prototype.forEach.call(tb.rows,function(r){
            if(r.classList.contains('aa-empty')) return;
            var show=true;
            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'; if(show)n++;
        });
        var cc=document.getElementById('aaCount'); if(cc) cc.textContent=n;
    }
    document.querySelectorAll('.aa-filter').forEach(function(inp){ inp.addEventListener('input',apply); inp.addEventListener('click',function(e){e.stopPropagation();}); });
    window.aaSort=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('.aa-arrow'); if(a)a.textContent='';});
        th.setAttribute('data-asc',asc?'1':'0'); var ar=th.querySelector('.aa-arrow'); if(ar)ar.textContent=asc?'▲':'▼';
        var rows=Array.prototype.filter.call(tb.rows,function(r){return !r.classList.contains('aa-empty');});
        function key(r){var c=r.cells[idx]; if(!c) return ''; var v=c.getAttribute('data-v'); return (v!==null?v:c.textContent).trim().toLowerCase();}
        rows.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);});
        rows.forEach(function(r){tb.appendChild(r);});
    };
})();
</script>
<?php require __DIR__ . '/../includes/footer.php'; ?>
