<?php
/**
 * My billing audit errors & rebuttals (billing.work). A biller sees every chart of THEIRS the QA team audited
 * as an ERROR — the error category, DPO defects, the auditor's comment — and can either AGREE the error stands
 * or DISPUTE it (routes to the auditor's Rebuttals queue). Advisory model only, mirroring AR audit: there is no
 * send-back / rework path — the chart stays worked and the finding is settled entirely here.
 *
 * States (mutually exclusive, all fenced to allocated_biller = me):
 *   open   — error, still 'worked', rebuttal none/rejected  → you can agree or dispute (or re-dispute a rejected one)
 *   raised — rebuttal raised, awaiting the auditor
 *   won    — a rebuttal the auditor accepted (the error was reversed to a pass)
 */
require_once __DIR__ . '/../includes/config.php';
$user = require_login('internal');
$pdo  = db();
$uid  = (int) $user['id'];

/* ----------------------------------------------------------- POST: agree, or raise a per-parameter rebuttal */
if ($_SERVER['REQUEST_METHOD'] === 'POST' && in_array($_POST['action'] ?? '', ['rebut','agree'], true)) {
    csrf_check_or_die();
    $invId = (int) ($_POST['inventory_id'] ?? 0);

    if (($_POST['action']) === 'agree') {   // the biller accepts the error as-is (terminal 'agreed', fenced to own flagged error)
        $ag = $pdo->prepare("UPDATE billing_allocation SET rebuttal_status='agreed', rebuttal_resolved_at=NOW()
                WHERE inventory_id=? AND allocated_biller=? AND audit_result='error' AND inventory_status='worked' AND rebuttal_status IN ('none','rejected')");
        $ag->execute([$invId, $uid]);
        flash($ag->rowCount() ? 'success' : 'error', $ag->rowCount() ? 'Marked as agreed — the error stands.' : 'That chart cannot be updated.');
        redirect('/admin/billing-rebuttals.php?q=open');
    }

    $note = trim((string) input('note'));
    if ($note === '') { flash('error', 'Add a reason for your rebuttal.'); redirect('/admin/billing-rebuttals.php'); }
    // collect the parameters the biller ticked to dispute (+ their per-param reason, defaulting to the overall note).
    $disputed = [];
    foreach ((array) ($_POST['disputed'] ?? []) as $pk) {
        $pk = (string) $pk; if (!isset(BILLING_AUDIT_PARAMS[$pk])) continue;
        $disputed[$pk] = trim((string) ($_POST['reason'][$pk] ?? '')) ?: $note;
    }
    $ok = billing_raise_rebuttal($pdo, $invId, $uid, $note, $disputed);   // empty $disputed → dispute all failed params
    flash($ok ? 'success' : 'error', $ok ? 'Rebuttal sent to the auditor.' : 'That chart cannot be rebutted (nothing valid to dispute).');
    redirect('/admin/billing-rebuttals.php?q=' . ($ok ? 'raised' : 'open'));
}

/* ----------------------------------------------------------- state predicates (fenced by allocated_biller in SQL) */
$stateSql = [
    'open'   => "a.audit_result='error' AND a.inventory_status='worked' AND a.rebuttal_status IN ('none','rejected')",
    'raised' => "a.rebuttal_status='raised'",
    'won'    => "a.rebuttal_status='accepted'",
];
$q = isset($_GET['q'], $stateSql[$_GET['q']]) ? (string) $_GET['q'] : 'open';

/* ----------------------------------------------------------- filters */
$fClient   = (int) ($_GET['client_id'] ?? 0);
$fFacility = (int) ($_GET['facility_id'] ?? 0);
$fAuditor  = (int) ($_GET['auditor_id'] ?? 0);
$from = preg_match('/^\d{4}-\d{2}-\d{2}$/', (string) ($_GET['from'] ?? '')) ? $_GET['from'] : '';
$to   = preg_match('/^\d{4}-\d{2}-\d{2}$/', (string) ($_GET['to'] ?? '')) ? $_GET['to'] : '';
$fw = []; $fp = [];
if ($fClient)   { $fw[] = 'ci.client_id=?';   $fp[] = $fClient; }
if ($fFacility) { $fw[] = 'ci.facility_id=?'; $fp[] = $fFacility; }
if ($fAuditor)  { $fw[] = 'a.auditor_id=?';   $fp[] = $fAuditor; }
if ($from)      { $fw[] = 'DATE(a.audited_at) >= ?'; $fp[] = $from; }
if ($to)        { $fw[] = 'DATE(a.audited_at) <= ?'; $fp[] = $to; }
$fwSql = $fw ? (' AND ' . implode(' AND ', $fw)) : '';

/* filter option sources — this biller's audit-error / rebuttal charts ($uid is an int) */
$fScope   = "a.allocated_biller=" . $uid . " AND (a.audit_result='error' OR a.rebuttal_status<>'none')";
$fClients = $pdo->query("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 $fScope ORDER BY c.name")->fetchAll();
$fFacils  = $pdo->query("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 $fScope ORDER BY f.name")->fetchAll();
$fAuds    = $pdo->query("SELECT DISTINCT au.id,au.name FROM billing_allocation a JOIN users au ON au.id=a.auditor_id WHERE $fScope ORDER BY au.name")->fetchAll();

$tabUrl = fn($k) => url('/admin/billing-rebuttals.php?' . http_build_query(array_filter(
    ['q'=>$k, 'client_id'=>$fClient, 'facility_id'=>$fFacility, 'auditor_id'=>$fAuditor, 'from'=>$from, 'to'=>$to],
    fn($v) => $v !== '' && $v !== 0)));

/* ----------------------------------------------------------- tab counts (total, unfiltered — my own charts) */
$cnt = $pdo->prepare("SELECT
        COALESCE(SUM(audit_result='error' AND inventory_status='worked' AND rebuttal_status IN ('none','rejected')),0) open,
        COALESCE(SUM(rebuttal_status='raised'),0) raised,
        COALESCE(SUM(rebuttal_status='accepted'),0) won
    FROM billing_allocation WHERE allocated_biller=?");
$cnt->execute([$uid]); $counts = $cnt->fetch() ?: ['open'=>0,'raised'=>0,'won'=>0];

/* ----------------------------------------------------------- rows for the active tab */
$rows = $pdo->prepare("SELECT a.*, ci.patient_name, ci.patient_mrn, ci.patient_dob, ci.dos,
        c.name cn, f.name fn, bp.name billing_prov, au.name auditor
    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 bp ON bp.id=ci.billing_provider_id
    LEFT JOIN users au ON au.id=a.auditor_id
    WHERE a.allocated_biller=? AND {$stateSql[$q]}$fwSql
    ORDER BY a.audited_at DESC, a.id DESC LIMIT 300");
$rows->execute(array_merge([$uid], $fp));
$rows = $rows->fetchAll();

// Open tab: the auditor's FAILED parameters per chart, so the biller can dispute specific ones with reasons.
$failByAlloc = [];
if ($q === 'open' && $rows) {
    $aids = array_map(fn($r) => (int) $r['id'], $rows); $in = implode(',', array_fill(0, count($aids), '?'));
    $fq = $pdo->prepare("SELECT allocation_id, param_key, note FROM billing_audit_param WHERE result='fail' AND allocation_id IN ($in)");
    $fq->execute($aids);
    foreach ($fq as $f) $failByAlloc[(int) $f['allocation_id']][$f['param_key']] = $f['note'];
}

$qMeta = [
    'open'   => ['To review / rebut', 'yellow', 'target-arrow',  'No audit errors waiting for your review. 🎉'],
    'raised' => ['Awaiting auditor',  'purple', 'message-2',     'You have no rebuttals awaiting the auditor.'],
    'won'    => ['Rebuttals won',     'green',  'thumb-up',      'No accepted rebuttals yet.'],
];
$bsBadge = ['billed'=>'green', 'hold_deductible'=>'orange', 'unbilled'=>'red'];
$rbColor = ['none'=>'secondary', 'raised'=>'purple', 'accepted'=>'green', 'rejected'=>'red'];

$pageTitle = 'My billing errors';
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-message-report me-2 text-primary"></i>My billing audit errors &amp; rebuttals</h2>
        <div class="text-secondary small">Charts of yours the QA team flagged as an <strong>error</strong>. Review the category &amp; comment, then
            <strong>agree</strong> the error stands or <strong>dispute</strong> it — the auditor reviews any dispute you raise.</div>
    </div>
</div></div></div>
<div class="page-body"><div class="container-xl">
    <ul class="nav nav-tabs mb-3">
        <?php foreach ($qMeta as $k => $m): ?>
        <li class="nav-item"><a class="nav-link <?= $q===$k?'active':'' ?>" href="<?= e($tabUrl($k)) ?>">
            <i class="ti ti-<?= $m[2] ?> me-1"></i><?= e($m[0]) ?> <span class="badge bg-<?= $m[1] ?>-lt ms-1"><?= (int)$counts[$k] ?></span></a></li>
        <?php endforeach; ?>
    </ul>

    <div class="card mb-3"><div class="card-body py-2"><form method="GET" class="row g-2 align-items-end">
        <input type="hidden" name="q" value="<?= e($q) ?>">
        <?php $rbSel = function ($name, $opts, $cur, $all) { $h = '<select name="'.e($name).'" class="form-select form-select-sm"><option value="">'.e($all).'</option>';
            foreach ($opts as $o) $h .= '<option value="'.(int)$o['id'].'"'.($cur===(int)$o['id']?' selected':'').'>'.e($o['name']).'</option>'; return $h.'</select>'; }; ?>
        <div class="col-6 col-md-3"><label class="form-label small mb-1">Client</label><?= $rbSel('client_id',$fClients,$fClient,'All clients') ?></div>
        <div class="col-6 col-md-3"><label class="form-label small mb-1">Facility</label><?= $rbSel('facility_id',$fFacils,$fFacility,'All facilities') ?></div>
        <div class="col-6 col-md-2"><label class="form-label small mb-1">Auditor</label><?= $rbSel('auditor_id',$fAuds,$fAuditor,'All auditors') ?></div>
        <div class="col-6 col-md-2"><label class="form-label small mb-1">Audited from</label><input type="date" name="from" value="<?= e($from) ?>" class="form-control form-control-sm"></div>
        <div class="col-6 col-md-2"><label class="form-label small mb-1">to</label><input type="date" name="to" value="<?= e($to) ?>" 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>Filter</button> <a href="<?= e(url('/admin/billing-rebuttals.php?q='.$q)) ?>" class="btn btn-sm btn-ghost-secondary">Clear</a></div>
    </form></div></div>

    <div class="card"><div class="table-responsive"><table class="table table-vcenter card-table table-sm" style="font-size:.82rem">
        <thead><tr><th>Patient</th><th>MRN</th><th>DOB</th><th>DOS</th><th>Client</th><th>Facility</th><th>Billing prov</th>
            <th>Billing status</th><th>Error category</th><th class="text-end">Defects</th><th>Auditor</th><th>Audited</th><th>State</th><th class="w-1"></th></tr></thead>
        <tbody>
        <?php if (!$rows): ?><tr><td colspan="14" class="text-center text-secondary py-4"><?= e($qMeta[$q][3]) ?></td></tr>
        <?php else: foreach ($rows as $r):
            $iid  = (int) $r['inventory_id'];
            $bs   = (string) ($r['billing_status'] ?? '');
            $rs   = (string) ($r['rebuttal_status'] ?? 'none');
            $opp  = (int) $r['audit_opportunities']; $def = (int) $r['audit_defects'];
            $canRebut = ($q === 'open');
        ?>
            <tr>
                <td><strong><?= e($r['patient_name']) ?></strong></td>
                <td class="small"><?= e($r['patient_mrn'] ?: '—') ?></td>
                <td class="small text-nowrap"><?= e(fmt_date($r['patient_dob'] ?? null)) ?></td>
                <td class="small text-nowrap"><?= e(fmt_date($r['dos'] ?? null)) ?></td>
                <td class="small"><?= e($r['cn'] ?: '—') ?></td>
                <td class="small"><?= e($r['fn'] ?: '—') ?></td>
                <td class="small"><?= e($r['billing_prov'] ?: '—') ?></td>
                <td class="small"><?php if ($bs !== ''): ?><span class="badge bg-<?= $bsBadge[$bs] ?? 'secondary' ?>-lt"><?= e(str_replace('_',' ',$bs)) ?></span><?php else: ?><span class="text-secondary">—</span><?php endif; ?></td>
                <td class="small"><?= e($r['audit_error_category'] ?: '—') ?><?php if ($r['audit_comment']): ?><div class="text-secondary" style="max-width:22rem"><?= e($r['audit_comment']) ?></div><?php endif; ?></td>
                <td class="text-end text-danger"><?= $def ?: '—' ?><?= $opp>0 ? ' / '.$opp : '' ?></td>
                <td class="small"><?= e($r['auditor'] ?: '—') ?></td>
                <td class="small text-secondary text-nowrap"><?= e(fmt_dt($r['audited_at'])) ?></td>
                <td class="small">
                    <?php if ($q === 'open' && $rs === 'rejected'): ?><span class="badge bg-red-lt">rejected · re-rebut</span>
                    <?php elseif ($q === 'open'): ?><span class="badge bg-yellow-lt">awaiting you</span>
                    <?php elseif ($q === 'raised'): ?><span class="badge bg-purple-lt">awaiting auditor</span>
                    <?php else: ?><span class="badge bg-green-lt">accepted</span><?php endif; ?>
                </td>
                <td class="text-nowrap">
                    <?php if ($canRebut): $fails = $failByAlloc[(int)$r['id']] ?? []; ?>
                        <button class="btn btn-sm btn-ghost-danger py-0 px-2" type="button" data-bs-toggle="collapse" data-bs-target="#reb<?= $iid ?>" title="Dispute this error"><i class="ti ti-message-2 me-1"></i>Rebut</button>
                        <form method="POST" action="<?= e(url('/admin/billing-rebuttals.php')) ?>" class="d-inline" onsubmit="return confirm('Agree the error stands? This closes it with no dispute.');">
                            <?= csrf_field() ?><input type="hidden" name="action" value="agree"><input type="hidden" name="inventory_id" value="<?= $iid ?>">
                            <button class="btn btn-sm btn-ghost-secondary py-0 px-2" title="Accept the error as correct"><i class="ti ti-check me-1"></i>Agree</button>
                        </form>
                    <?php else: ?><span class="text-secondary">—</span><?php endif; ?>
                </td>
            </tr>
            <?php if ($canRebut): ?>
            <tr class="collapse" id="reb<?= $iid ?>"><td colspan="14" class="bg-red-lt">
                <form method="POST" action="<?= e(url('/admin/billing-rebuttals.php')) ?>" class="py-1">
                    <?= csrf_field() ?><input type="hidden" name="action" value="rebut"><input type="hidden" name="inventory_id" value="<?= $iid ?>">
                    <?php if ($fails): ?>
                        <div class="small text-secondary mb-1">Tick the parameter(s) you disagree with and give a reason (leave all unticked to dispute the whole error):</div>
                        <?php foreach ($fails as $pk => $anote): ?>
                            <div class="d-flex align-items-center gap-2 mb-1 flex-wrap">
                                <label class="form-check mb-0" style="min-width:16rem"><input type="checkbox" class="form-check-input" name="disputed[]" value="<?= e($pk) ?>">
                                    <span class="form-check-label small"><?= e(BILLING_AUDIT_PARAMS[$pk] ?? $pk) ?><?php if ($anote): ?> <span class="text-secondary">— auditor: <?= e($anote) ?></span><?php endif; ?></span></label>
                                <input name="reason[<?= e($pk) ?>]" class="form-control form-control-sm" style="min-width:18rem;flex:1" placeholder="Why this parameter was correct…" maxlength="255">
                            </div>
                        <?php endforeach; ?>
                    <?php endif; ?>
                    <div class="d-flex gap-2 align-items-center flex-wrap">
                        <span class="small text-secondary">Overall note:</span>
                        <input name="note" class="form-control form-control-sm" style="min-width:22rem;flex:1" placeholder="Explain why your billing was correct…" required>
                        <button class="btn btn-sm btn-danger"><i class="ti ti-send me-1"></i>Send rebuttal</button>
                    </div>
                </form>
            </td></tr>
            <?php endif; ?>
        <?php endforeach; endif; ?>
        </tbody>
    </table></div></div>
</div></div>
<?php require __DIR__ . '/../includes/footer.php'; ?>
