<?php
/**
 * Validation history report (coding.reports / coding.supervise / coding.audit).
 *
 * The full RFI / Disregard lifecycle for each chart, pivoted from the durable event log
 * (coding_chart_events) so it survives the column resets a send-back performs:
 *   coder → validator (coder_submit→rfi/disregard) · validated (validate_tag) ·
 *   sent to client (client_sent) · client response received (client_response, with the response text) ·
 *   sent back to coder (validate_return).
 * Filter by client / coder / date; export to CSV.
 */
require_once __DIR__ . '/../includes/config.php';
$user = require_login('internal');
$pdo  = db();

$fClient = (int) ($_GET['client_id'] ?? 0);
$fCoder  = (int) ($_GET['coder_id'] ?? 0);
$to   = preg_match('/^\d{4}-\d{2}-\d{2}$/', (string) ($_GET['to'] ?? ''))   ? $_GET['to']   : date('Y-m-d');
$from = preg_match('/^\d{4}-\d{2}-\d{2}$/', (string) ($_GET['from'] ?? '')) ? $_GET['from'] : date('Y-m-d', strtotime('-89 days'));
$stage = in_array($_GET['stage'] ?? '', ['validated','sent','responded','pending_resp'], true) ? $_GET['stage'] : '';

// Pivot the event log to one row per chart with the key lifecycle timestamps + the latest client response.
$pivot = "SELECT e.inventory_id,
        MAX(CASE WHEN e.event_type='coder_submit' AND e.to_state IN ('rfi','disregard') THEN e.created_at END) sent_to_validator,
        MAX(CASE WHEN e.event_type='validate_tag' THEN e.created_at END) validated_at,
        SUBSTRING_INDEX(GROUP_CONCAT(CASE WHEN e.event_type='validate_tag' THEN e.actor_id END ORDER BY e.created_at DESC, e.id DESC SEPARATOR 0x1f),0x1f,1) validator_id,
        SUBSTRING_INDEX(GROUP_CONCAT(CASE WHEN e.event_type='validate_tag' THEN e.to_state END ORDER BY e.created_at DESC SEPARATOR 0x1f),0x1f,1) disposition,
        MAX(CASE WHEN e.event_type='client_sent' THEN e.created_at END)     sent_to_client,
        MAX(CASE WHEN e.event_type='client_response' THEN e.created_at END) response_at,
        SUBSTRING_INDEX(GROUP_CONCAT(CASE WHEN e.event_type='client_response' THEN e.note END ORDER BY e.created_at DESC SEPARATOR 0x1f),0x1f,1) response_note,
        MAX(CASE WHEN e.event_type='validate_return' THEN e.created_at END) sent_back_at
    FROM coding_chart_events e
    WHERE e.event_type IN ('coder_submit','validate_tag','client_sent','client_response','validate_return')
    GROUP BY e.inventory_id
    HAVING validated_at IS NOT NULL OR sent_to_client IS NOT NULL OR response_at IS NOT NULL";

$w = ['(t.validated_at IS NOT NULL OR t.sent_to_client IS NOT NULL OR t.response_at IS NOT NULL)']; $p = [];
$w[] = '(t.sent_to_validator IS NULL OR DATE(t.sent_to_validator) BETWEEN ? AND ?)'; $p[] = $from; $p[] = $to;
if ($fClient) { $w[] = 'ci.client_id=?'; $p[] = $fClient; }
if ($fCoder)  { $w[] = 'ci.coder_id=?';  $p[] = $fCoder; }
// Per-user scope (bug fix): a plain coder sees ONLY charts they coded; a supervisor/manager sees their
// reporting team; a validator reviews the whole vertical; sysadmin sees all. Without this, a coder (who
// holds coding.reports and so can open this page) saw every coder's history.
$uid = (int) $user['id'];
/* An explicitly page-granted viewer who is NOT a coder — e.g. an AR / Billing manager handed this report for
 * business oversight. They hold no coding.* role, so without this they fell into the "plain coder" branch below
 * and were narrowed to `coder_id = their own id`, i.e. an empty report. The restriction above was added to stop
 * a CODER seeing everyone's history; requiring !can('coding.work') keeps that intact — coders stay restricted. */
$isPageViewer = !can('coding.work') && !can('coding.supervise') && !can('coding.validate')
             && can(page_perm_code('coding-history.php'));
if (can('coding.supervise')) {
    $team = coding_team_scope($pdo, $uid);                       // null = sysadmin (unrestricted)
    if ($team !== null) $w[] = 'ci.coder_id IN (' . implode(',', array_map('intval', $team ?: [0])) . ')';
} elseif (!can('coding.validate') && !$isPageViewer) {           // plain coder (validators are vertical-wide)
    $w[] = 'ci.coder_id = ?'; $p[] = $uid;
}
if ($stage === 'validated')    $w[] = 't.validated_at IS NOT NULL';
elseif ($stage === 'sent')     $w[] = 't.sent_to_client IS NOT NULL';
elseif ($stage === 'responded')$w[] = 't.response_at IS NOT NULL';
elseif ($stage === 'pending_resp') $w[] = 't.sent_to_client IS NOT NULL AND t.response_at IS NULL';

$sql = "SELECT t.*, ci.patient_name, ci.patient_mrn, ci.gender, c.name client,
            co.name coder, vu.name validator
        FROM ($pivot) t
        JOIN coding_inventory ci ON ci.id=t.inventory_id
        JOIN clients c ON c.id=ci.client_id
        LEFT JOIN users co ON co.id=ci.coder_id
        LEFT JOIN users vu ON vu.id=t.validator_id
        WHERE " . implode(' AND ', $w) . "
        ORDER BY COALESCE(t.response_at, t.sent_to_client, t.validated_at) DESC LIMIT 5000";
$st = $pdo->prepare($sql); $st->execute($p); $rows = $st->fetchAll();

/* CSV export */
if (($_GET['export'] ?? '') === 'csv') {
    header('Content-Type: text/csv; charset=utf-8');
    header('Content-Disposition: attachment; filename="validation-history-' . $from . '_' . $to . '.csv"');
    $out = fopen('php://output', 'w'); fwrite($out, "\xEF\xBB\xBF");
    fputcsv($out, ['Patient','MRN','Client','Coder','Validator','Disposition','Coder→Validator','Validated','Sent to client','Client response','Response received','Sent back to coder']);
    foreach ($rows as $r) fputcsv($out, [$r['patient_name'],$r['patient_mrn'],$r['client'],$r['coder'],$r['validator'],$r['disposition'],
        $r['sent_to_validator'],$r['validated_at'],$r['sent_to_client'],$r['response_note'],$r['response_at'],$r['sent_back_at']]);
    fclose($out); exit;
}

$clients = $pdo->query("SELECT DISTINCT c.id,c.name FROM coding_inventory ci JOIN clients c ON c.id=ci.client_id WHERE ci.audit_status IN ('rfi','disregard') OR ci.client_sent_at IS NOT NULL ORDER BY c.name")->fetchAll();
$coders  = $pdo->query("SELECT DISTINCT u.id,u.name FROM users u JOIN user_roles ur ON ur.user_id=u.id JOIN roles r ON r.id=ur.role_id WHERE r.code IN ('coder','coding_supervisor','coding_manager') AND u.status='active' ORDER BY u.name")->fetchAll();
$selfUrl = fn(array $o=[]) => '/admin/coding-history.php?' . http_build_query(array_filter(array_merge(['client_id'=>$fClient,'coder_id'=>$fCoder,'from'=>$from,'to'=>$to,'stage'=>$stage],$o), fn($v)=>$v!==null&&$v!==''&&$v!==0));

$dispBadge = ['rfi'=>'orange','disregard'=>'danger'];
$pageTitle = 'Validation history';
require __DIR__ . '/../includes/header.php';
$dt = fn($v) => $v ? e(fmt_dt($v)) : '<span class="text-secondary">—</span>';
?>
<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-history me-2 text-primary"></i>Validation history</h2>
        <div class="text-secondary small">Full RFI / Disregard lifecycle per chart — coder→validator, validated, sent to client, client response received, sent back to coder.</div></div>
    <div class="col-auto"><a href="<?= e(url($selfUrl(['export'=>'csv']))) ?>" class="btn btn-outline-secondary"><i class="ti ti-download me-1"></i>Export CSV</a></div>
</div></div></div>
<div class="page-body"><div class="container-xl">
    <form method="GET" class="card mb-3"><div class="card-body row g-2 align-items-end">
        <div class="col-md-3"><label class="form-label">Client</label><select name="client_id" class="form-select form-select-sm"><option value="">All</option><?php foreach($clients as $o):?><option value="<?=(int)$o['id']?>" <?=$fClient===(int)$o['id']?'selected':''?>><?=e($o['name'])?></option><?php endforeach;?></select></div>
        <div class="col-md-3"><label class="form-label">Coder</label><select name="coder_id" class="form-select form-select-sm"><option value="">All</option><?php foreach($coders as $o):?><option value="<?=(int)$o['id']?>" <?=$fCoder===(int)$o['id']?'selected':''?>><?=e($o['name'])?></option><?php endforeach;?></select></div>
        <div class="col-auto"><label class="form-label">From</label><input type="date" name="from" value="<?= e($from) ?>" class="form-control form-control-sm"></div>
        <div class="col-auto"><label class="form-label">To</label><input type="date" name="to" value="<?= e($to) ?>" class="form-control form-control-sm"></div>
        <div class="col-md-2"><label class="form-label">Stage</label><select name="stage" class="form-select form-select-sm">
            <?php foreach(['' =>'All','validated'=>'Validated','sent'=>'Sent to client','pending_resp'=>'Awaiting client response','responded'=>'Response received'] as $k=>$v):?><option value="<?=$k?>" <?=$stage===$k?'selected':''?>><?=e($v)?></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> <a href="<?= e(url('/admin/coding-history.php')) ?>" class="btn btn-sm btn-ghost-secondary">Reset</a></div>
        <div class="col-auto ms-auto align-self-center text-secondary small"><strong><?= count($rows) ?></strong> chart(s)</div>
    </div></form>

    <div class="card"><div class="table-responsive"><table class="table table-vcenter card-table table-sm" style="font-size:.8rem">
        <thead><tr><th>Patient</th><th>Client</th><th>Coder</th><th>Validator</th><th>Disposition</th>
            <th>Coder→Validator</th><th>Validated</th><th>Sent to client</th><th>Response received</th><th>Client response</th><th>Sent back</th></tr></thead>
        <tbody>
        <?php if (!$rows): ?><tr><td colspan="11" class="text-center text-secondary py-4">No validation history in this range.</td></tr>
        <?php else: foreach ($rows as $r): $d=(string)($r['disposition']??''); ?>
            <tr>
                <td><strong><?= e($r['patient_name']) ?></strong><div class="small text-secondary"><?= e($r['patient_mrn'] ?: '') ?></div></td>
                <td class="small text-secondary"><?= e($r['client']) ?></td>
                <td class="small"><?= e($r['coder'] ?? '—') ?></td>
                <td class="small"><?= e($r['validator'] ?? '—') ?></td>
                <td><?= $d!==''?'<span class="badge bg-'.($dispBadge[$d]??'secondary').'-lt">'.e(strtoupper($d)).'</span>':'—' ?></td>
                <td class="small text-nowrap"><?= $dt($r['sent_to_validator']) ?></td>
                <td class="small text-nowrap"><?= $dt($r['validated_at']) ?></td>
                <td class="small text-nowrap"><?= $r['sent_to_client'] ? $dt($r['sent_to_client']) : '<span class="badge bg-warning-lt">pending</span>' ?></td>
                <td class="small text-nowrap"><?= $r['response_at'] ? $dt($r['response_at']) : ($r['sent_to_client']?'<span class="badge bg-azure-lt">awaiting</span>':'—') ?></td>
                <td class="small" style="max-width:280px"><?= e($r['response_note'] ?: '') ?></td>
                <td class="small text-nowrap"><?= $dt($r['sent_back_at']) ?></td>
            </tr>
        <?php endforeach; endif; ?>
        </tbody>
    </table></div>
    <?php if (count($rows) >= 5000): ?><div class="card-footer text-secondary small">Showing first 5000 — narrow with filters.</div><?php endif; ?>
    </div>
</div></div>
<?php require __DIR__ . '/../includes/footer.php'; ?>
